OpenGL阴影立方体映射 - 查找问题

时间:2013-05-25 13:50:48

标签: opengl glsl shader shadow

我正在尝试使用立方体贴图为点光源创建阴影。

我找到了帮助我的各种教程(Pointers on modern OpenGL shadow cubemapping?https://www.opengl.org/discussion_boards/showthread.php/169743-cubemap-shadows-for-pointlightshttp://www.cg.tuwien.ac.at/courses/Realtime/repetitorium/2011/OmnidirShadows.pdf,...)但我仍然遇到立方体地图查找问题。

此着色器创建立方体贴图(格式: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是光在世界空间中的位置,lightRange基本上是光投影矩阵的zFar。

使用gDEBugger调试应用程序时生成的立方体贴图看起来很好。

主着色器中的阴影查找:

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;

}

此函数的结果乘以光计算的值。问题是它总是返回1.0。

有谁知道我做错了什么?

1 个答案:

答案 0 :(得分:0)

您需要反转lookup_vector的y坐标。渲染(我假设)你的y坐标向上,但对于OpenGL纹理,y指向下方。你的场景是对称的,所以你的纹理一开始似乎是正确的但需要反映 - 或者只是转过你的lookup_vector

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

然后只需查看渲染到阴影贴图的距离:

float dist = texture(shadowMap, new_vec);

要测试的深度必须计算如下:

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_far是您的lightRangez_near是近平面等效物。最后但同样重要的是,返回结果:

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

我根据这个问题的答案进行了这些计算:Cubemap shadow mapping not working