Hi,
For images showing what I’m talking about below, see here:
http://www.software3d.com/BadSpecular
Until now I’ve been handling texture + specular with two-pass rendering. I decided to use GL_EXT_separate_specular_color when available to reduce this to one pass. But it seems that they still have the lighting calculation wrong. Let me explain…
When first implementing my two-pass algorithm, I did the texture pass first, then the specular pass, using this call:
glBlendFunc(GL_ONE, GL_ONE);
But I noticed that this just didn’t look right. Bright parts of the texture would burn out first, making it appear as if the specular was spreading from the bright parts to the dark parts. I realised that specular shouldn’t just be added, but rather it should REPLACE the existing texture, so I changed to this:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
And it worked beautifully. As the specular gets close to white, we belend out the original colour.
But I was disappointed when I tried the GL_EXT_separate_specular_color extension with this call:
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
It appears to be equivalent to using the faulty glBlendFunc(GL_ONE, GL_ONE). Is there any way to make it behave correctly? Another extension maybe?
For those not sure, think about viewing a shiny poster side-on, so that the light shines off it. The light replaces the image on the poster, it does not add a constant amount of brightness to it so that the image is still fully visible, just brighter. Arguments aside, that old computer graphics adage holds here, “if it looks right, it is right”, and the standard solution here just looks wrong.
How can I get the behaviour I want, the correct behaviour, in a single pass?
Thanks,
Rob.