Tex combine problem

Hi

I have a small problem getting the blending mode I want using ARB/EXT_texture_env_combine and multi-texturing.

I would like to get this TexEnv function: Cv = Cf * (Ct0 + Ct1)

In other words: Add the texture colours of both texture units and multiply the result with the fragment’s (gouraud interpolated) primary colour.

I looked at the EXT_texture_env_combine and ARB_texture_env_combine extensions, but I wasn’t able to figure out the appropriate combine formula. Is it even possible with 2 texture units using the blending equations that those extensions give you ? The closest I could come up with was: Cv = (Cf * Ct0) + Ct1, trivial, but that’s not what I want.

It was no problem with the NV_texture_env_combine4 extension or even with register combiners, but those are too specific, and I would like to avoid anything manufacturer dependent.

Any ideas ? Thanks !

Regards,
Alex

That’s the fixed order of things, unforunately.
fragment = (primarycolour*tex0)+tex2);

You could do a two pass render:

  • Render triangle with no texture, so interpolated colour is written directly into framebuffer.
  • Enable blending using
    glBlendFunc(GL_DST_COLOUR, GL_ZERO);
    glColor3f(0.0f, 0.0f, 0.0f);

Then…
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_ADD);
For both textures.

Haven’t tried it out, but it should work.

That’s the fixed order of things, unforunately.
fragment = (primarycolour*tex0)+tex2);

Yes, right. That’s why I thought that an advanced tex combine extension could circumvent the problem of this old OpenGL limitation. Apparently newer manufacturer specific extension can do that (see NV_texture_env_combine4, ATI must have similar ones), but I was wondering, if there is an ARB or EXT extension to get this result. Or perhaps some weird trick to achieve it approximately, as a fallback option.

You could do a two pass render:
/snip/

This works, no doubts. But the system is already almost fillrate saturated right now, so a second pass over the geometry would be impossible. And the second texture unit needs something to do

BTW: the formula is used as a specular trick, as you might have guessed.

Regards,
Alex

Using OpenGL 1.3, you can come very close to this equation using ARB_texture_env_combine instead of the older EXT_texture_env_combine.
Also OpenGL 1.3 has the ARB_texture_env_crossbar extension which is similiar to NV_texture_env_combine4 in that it allows you to use any texture unit as a source. You can get the exact equation with this extension. Of course, you still have to determine if these ARB extensions are available, e.g. IIRC NVIDIA does not support the crossbar extension.

[This message has been edited by DFrey (edited 01-16-2002).]

Yes, the ARB_texture_env_crossbar is very interesting, I think I could get the exact equation using it. I never heard about it before, since I’m developing on a GeForce, and as you said, nVidia doesn’t support it. Does ATi ?

About the ARB_texture_env_combine: You said I could come very close to my equation, what combine mode did you had in mind ? AFAIK, the only difference between the EXT and ARB versions is that I can use RGB sources for Arg2, is that correct, or did I miss a detail ?

It won’t hurt, if the equation isn’t reproduced 100% accurate (esp. for a fallback option), eg. the texture in one of the units can be monochrome. But it is absolutely vital, that the fragment’s primary colour scales the result. Ie. the result must go zero, if the primary colour is zero. Otherwise, I’ll get lots of funky little speculars in the dark areas of my scene…

Hmm, this equation was easy to get in Glide, on an old Voodoo2…

Regards,
Alex

Using ARB_texture_env_combine you can do this:

Use GL_MODULATE on Tex0: C0 = Ct0 * Cf
Use GL_COMBINE_ARB on Tex1, interpolation op: C1= Ct1 * Cf + C0 * (1-Cf)

Results in: C1= Ct1 * Cf + Ct0 * Cf - Ct0 * Cf^2

So you have this error term Ct0*Cf^2, but under certain condition this error could be made small. Then again, in other conditions, it could be overwhelming.

[This message has been edited by DFrey (edited 01-16-2002).]

Hmm, this equation was easy to get in Glide, on an old Voodoo2

It is also easy to get on a TNT or Geforce. The trick of course, is finding a way to do it on any card rather than a specific one.

My first post…here goes

On Layer 0, set GL_REPLACE with GL_TEXTURE
On Layer 1, set GL_ADD with GL_TEXTURE, GL_PREVIOUS_ARB
(adds tex0 and tex1)
on Layer 2, set GL_MODULATE with GL_PREVIOUS_ARB and GL_PRIMARY_COLOR_ARB

Blows 3 layers, but hey - it works without crossbar or Nvidia extensions…

Oops - sorry, didn’t spot the requirement for only 2 texture layers - of course this eqn will not work on those HWs which only support 2 layer multitexturing

Originally posted by DFrey:
Using ARB_texture_env_combine you can do this:

Use GL_MODULATE on Tex0: C0 = Ct0 * Cf
Use GL_COMBINE_ARB on Tex1, interpolation op: C1= Ct1 * Cf + C0 * (1-Cf)
Results in: C1= Ct1 * Cf + Ct0 * Cf - Ct0 * Cf^2

So you have this error term Ct0*Cf^2, but under certain condition this error could be made small. Then again, in other conditions, it could be overwhelming.

Thanks, I will try that out. The error term looks a bit weird to me, I’m afraid it will have a rather large impact on the expected result. It probably depends on the characteristics of the textures and lighting, I’ll just give it a try and see if the result is visually OK.
And as I said, it’s only a fallback option, so it isn’t really that critical.

Thanks for your help !

Regards,
Alex