Original Post
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
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:
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?
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?