In order to get identical rendering results, how would I blend subsequent passes on a user’s card that doesn’t have enough texture units to render in one pass? Say I have 3 textures, and the card only supports 2 texture units. I render the first two as normal, then render the third in a second pass. But how do I get the second pass to blend over the first one, in the appopriate way so that whatever the blend mode of the third texture is, it looks as though I were rendering three textures in one pass?
The closest I have found is GL_DST_COLOR,GL_ZERO, but if you look at this image, you can see that the two methods are not identical. Look at the tree view on the right to see how the rendering is processed.
it comes down to basic algebra.
you work out the “complete” formula for your mtex environment, and then the one for the mpasses should match. the easiest is sometimes brute force doing every tex as pass, unless you do some very special combiners, mpass should be able to reproduce every tex environment.
It really depends on what kind of combines you have, but often the basic math laws, like associtivity, commutativity and distributivity help to swizzle the total formula of the effect. I spend quite some time on this stuff so there is no real easy solution, a lot of special cases…
however the most obvious problem often are the vertex colors.
lets say you have 3 textures, all set to modulate:
then you get:
vcolor * tex0 * tex1 * tex2
if you do just split the 3rd off in a second pass:
(vcolor * tex0 * tex1) * (tex2 * vcolor)
which is not the same.
in the blended passes you often will need to set the texmode to gl_replace.
You must also not forget that value range for internal multitexture operations may be wider than [0,1] (for instance [-4, 4]) whereas the multipass approach clamps values to [0,1] for intermediate results.
Not to mention that not all fixed function texture ops can be reproduced by blending (I have a doubt now that i say it, but…)
The problem in the above shot is that the concrete texture is set GL_RGB_SCALE 2. It multiplies the texture 2x the white surface of the second layer. I want it to blend the texture with the first layer beneath that, with the black gradient.
How would I emulate this type of blending with the layer?
If I get it right, you’re doing something like :
glFragColor = color_tex0 * (2 * color_tex1)
Off to top of my head, you could do something like :
pass1:: glFragColor = color_tex1
pass2:: glFragColor += color_tex1
pass3:: glFragColor *= color_tex0
far from optimal, and losing precision in intermediate results, but that’s all I’m able to think about right now…
FWIW, are you really in need of targeting platforms that don’t support multitexturing ? from what I could see these platforms don’t even have reliadble GL drivers, so you may encounter even more problems !..
GEForce 4 MX is one of the most common cards (see Valve’s surveys), and supports just two texture units.