Math 逐片段照明和窗口到摄影机变换

Math 逐片段照明和窗口到摄影机变换,math,opengl,glsl,opengl-4,Math,Opengl,Glsl,Opengl 4,我使用窗口到摄影机转换实现了逐片段照明和光衰减: vec4 ndcPos; ndcPos.xy = ((gl_FragCoord.xy / windowSize.xy) * 2.0) - 1.0; ndcPos.z = (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) / (gl_DepthRange.far - gl_DepthRange.near); ndcPos.w = 1.0; vec4 clipPos =

我使用窗口到摄影机转换实现了逐片段照明和光衰减:

vec4 ndcPos;
ndcPos.xy = ((gl_FragCoord.xy / windowSize.xy) * 2.0) - 1.0;
ndcPos.z = (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) / (gl_DepthRange.far - gl_DepthRange.near);
ndcPos.w = 1.0;

vec4 clipPos = ndcPos / gl_FragCoord.w;

vec3 cameraPos = vec3(clipToCameraMatrix * clipPos);
然后我使用lightPos和cameraPos计算照明。lightPos在世界空间中有一个固定的位置。我有ViewMatrix来处理fps样式的相机和ModelMatrix。早些时候,我使用顶点位置,而不是窗口到摄影机的变换,一切正常。现在,当我使用相机在物体周围移动时,我得到了不正确的照明。在上传到片段着色器之前,lightPos将乘以ViewMatrix

glUniform3fv(dirToLightUniformLocation, 1, glm::value_ptr(ViewMatrix * lightPos));

我不知道我做错了什么。

灯光怎么了?移动视图时,照明是否保持静止?(即镜面反射高光从不移动)


您的lightPos应该是:lightPosition-(worldMatrix*VertexExposition)的标准化Vec3

您这里有一个问题:


除非您使用的是正交投影,否则gl_FragCoord.z不会线性映射到深度范围,这是由w分割引起的。虽然可以(也不难)反向投影它,但我建议您只需使用附加的可变输入/输出将viewspace眼睛位置从顶点着色器传递到片段着色器。

我还没有实现镜面反射高光,但您可以在以下图像上看到问题所在。灯光向观察者扭曲。lightPosition-(worldMatrix*VertexExposition)提供的照明完全不正确。我的代码基于不良照明:良好照明(顶点位置而不是窗口到摄影机的变换):良好照明也考虑了衰减因素?是的,但正如我在上述良好照明中提到的,我使用顶点位置乘以模型矩阵。例如,在光衰减方程中使用的距离=长度(lightPos-vec3(位置));你的代码看起来是正确的,所以错误在你没有发布的代码中。当我使用lightPos和顶点位置乘以模型矩阵时,一切都正常(良好的照明),但我想尝试使用lightPos和窗口到相机变换计算照明。我是根据那个教程来实现这个技术的,有什么问题吗?我的代码和教程代码之间的主要区别在于相机的工作方式。
ndcPos.z = (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) / (gl_DepthRange.far - gl_DepthRange.near);