Framebuffer blending

Started by
5 comments, last by Namethatnobodyelsetook 19 years, 7 months ago
Hi Hopefully this will just be a simple case of confusion. However. As the framebuffer blend algorithm is based around an additive operation, i can perform a modulative blend ok by making, say the src term on the left side of the addition, zero, and the right side destcol*srccol. that's fine, what i have been attempting to do is use the alpha from the texture cascade to control how much of the src texture is blended with the frame buffer. i have tried this : "src*srcalpha + dest*srccol", which doesnt look right. has anyone done this before? help much appreciated. Regards Kraik
Advertisement
src = srcalpha
dest = invsrcalpha

alpha * newcolor + (1-alpha) * oldcolor
Hi

thats what i had originally used and was close, but im looking to blend the color values, regardless of what the alpha value is.

so, where you get a full alpha value at a certain point, rather than "only" the second pass texture showing, im was expecting to have this texture modulate with the first pass texture.

i have also played with clamping the alpha values at 0.8 max to have the base texture show, which also works, but seems a bit of a hack really.

thanks and help still much appreciated.

Kraik

Hi

Got it. the blend i needed is:
Src == DESTCOLOR
Dest == INVSRCALPHA

i was oversaturating the vertex diffuse alpha in the vertex shader.

thanks

Kraik
This will have an overbright effect,

Imagine both src and dest are 100% white, and the mix level is 50%

1 * 1 + 1 * .5 = 1.5


You might actually want:
src * dest * srcalpha + dest * invsrcalpha.

You can't get src*dest*srcalpha in blending modes, however, in your texture stage setup, or pixel shader, you could multiply src by srcalpha.

// Example of current effect
SetTSS(0, colorop, selectarg1)
SetTSS(0, colorarg1, texture)
SetTSS(0, alphaop, selectarg1)
SetTSS(0, alphaarg1, texture)
// Example of what to add to the end
// to modulate src*srcalpha
SetTSS(1, colorop, modulate)
SetTSS(1, colorarg1, current)
SetTSS(1, colorarg2, current|alphareplicate)
SetTSS(1, alphaop, selectarg1)
SetTSS(1, alphaarg1, current)
// Terminate
SetTSS(2, colorop, disable)
SetTSS(2, alphaop, disable)

Then set up as src=destcolor, dest=invsrcalpha

Thanks for that,

I quickly discovered that my previous method was also oversaturating with each subsequent pass.

I need to fiddle with that last setup you've presented due to the nature of whats in my texture stages. I'll try to expain what im doing:

For a single 33x33 terrain patch i have the following textures to apply to it:

*First pass* - AlphaBlend Off
1 basemap texture in texture stage 1, acting as a color map for areas > 200 meters. This is effectively stretched over the whole terrain. DTX1
Texture Stage 1 disabled

*Second pass* - AlphaBlend On - SrcCol*DestCol + DestCol*InvSrcAlpha
1 alpha map texture in first texture stage DTX5
1 "rock" texture in second texture stage DXT1
Texture Stage 2 disabled

*Third pass* - AlphaBlend On - SrcCol*DestCol + DestCol*InvSrcAlpha
1 "dirt" alpha map texture in first texture stage. DXT5
1 "dirt" texture in second texture stage DXT1
Texture Stage 2 disabled

.
.
.
Subsequent passes determined by the amount of detail textures actually required.


Now, what im also doing is using a vertex shader in all of the detail passes ( pass 2 + above ). This is really to create a vertex alpha value which fades out over distance. So in each patch, the closest vertices will have an alpha value of 255 and gradually fading out by a factor of (normalized values): 1-(dist_to_vertex*max_detail_dist_factor), where max_detail_dist_factor = 1/max_detail_dist_meters.

My thinking is that i can modulate the diffuse alpha and texture alpha values to fade the detail textures out, within the texture cascade. thinking that the diffuse alpha will factor out the texture alpha to give me the fade effect.

So, an excerpt from my render set up is this (HLSL format):

pass one ( base texture )
-----------------------------
alphablending = off

ColorOp[0] = SelectArg1;
ColorArg1[0] = Texture;
AlphaOp[0] = Disable;
ColorOp[1] = Disable;
AlphaOp[1] = Disable;

pass 2 + above (detail textures)
--------------------------------
alphablending = on
SrcBlend = DESTCOL;
DestBlend = INVSRCALPHA;

<tex = "alphamap">
ColorOp[0] = SelectArg1; // never really used because no rgb required from this stage - a waste ?
ColorArg1[0] = Texture;
AlphaOp[0] = SelectArg1;
AlphaArg1[0] = Texture;

<tex = "detail"> // e.g. rock -
ColorOp[1] = SelectArg1;
ColorArg1[1] = Texture | AlphaReplicate;
AlphaOp[1] = Modulate;
AlphaArg1[1] = Current;
AlphaArg2[1] = Diffuse;

ColorOp[2] = Disable;
AlphaOp[2] = Disable;


Thanks for all your help, and hopefully this explanation is a little clearer on what im trying to achieve. Im obviously not doing something right. Can you/anybody help again please?

Much appreciated.

Kraik.


Quote:Original post by Kraiklyn
<tex = "detail"> // e.g. rock -
ColorOp[1] = SelectArg1;
ColorArg1[1] = Texture | AlphaReplicate;
AlphaOp[1] = Modulate;
AlphaArg1[1] = Current;
AlphaArg2[1] = Diffuse;
Kraik.


Your never use the rock texture's color, you're asking for it's alpha instead. Also, want to modulate your final color with your final alpha.

We'd like:
blending: srccolor*destcolor*srcalpha + destcolor*invsrcalpha

However, we can't put 3 multiplies into alpha blending, but srcolor is only used once, so if we multiply it before it gets to blending, we're set.

effect of stage2: srccolor = srccolor * srcalpha
then blending: srccolor*destcolor + destcolor*invsrcalpha
Which is exactly what we wanted.

Try
arg1[1] = texture

colorop[2] = modulate
colorarg1[2] = current
colorarg2[2] = current | alphareplicate
alphaop[2] = selectarg1
alphaarg1[2] = current

This will do the following:
[0] = nothing / get alpha texture
[1] = get color / mix alpha with vertex diffuse
[2] = mix color by (tex[0]alpha * vertexalpha) / leave alpha alone

This topic is closed to new replies.

Advertisement