Skip to main content
gamedev.net
🔒 Locked

[D3D9] FixedFunction Texture Blends

Started by DragonGeo2 Apr 8, 2011 at 12:58 AM 0 replies 1.9k views
Original Post
DragonGeo2
DragonGeo2
What I want to do is "lerp" between two textures using only the fixed-function pipeline (so no shaders). I have textureA and textureB and an interpolation value (and the interpolation value changes each frame, so it would not be practical to lock and write and unlock an intermediary texture each frame). The interpolation value goes from [0.0, 1.0) . This problem is slightly complicated by the fact that I need to eventually draw this lerp-blended texture onto a quad that has a vertex/material alpha of 0.7f.

I've tried three methods already and all of them have worked, but they each have their own glitches. In all three pseudocode examples, the following variables are used:
lerpArg // This is the lerp value that goes from 0 to 1 to interpolate the textures
vertAlpha // This is the vertex alpha, it is always 0.7f
textureA // The first texture to be blended
textureB // The second texture to be blended

Try 1) Multipass and blend states manipulation:
Setup:
SetRenderState(D3DRS_SRCBLEND = D3DBLEND_SRCALPHA)
SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE = D3DMCS_MATERIAL) // For Try 1, we're using material alpha instead of vertex alpha so we can change the alpha between passes

Pass 1:
SetRenderState(D3DRS_DESTBLEND = D3DBLEND_BLENDFACTOR)
SetRenderState(D3DRS_BLENDFACTOR = D3DCOLOR_COLORVALUE(0.3f, 0.3f, 0.3f, 0.3f) ) // 0.3f is (1.0f - vertAlpha)
material.Diffuse.a = vertAlpha * (1.0f - lerpArg)
SetMaterial(&material)
SetTexture(0, textureA)
Draw()

Pass 2:
SetRenderState(D3DRS_DESTBLEND = D3DBLEND_ONE)
material.Diffuse.a = vertAlpha * lerpArg
SetMaterial(&material)
SetTexture(0, textureB)
Draw()


Try 2: Single-pass with multitexturing (using D3DTOP_BLENDFACTORALPHA)

Setup:
SetRenderState(D3DRS_SRCBLEND = D3DBLEND_SRCALPHA)
SetRenderState( D3DRS_DESTBLEND = D3DBLEND_INVSRCALPHA)
SetTexture(0, textureA)
SetTexture(1, textureB)
SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0)

SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDFACTORALPHA)
SetRenderState(D3DRS_TEXTUREFACTOR = D3DCOLOR_COLORVALUE(lerpArg, lerpArg, lerpArg, lerpArg) )
Draw()


Try 3: Single-pass with multitexturing (using D3DTOP_LERP)

Setup: (Exact same setup as Try 2)
SetRenderState(D3DRS_SRCBLEND = D3DBLEND_SRCALPHA)
SetRenderState(D3DRS_DESTBLEND = D3DBLEND_INVSRCALPHA)
SetTexture(0, textureA)
SetTexture(1, textureB)
SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0)

SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_LERP)
SetTextureStageState(1, D3DTSS_COLORARG0, D3DTA_TEXTURE)
SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CONSTANT)
SetTextureStageState(1, D3DTSS_CONSTANT, D3DCOLOR_COLORVALUE(lerpArg, lerpArg, lerpArg, lerpArg) )
Draw()


The glitch in Try 1 is that at the "boundaries" (within 0.008 of either the 0.0 and the 1.0) the texture glitches out, turning entirely white.

The glitch in Try 2 and Try 3 is that the lerpArg seems to somehow be affecting the "brightness" of the texture. As the lerpArg climbs from 0.0 to 1.0, the lerped texture gets brighter and brighter.

I've checked and double-checked to make sure that the lerpArg is always within the range specified. I even went so far as to add:
if (lerpArg < 0.0f || lerpArg >= 1.0f) __debugbreak(); to the tops of each of the three Try functions, and the breakpoint was never hit.
I've also checked and double-checked to make sure that textureA and textureB are not NULL.

I've also tested to see if the "brightness" glitch present in Try 2 and Try 3 was because textureB was brighter than textureA, but it occurs even when I set textureB to the same texture as textureA.

Can someone figure out what I'm doing wrong here?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.