Reconstructing eye-view position from linearized depth incorrect

Started by
5 comments, last by Ohforf sake 10 years, 5 months ago

i have been trying to implement deferred rendering for past 2 weeks. I have finally come to the spot lighting pass part using stencil buffer and linearized depth. I hold 3 framebuffer textures : albedo, normal+depth (X,Y,Z,EyeViewLinearDepth), Lighting texture. So I draw my light (sphere) and apply this fragment shader :


void main(void)
{
  vec2 texCoord = gl_FragCoord.xy * u_inverseScreenSize.xy;

  float linearDepth = texture2D(u_normalDepth, texCoord.st).a;

  // vector to far plane
  vec3 viewRay = vec3(v_vertex.xy * (-farClip/v_vertex.z), -farClip);
  // scale viewRay by linear depth to get view space position
  vec3 vertex = viewRay * linearDepth;

  vec3 normal = texture2D(u_normalDepth, texCoord.st).xyz*2.0 - 1.0;

  vec4 ambient = vec4(0.0, 0.0, 0.0, 1.0);
  vec4 diffuse = vec4(0.0, 0.0, 0.0, 1.0);
  vec4 specular = vec4(0.0, 0.0, 0.0, 1.0);

  vec3 lightDir = lightpos - vertex ;
  vec3 R = normalize(reflect(lightDir, normal));
  vec3 V = normalize(vertex);

  float lambert = max(dot(normal, normalize(lightDir)), 0.0);

  if (lambert > 0.0) {
    float distance = length(lightDir);
    if (distance <= u_lightRadius) {  

      //CLASSICAL LIGHTING COMPUTATION PART
    }
  }


  vec4 final_color = vec4(ambient + diffuse + specular);
  gl_FragColor = vec4(final_color.xyz,  1.0);

}

The variables you need to know : v_vertex is eye space position of the vertex (of sphere), lightpos is the position/center of the light in eye space, linearDepth is generated on geometry pass stage in eye space.

The problem is that, the code fail this if check :


if (distance <= u_lightRadius)

. The light is never computed until i remove the distance check. I can see some lights if i remove the check but i am sure it is computed incorrectly because of the incorrect distance. I am sure that i pass these values correctly, radius is 170.0, light position is only like 40-50 units away from the model. There is definitely something wrong but i can't find it somehow. I tried many possibilities of radius and other variables.

Advertisement
The shader code looks correct.

Usually the best approach is to output all important internal variables in the shader one by one (linearDepth, viewRay, vertex, lightDir, distance) either as colors or as brightness and check if they are what you expect them to be.

is there a glsl debugger, i still couldnt find the error. but it doesnt work :/

vec4 position = vec4( gl_TexCoord.x*2-1, glTexCoord.y*2-1, depth, 1 );
position /= position.w;
Did you check the variables as I proposed? Can you post the images?

guys i have found the problem. i was passing center of the light as uniform and multiplying it with gl_modelview to get in eye space. that's correct until there but since i draw the light sphere with gltranslate and glscale functions, my gl_modelview matrix corrupts the lightpos uniform. i dont know how to fix this but if i try really small variables to avoid scale, the lighting works.

You could reuse the u_lightRadius uniform, that you already have in the fragment program, to scale the vertices in the vertex program. That way you don't need to scale the modelview matrix.

This topic is closed to new replies.

Advertisement