每个片段照明和窗口到相机的转换

Posted

技术标签:

【中文标题】每个片段照明和窗口到相机的转换【英文标题】:per fragment lighting and window to camera transforms 【发布时间】:2012-05-07 13:02:19 【问题描述】:

我使用窗口到相机的变换实现了每个片段的光照和光衰减:

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));

我不知道我做错了什么。

【问题讨论】:

您的代码看起来是正确的,因此错误出现在您未发布的代码中。 【参考方案1】:

你这里有一个问题:

ndcPos.z = (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) / (gl_DepthRange.far - gl_DepthRange.near);

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

【讨论】:

当我使用 lightPos 和顶点位置乘以模型矩阵时,一切正常(良好的照明),但我想尝试使用 lightPos 和窗口到相机转换来计算照明。我基于link 实现了该技术,该教程有问题吗?我的代码和教程代码的主要区别在于相机的工作方式。【参考方案2】:

灯光有什么问题?当您移动视图时,照明是否会保持静止? (即镜面高光永远不会移动)。

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

【讨论】:

我还没有实现镜面高光,但你可以在下面的图片中看到有什么问题。照明向观察者方向扭曲。 lightPosition - (worldMatrix * vertexPosition) 给出完全不正确的光照。我的代码基于link 不良照明:link 良好照明(顶点位置而不是窗口到相机的转换):link 良好的照明是否也考虑了衰减? 是的,但正如我上面在良好照明中提到的,我使用顶点位置乘以模型矩阵。例如然后在光衰减方程中使用的距离 = length(lightPos - vec3(position));

以上是关于每个片段照明和窗口到相机的转换的主要内容,如果未能解决你的问题,请参考以下文章

在代码片段中包含类型转换

我可以将活动转换为浮动窗口吗?

共享转换片段到片段不起作用

给定相机参数,我如何找到从视图空间到像素坐标的转换?我的矩阵有啥问题?

将 XSLT 转换的 XML 片段写入 XMLStreamWriter

相机不显示,状态转换问题,反应原生