繁体   English   中英

通过texture2D函数使用自动比较从阴影贴图纹理中采样数据

[英]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);

其中nf是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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM