[英]Sampling data from a shadow map texture using automatic comparison via the texture2D function
我的着色器中有一个sampler2DShadow,我想用它来实现阴影贴图。 我的阴影纹理具有良好的初始化器,GL_TEXTURE_COMPARE_MODE设置为GL_COMPARE_R_TO_TEXTURE,GL_TEXTURE_COMPARE_FUNC设置为GL_LEQUAL(意味着如果我的坐标的r值小于或等于纹理中获取的深度值,则比较应返回1)。 此纹理绑定到在光空间坐标中渲染的FBO的GL_DEPTH_ATTACHMENT。
我应该在最终片段着色器中给出texture2D函数的坐标是什么? 我现在有一个
光滑的vec4 light_vert_pos
在我的片段着色器中设置,该着色器由函数在顶点着色器中定义
light_vert_pos = light_projection_camera_matrix * modelview * in_Vertex;
我想我可以将我的照明倍增
的Texture2D(阴影贴图,(light_vert_pos.xyz)/light_vert_pos.w)
但这似乎不起作用。 由于light_vert_pos仅在后投影坐标中(用于创建它的矩阵是我用来在FBO中创建深度缓冲区的矩阵),我应该手动将3 x / y / z变量钳制到[0,1]吗?
您没有说明如何生成深度值。 所以我假设您通过使用法线投影渲染三角形来生成深度值。 也就是说,您将几何体转换为相机空间,将其转换为投影空间,并让光栅化管道正常处理事物。
为了使阴影贴图起作用,您的纹理坐标必须与栅格化器的作用相匹配。
顶点着色器的输出是剪辑空间。 从那里,您获得透视分割,然后是视口变换。 后者使用glViewport和glDepthRange中的值来计算窗口空间XYZ。 窗口空间Z是写入深度缓冲区的深度值。
请注意,这是深度传递期间的全部内容:生成阴影贴图的深度值。
但是,您可以采取一些快捷方式。 如果你的glViewport范围被设置为与纹理相同的大小(通常是这样做的话),那么你可以忽略视口变换。 您仍然需要在深度传递中使用的glDepthRange。
在片段着色器中,您可以执行透视分割,它将坐标放在标准化设备坐标(NDC)空间中。 所有方向的空间都是[-1,1]。 你的纹理坐标是[0,1],所以你需要将X和Y除以2并将它们加0.5:
vec3 ndc_space_values = light_vert_pos.xyz / light_vert_pos.w
vec3 texCoords;
texCoords.xy = ndc_space_values.xy * 0.5 + 0.5;
要计算Z值,您需要知道用于glDepthRange
的near和far值。
texCoords.z = ((f-n) * 0.5) * ndc_space_values.z + ((n+f) * 0.5);
其中n
和f
是glDepthRange near和far值。 你当然可以预先计算其中一些并将它们作为制服传递给你。 或者,如果您使用near = 0和far = 1的默认范围,则得到
texCoords.z = ndc_space_values.z * 0.5 + 0.5;
哪个看起来很熟悉。
在旁边:
由于您使用in
而不是varying
来定义输入,因此必须使用GLSL 1.30或更高版本。 那么为什么你使用texture2D
(这是一个旧函数)而不是texture
?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.