Clamping in the Blend Function..

Started by
1 comment, last by V-man 15 years, 11 months ago
Hey all, Is there some easy way to clamp the values in the blend equation to something other than 0 and 1? For example, clamp the values from 0 to 0.4? The reason is, I've got myself some lovely 2d dynamic soft shadows which are made by drawing shapes of varying intensity into the alpha buffer. The way I'm doing it at the moment is drawing with an intensity of 1.0 in the umbra, and fading between 0 and 1 intensity in the penumbra. Areas not in shadow have a value of 0. Once the shadows of all objects have been drawn to the alpha buffer, I draw a quad over the screen using the following equation: glBlendFunc(GL_ZERO,GL_ONE_MINUS_DST_ALPHA); This results in the areas of shadow being full black, the areas in the penumbra fading nicely from shaded to not shaded, and the areas not in shadow staying the same. Now this would be just fine and dandy if I wanted my shadowed areas to be completely black - but I don't. I want some ambience in there. So what I'm currently doing is before drawing this shadow quad over the screen, I draw ANOTHER quad over the screen using: float shadowIntensity = 0.4; glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); glBlendFunc(GL_DST_ALPHA, GL_ZERO); glColor4f(0,0,0,shadowIntensity); This multiplies all the alpha values in the screen by shadowIntensity (0.4), so now my intensity values range from 0 to 0.4, so now when I draw the shadow quad over the screen, the areas in complete shadow aren't pitch black, but are only partially darkened, resulting in the effect I want. My problem with all this is that it just seems so inefficient having to draw a quad over the entire screen simply to scale my values from 0-1.0 to 0-0.4. This takes an extra 30fps on my computer, which is bad. Now comes my original question about clamping. When I'm actually drawing the shadows into the alpha buffer in the first place, is there a way to clamp values at something other than 1.0, like 0.4? If there is, then I could simply draw into the alpha buffer a value of 0.4 for the areas of full shadow, rather than 1.0, which would result in the final alpha buffer ALREADY being in the range of 0 to 0.4, and I wouldn't need waste 30fps rescaling it. The reason why I need to CLAMP at 0.4, is because if there's no clamping then the shadows overlap in an unnatural way. One shadow on it's own is ok, but if I have 2 shadows overlapping.. the intensity in the alpha buffer where the shadows overlap ends up being 0.8, when it should remain 0.4. There may be other solutions too, like continuing to draw into the buffer with a range of 0 to 1, but when I draw the actual shadow quad, I somehow scale the values down to 0.4 at the same time. The real problem is having to do 2 passes over the entire screen when only 1 should be necessary (I hope :p). I'm sure this is possible using fragment shaders, and I may have to resort to that.. but if there's an easier way I'd much rather do that instead. P.S. I've tried using this for the shadow quad: float shadowIntensity = 0.4; glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); glBlendFunc(GL_DST_ALPHA,GL_ONE); glColor4f(shadowIntensity,shadowIntensity,shadowIntensity,0); But the results aren't the same. The shadowed areas have 0.4 removed from them, rather than being multiplied by 0.6 (1 - 0.4). Thus a purplish pixel of (0.5,0,0.4) actually becomes really dark red(0.1,0,0), when it should simply become a darker purple (0.3,0,0.24). ANYWAY.. I'm done. Sorry for the monster long post. I'm new to posting here, so if there's a way to add pictures, let me know, cause it might help explain things.. Thanks! :p
--------------------------Check out my free, top-down multiplayer shooter: Subvein
Advertisement
Any ideas?
--------------------------Check out my free, top-down multiplayer shooter: Subvein
No, the only thing that can be clamped is the fragment output just before the blending stage.
I don't know if you are using shaders but I'm sure it's possible in the fixed function pipe as well.

With shaders:
gl_FragColor = clamp(myresult, 0.0, 0.4);
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

This topic is closed to new replies.

Advertisement