Decomposing multitexturing to multiple passes

Sage
Posts: 1,232
Joined: 2002.10
Post: #1
OK. This is just another way of asking my other question.

Is it true that any multitexturing operation can be broken down into multiple passes with one texture unit?

If so, is it also true that it can be broken down in such a way that geometry can still be drawn in two complete passes, instead of one polygon from pass A, the same polygon from pass B, repeat? There might be state change required between the two passes.

Consider this situation:
Texture a bunch of overlapping, translucent geometry with two textures. First is solid. Second is an alpha texture, multiplying the first unit's alpha.

In the multitexturing case the hardware draws each polygon's alpha as the product of both textures and the current color. As long as the geometry is drawn back-to-front, it looks correct.

In the two pass case, all the polygons are drawn with the solid texture times the current color's alpha. Then, they are redrawn with the alpha texture, but (partially) obscured sections will get the wrong value, that of the foreground polygon.


Is there a trick to this I'm just not seeing?
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
I'm sorry, I'm really not following that.

Perhaps a diagram or something?
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #3
All right, here it is explained in pictures.

texture unit 0 is bound to a base alpha texture (stripes)
texture unit 1 is bound to a modulating alpha texture ("ONE" or "TWO" for this example, though in practice it is the same texture for all quads)

Multitexturing case:
[Image: Multitexture.png]

1) quad_one is drawn, with both textures modulating the base color.
2) quad_two is drawn, with both textures modulating the base color.

To clarify, quad_one is color (1, 1, 0, 0.7) and quad_two is color (0, 0, 1, 0.7) so there is translucency everywhere, not just where the alpha texture filtered.


Now, let's suppose that we want to do this using only one texture unit. (Actually, the reason is not because of lack of texture units, it is because I need to draw overlapping geometry to modify the alpha, without writing to the color buffer. But I figure this is equivalent to doing it using one texture unit.)

Here's one way to do it with one texture unit that works, but it takes (textures + 1) passes. The picture shows all six steps for clarity (reduced 50% for bandwidth...)

Multipass case:
[Image: Multipass_small.png]

1) quad_one's base alpha texture is drawn into the destination alpha buffer, using glBlendFunc(GL_ONE, GL_ZERO).
2) quad_one's modulating alpha texture is drawn into the destination alpha buffer, using glBlendFunc(GL_DST_ALPHA, GL_ZERO) and the alpha of the current color set to 1.
3) an untextured quad_one with the desired color is drawn to the color buffer only (alpha write disabled) using glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA).
4) quad_two's base alpha texture is drawn into the destination alpha buffer, using glBlendFunc(GL_ONE, GL_ZERO).
5) quad_two's modulating alpha texture is drawn into the destination alpha buffer, using glBlendFunc(GL_DST_ALPHA, GL_ZERO) and the alpha of the current color set to 1.
6) an untextured quad_two with the desired color is drawn to the color buffer only (alpha write disabled) using glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA).

The color buffer end result is the same, it just took more fillrate. I don't care so much about the fillrate (in practice, it will only be two passes, because I can write all alpha textures into the alpha buffer using multitexuring with one pass, and then a second pass for the untextured quad.)

However, the big problem with this is that there is a bunch of state change around drawing each quad, so I can't draw a group of geometry using VAR.

If I try to draw more than one quad at a time, the alpha values are wrong wherever the geometry overlaps. To illustrate, let's try to draw both quads in a group during the same pass.

Multipass_group case:
[Image: Multipass_group_small.png]

1) all quad's base alpha texture are drawn into the destination alpha buffer, using glBlendFuncglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA).
2) all quad's modulating alpha texture are drawn into the destination alpha buffer, using glBlendFunc(GL_DST_ALPHA, GL_ZERO) and the alpha of the current color set to 1.
3) all untextured quads with the desired colors are drawn to the color buffer only (alpha write disabled) using glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA).

You can see that the alpha is wrong.

Ideas?
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #4
And for a better example here's the multipass (group) method but using multitexturing to write both alpha masks at once, like I'd do in the real app.

Multipass_group multitexture case:
[Image: Multipasstexture_small.png]

1) quad_one is drawn, with both alpha textures, into the destination alpha buffer using glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA).
2) quad_two is drawn, with both alpha textures, into the destination alpha buffer using glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA).
3) all untextured quads with the desired colors are drawn to the color buffer only (alpha write disabled) using glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA).

In the real app 1) and 2) could be one pass, the only state change in the example is rebinding between ONE and TWO textures.

Now you can see the real problem better which is that the color coverage for the quads are wrong.
Quote this message in a reply
Member
Posts: 72
Joined: 2006.10
Post: #5
There might be a way to get your last example to draw properly. It's not a very efficient way, but it may give you an idea.

When you arrive to draw the untextured polygons, you'd have to draw each of them two times with two different blending equations:

Code:
glBlendEquation(GL_FUNC_SUBTRACT);
//draw the quad
glBlendEquation(GL_FUNC_ADD);
//draw de quad again


N.B. this works for the black background, I doubt the result would be good otherwise

When you draw the quad the first time, with a substractive blend equation, you would negate the effect of the combinasion of the two quads on the surface that that combinasion would affect. You can then safely draw the polygon again properly.

- Sohta
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Can't get multitexturing to work Coyote 4 3,877 Nov 16, 2009 11:48 PM
Last Post: arekkusu
  Using glTexCoordPointer with multitexturing TomorrowPlusX 6 13,540 Dec 5, 2006 09:42 AM
Last Post: NYGhost
  Lighting and Multitexturing problem Scribendi 0 2,561 Sep 25, 2005 09:22 PM
Last Post: Scribendi
  OpenGL Multitexturing Details w/Alpha WakingJohn 22 10,670 Dec 4, 2004 10:52 AM
Last Post: WakingJohn
  Sparseness of Multitexturing documentatin in Red Book WhatMeWorry 2 3,155 Nov 10, 2004 01:54 PM
Last Post: arekkusu