我有一个工作的G缓冲区(颜色、法线、深度),对于每个聚光灯,我都有灯光视角的深度图。问题是在照明地图阶段,我无法让它工作。你能指出这里出了什么问题吗?
以下是我对这个过程的"理解":
1. Pass the G-buffer depth map to the lighting shader
2. Pass the light's depth map to the lighting shader
3. For each pixel in the G-buffer depth map:
3.1. Get the depth value from the texture
3.2. Convert the X and Y coordinates from texture space to clip space
3.2.1. pos.x = texcoord.x * 2.0 - 1.0;
3.2.2. pos.y = -(texcoord.y * 2.0 - 1.0);
3.3. Set pos.w to 1
3.4. Multiply the position by inverse view projection matrix to get the world space coordinate
3.5. Divide the new coordinates by w to "correct" the coords
3.6. Multiply the coordinates by light's view matrix
3.7. Change the coordinates from clip space to texture space
3.8. Compare the Z value of the pixel to the depth value in the light's depth map
3.9. If pos.z > depthmap.z, the pixel is in shadow
过程实际上恰恰相反。不将纹理坐标转换为片段空间,而是将坐标从片段空间转换为纹理。要实现这一点,您需要将光摄影机和投影传递到片段着色器(并将位置从顶点着色器传递到片段着色,至少在OpenGLES 2.0中,不知道OpenGL 3.3)
- 将位置乘以摄影机和投影,即可获得灯光视图中的位置
- 将xyz除以w,即可获得灯光视图的剪辑空间中的位置
- 将x和y乘以0.5,再加上0.5,就得到了阴影贴图的uv坐标
现在,您可以从uv下的阴影贴图中读取深度,并将其与像素的深度进行比较。