Sign in to follow this  
xantier

Reconstructing eye-view position from linearized depth incorrect

Recommended Posts

xantier    210

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.

Share this post


Link to post
Share on other sites
Ohforf sake    2052
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.

Share this post


Link to post
Share on other sites
xantier    210

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.

Share this post


Link to post
Share on other sites
Ohforf sake    2052
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this