Specular bleeding?

Hi,

after getting diffuse lighting to work I just added specular to my deferred renderer. But somehow I have the feeling that there is something wrong. I tried it with Phong and Blinn-Phong but both seem to produce specular highlights even when the light source is behind the sphere I render:

Phong:

Blinn-Phong:

Here is my shader code:


uniform sampler2D Tex0, Tex1, Tex2;

void main(void)
{
  vec4 Color =  texture2DProj(Tex0, gl_TexCoord[0]);
  vec3 Position = texture2DProj(Tex1, gl_TexCoord[0]).xyz;
  vec3 Normal = texture2DProj(Tex2, gl_TexCoord[0]).xyz;
  vec3 LightDirection = gl_LightSource[0].position.xyz-Position;
  vec3 L = normalize(LightDirection);
  float NdotL = max(dot(Normal, L), 0.0);
  vec4 FinalColor = vec4(0.0,0.0,0.0,0.0);
  if (NdotL>0.0)
  {
    float Distance = length(LightDirection);
    float Attenuation = 1.0-gl_LightSource[0].quadraticAttenuation * Distance * Distance;
    // blinn-phong specular
    // screenshot 1
    vec3 H = normalize(L-normalize(Position));
    vec4 Ispec = vec4(1.0,1.0,1.0,1.0) * pow(max(dot(Normal,H),0.00001),32.0);
    // phong specular
    // screenshot 2
    //vec3 E = normalize(-Position);
    //vec3 R = normalize(-reflect(L,Normal));
    //vec4 Ispec = vec4(1.0,1.0,1.0,1.0)
    //              * pow(max(dot(R,E),0.00001),32.0);
    vec4 Idiffuse = Color * gl_LightSource[0].diffuse;
    FinalColor = Attenuation * ((NdotL * Idiffuse) +  Ispec);
  }
  gl_FragColor = FinalColor;
}

I thought the if statement would take care of not drawing the specular if there is no diffuse, but it looks like NdotL is greater than zero in this case.
I hope the screenshots show the problem good enough. Using a moving lightsource the problem is far more distracting than in this shots.
Any help is highly appreciated.

If the light is the small black dot, then it is normal.
Specular goes farther than diffuse. You can smoothstep it if needed.

Yes, the black dot is the light. I think it looks weird, but if it is normal then I have to accept it.

Never heard of smoothstep. Gave it a try and it looks even more distracting to me as it increases the size of the highlight.
That is what I tried:


  vec4 Ispec = vec4(1.0,1.0,1.0,1.0) * pow(smoothstep(0.00001,1.0,dot(Normal,H)),32.0);

vec4 Ispec = vec4(1.0,1.0,1.0,1.0) * pow(max(dot(Normal,H),0.00001),32.0);

Is there a reason why max is not at 0.0 instead of 0.00001 here ?

Anyway, I would suggest playing with smspec value like this :
float smspec = 0.05;
vec4 Ispec = vec4(1.0,1.0,1.0,1.0) *
(smoothstep(0.0,smspec,NdotL) * pow(max(dot(Normal,H),0.0),32.0));

http://www.opengl.org/discussion_boards/…9330#Post239330 :slight_smile:

Gave it a try. And although it helps to avoid bleeding, I need large values of smspec (between 0.8 and 1.0) and this distorts the highlights on flat polygons more than I am willing to accept (making them nearly perfect circles).
I think I have to implement shadows and test again, to see if the highlights are acceptable.
Thanks for the input.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.