0
votes

I am trying to use a cube map to create shadows for a point light.

I found various tutorial that helped me (Pointers on modern OpenGL shadow cubemapping?, https://www.opengl.org/discussion_boards/showthread.php/169743-cubemap-shadows-for-pointlights, http://www.cg.tuwien.ac.at/courses/Realtime/repetitorium/2011/OmnidirShadows.pdf, ...) but I still have problems with the cube map lookup.

This shader creates the cube map (Format: GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE):

//vertex shader
#version 330

uniform mat4 Model;
uniform mat4 View;
uniform mat4 Projection;

in vec3 vertex;

out vec3 vertexModel;

void main()
{       
    gl_Position =  Projection * View * Model * vec4(vertex, 1.0);
    vertexModel = vec3(Model * vec4(vertex, 1.0));
}

//fragment shader
#version 330

uniform vec3 lightPosition;
uniform float lightRange;

out float fragDepth;
out vec4 fragColor;

in vec3 vertexModel;

void main()
{   
    gl_FragDepth = length(lightPosition - vertexModel) / lightRange;  
    fragColor = vec4(1.0);
}

lightPosition is the position of the light in world space, lightRange is basically the zFar of the light's projection matrix.

The generated cube map looks good when debugging the application with gDEBugger.

Shadow lookup in the main shader:

float shadowValue(int i)
{
    vec3 lookup_vector = vertexModel - lightPosition;
    float dist = texture(shadowMap, lookup_vector).r; 

    float curr_fragment_dist_to_light = length(lookup_vector) / lightRange;

    float result = 1.0; 
    if (dist < curr_fragment_dist_to_light)
        result = 0.0;
    return result;

}

The result of this function is multiplied with the value frum the light calculation. The problem is that it returns always 1.0.

Has anyone an idea what i am doing wrong?

1
have you tried to just return dist or curr_fragment_dist_to_light to see how that affects your scene?Grimmy
yes. curr_fragment_dist_to_light is good - it gets greater farther away from the light. Thre problem is dist - the cube map lookup. It's always 1.0 (or at least a very high value) and is always constant. This is the generated shadow map: http://oi40.tinypic.com/6gcwte.jpg (I switched to back-face culling for the screenshot, normally I render the shadow map with front-face culling.)Lukas F.

1 Answers

0
votes

You need to invert the y-coordinate of the lookup_vector. While rendering (I presume) your y-coordinate points upwards but for OpenGL textures, y points downwards. Your scene is symmetrical, so your texture seems to be correct at first but it needs to be reflected - or just turn around your lookup_vector:

vec3 new_vec = vec3(lookup_vector .x, -lookup_vector .y, lookup_vector .z);

Then just look up the distance rendered to your shadow map as you already did:

float dist = texture(shadowMap, new_vec);

The depth to test against has to be computed like this:

vec3 abs_vec = abs(new_vec);
float local_z_comp = max(abs_vec .x, max(abs_vec .y, abs_vec .z));
float norm_z_comp = (z_far + z_near) /
    (z_far - z_near) - (2 * z_far * z_near) / (z_far - z_near) / local_z_comp;
float curr_fragment_dist_to_light = (norm_z_comp + 1.0) * 0.5;

z_faris your lightRange, z_near is the near plane equivalent. Last but not least, return your result:

float result = 1.0; 
if (dist < curr_fragment_dist_to_light)
    result = 0.0;
return result;

I based these computations on the answer to this question: Cubemap shadow mapping not working