PDA

View Full Version : How can I have two Alpha test func?



pmliming
06-02-2004, 03:33 PM
I want to hold the vertex that alpha in the range(0.2,0.8) . But the alpha function can only have one threshold:
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GEQUAL,0.2);
How can I mask out the vertex that alpha larger than 0.8? Sorry for my poor English. Thank you.

zeckensack
06-02-2004, 04:45 PM
It's not possible to use two alpha tests at the same time.
But you can use the stencil buffer. Draw all vertices twice. This is often referred to as "multipass rendering".
Pseudocode:

//---prepare first pass
glStencilMask(1);
glStencilFunc(GL_ALWAYS,1,1);
glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);
glEnable(GL_STENCIL_TEST);

glAlphaFunc(GL_GREATER,0.2f);
glEnable(GL_ALPHA_TEST);

//draw *only* to the stencil buffer in first pass
glColorMask(0,0,0,0);
glDepthMask(0);

glBegin(<...>);
...
glEnd();

//---prepare second pass
glStencilFunc(GL_EQUAL,1,1);
glStencilOp(GL_ZERO,GL_ZERO,GL_ZERO); //see note below
glEnable(GL_STENCIL_TEST);

glAlphaFunc(GL_LESS,0.8f);

//second pass will be visible and will update the depth buffer
glColorMask(1,1,1,1);
glDepthMask(1);
glBegin(<...>);
...
glEnd();Note that glStencilOp(GL_ZERO,GL_ZERO,GL_ZERO) will reset the stencil buffer to zeroes again, so you don't need to clear the stencil buffer if you draw the same vertices twice. If you don't want that, just add GL_STENCIL_BUFFER_BIT to your glClear command and delete the second glStencilOp.

seed
06-04-2004, 04:42 AM
or use a vertex shader that throws out all vertices within your alpha range

zeckensack
06-04-2004, 06:53 AM
Originally posted by seed:
or use a vertex shader that throws out all vertices within your alpha rangeA vertex shader can't throw away vertices. One goes in, one comes out, no exceptions.

A fragment program would work, though.
!!ARBfp1.0

TEMP hmm;
SUB hmm.a,fragment.color,0.6;
ABS hmm.a,hmm;
ADD hmm.a,-hmm,0.4;
KIL hmm.a;
MOV result.color,fragment.color;
END

pmliming
06-07-2004, 04:52 AM
Thanks a lot!

V-man
06-07-2004, 07:27 AM
[quote]Originally posted by zeckensack:

!!ARBfp1.0

TEMP hmm;
SUB hmm.a,fragment.color,0.6;
ABS hmm.a,hmm;
ADD hmm.a,-hmm,0.4;
KIL hmm.a;
MOV result.color,fragment.color;
END</font><hr /></blockquote><font size="2" face="Verdana, Arial">With the above code, if alpha = 1.0

hmm.a = 1.0 - 0.6 = 0.4
hmm.a = abs(0.4) = 0.4
hmm.a = -0.4 + 0.4 = 0.0

Since TEMP hmm contains no negative values, the fragment will pass.

You could try

//NOTE : unfortunatly, you need NV_fp for SGT
//support

PARAM testcase1={1.1, 1.1, 1.1, 0.8};
PARAM testcase2={0.0, 0.0, 0.0, 0.2};

SGE hmm, fragment.color, testcase1;
KIL -hmm; # KIL if alpha >= 0.8
SLT hmm, fragment.color, testcase2;
KIL -hmm; # KIL if alpha < 0.2

...continue processing otherwise

zeckensack
06-08-2004, 06:10 PM
Oops :)
I picked the wrong numbers. Change 0.6 to 0.5 and 0.4 to 0.3. Pans out like this
alpha in SUB ABS ADD KIL
0.1 -0.4 0.4 -0.1 X
0.2 -0.3 0.3 0.0 -
...
0.8 0.3 0.3 0.0 -
0.9 0.4 0.4 -0.1 X