PDA

View Full Version : GL_MODULATE and multi-texturing with GLES



scratt
04-19-2009, 10:14 AM
Hi can anyone help me with the best way to multi-texture geometry with two grey scale textures, where I want both the textures to be modulated / modulate with the geometry's own colour? (Both textures are .png with alpha)

I can modulate with one, decal with the second, or add the second, and any number of combinations from this documentation here..

http://www.khronos.org/opengles/sdk/1.1/docs/man/glTexEnv.xml

But I cannot seem to get *both* grey scale textures to modulate and give me an overall hue based on the geometry's colour...

Any help from gles FF gurus appreciated. :)

At the moment I am using GL_MODULATE for the first texture unit and then GL_ADD for the second texture unit. This works, but gives me a very white second texture, rather like a blurred decal. Unfortunately GL_ADD_SIGNED takes too much brightness from the first texture, even though it allows the second texture to appear to be modulated.

That kind of makes sense when I read the function algorithms, but I can't see a way to do a more useful half / half blend of texture data with some geometry colour added in. In a shader this would take me 5 seconds! :(

arekkusu
04-19-2009, 12:13 PM
Pay careful attention to the definition of TexEnv. The operation depends on the format of the texture, so a LUMINANCE texture will produce different results than RGBA.

If you want to modulate with two textures, simply use MODULATE on both units.
You'll get primary color * tex0 * tex1.

If you want a "half / half blend" that's completely different. What are you actually trying to do?

scratt
04-19-2009, 08:02 PM
You have a point on the LUMINANCE thing. I had not thought of that. I also don't use them often...

Basically I am using two GreyScale RGB textures for now, with an alpha channel on each. I may at some point have some spot colour in the textures so want to keep it that way..

I found that this almost does what I need..
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
glTexEnvf (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
glTexEnvf (GL_TEXTURE_ENV, GL_SRC2_RGB, GL_PRIMARY_COLOR);

The only problem is because the second texture is effectively a symbol which takes up a small area on the surface of the first texture and the geometry, that it tends to dim the overall image... I am guessing for a similar reason GL_MODULATE simply does not work as I need. It does not matter what order I put the textures in because one of the textures is mostly transparent and ends up killing all the colour from the first texture unit. What I need in a perfect world is a way to modulate and carry the PRIMARY_COLOR through to the second texture unit too, which is why I started looking at functions with three inputs like INTERPOLATE.

I am sure someone who is an absolute guru with the Alpha side of things may be able to work around that, but I am not having much success. Perhaps I may need to look at the way I format the textures?

Other than losing colour intensity INTERPOLATE (used as above) does exactly what I want, giving an overall colour to everything but allowing the lighting effects to hit the geometry as well as both levels of the textures.

Gah. I hate FF stuff! ;)

arekkusu
04-19-2009, 10:22 PM
You still haven't said what you're trying to do.

If you wrote a shader to do it, what would it look like?

scratt
04-20-2009, 12:24 AM
I thought I had said what I was doing, but a pseudo shader would probably be clearer..

Something like this..

colour = mix(texture1frag, texture2frag, 0.5);
glColor = mix(colour, glFrontColor, 0.5);

After that I may have to play with some clamping or division, but seeing as this is on a platform where I don't have shaders I have not actually tried it in anger. But I think that describes algorithmically what I am trying to do, more or less..

Xmas
04-20-2009, 04:32 AM
That is something quite different from modulation, though. It is possible to do that with GL ES with a bit of rearranging.

If you expand the mix() functions, you end up with:

gl_FragColor = 0.25 * tex1 + 0.25 * tex2 + 0.5 * gl_FrontColor;
which is equivalent to:

gl_FragColor = mix(tex2, mix(tex1, gl_FrontColor, 0.666), 0.25);
which can be expressed as two COMBINE mode texture environment stages with INTERPOLATE as the operation, with Arg2 sourced from the constant. Note that some ES1.x implementations only support a single constant value shared across texture environments, so you'd need to use RGB in one environment and alpha in the other, setting the constant to (.666, .666, .666, .25)

arekkusu
04-20-2009, 09:42 AM
Thanks Xmas ;)

scratt
04-20-2009, 11:31 AM
Thanks Xmas / arekkusu. I kind of got there with a bit of experimentation today, but your explanation was helpful. :)