延迟渲染和移动点光源

4

我知道网络上有一些与此问题相关的帖子,但由于我的实现方式不同,所以我没有从中得到帮助。

我正在将颜色、法线和深度在视图空间中渲染成纹理。然后我绑定这些纹理到全屏四边形上并计算光照。方向光似乎工作得很好,但点光源会随着相机移动。

以下是对应的着色器代码:

光照步骤顶点着色器

in vec2 inVertex;
in vec2 inTexCoord;
out vec2 texCoord;
void main() {
    gl_Position = vec4(inVertex, 0, 1.0);
    texCoord = inTexCoord;
}

光照步骤片段着色器

float depth = texture2D(depthBuffer, texCoord).r;
vec3 normal = texture2D(normalBuffer, texCoord).rgb;
vec3 color = texture2D(colorBuffer, texCoord).rgb;

vec3 position;
position.z = -nearPlane / (farPlane - (depth * (farPlane - nearPlane))) * farPlane;
position.x = ((gl_FragCoord.x / width) * 2.0) - 1.0;
position.y = (((gl_FragCoord.y / height) * 2.0) - 1.0) * (height / width);
position.x *= -position.z;
position.y *= -position.z;

normal = normalize(normal);
vec3 lightVector = lightPosition.xyz - position;
float dist = length(lightVector);
lightVector = normalize(lightVector);

float nDotL = max(dot(normal, lightVector), 0.0);
vec3 halfVector = normalize(lightVector - position);
float nDotHV = max(dot(normal, halfVector), 0.0);

vec3 lightColor = lightAmbient;
vec3 diffuse =  lightDiffuse * nDotL;
vec3 specular = lightSpecular * pow(nDotHV, 1.0) * nDotL;
lightColor += diffuse + specular;
float attenuation = clamp(1.0 / (lightAttenuation.x + lightAttenuation.y * dist + lightAttenuation.z * dist * dist), 0.0, 1.0);

gl_FragColor =  vec4(vec3(color * lightColor * attenuation), 1.0);

我将光线属性作为uniform发送到着色器中:
shader->set("lightPosition", (viewMatrix * modelMatrix).inverse().transpose() * vec4(0, 10, 0, 1.0));

viewmatrix是相机矩阵,而modelmatrix只是身份证明。

为什么点光源与模型不一起移动,而是随着相机移动?

欢迎提出任何建议!


3
为了使 vec3 halfVector = normalize(lightVector - position); 能够正常工作,向量 position 必须具有单位长度(或至少与 lightVector 相同),否则你将得到一个加权的解而不是一半的向量。 - Nobody moving away from SE
1个回答

4
除了Nobody的评论之外,你计算的所有向量都必须被规范化,你还必须确保它们都在同一个空间内。如果你使用视图空间位置作为视图向量,则法向量也必须在视图空间中(在第一次遍历中写入G缓冲区之前必须通过逆转置模型视图矩阵进行变换)。光向量也必须在视图空间中。因此,你必须通过视图矩阵(如果光位置不在世界空间中,则使用模型视图矩阵)来转换光位置,而不是使用其逆转置。
shader->set("lightPosition", viewMatrix * modelMatrix * vec4(0, 10, 0, 1.0));

编辑:对于定向光源,如果您指定的是指向光源的方向(例如vec4(0, 1, 0, 0)表示朝向-z方向的光源),那么使用逆转置矩阵实际上是一个不错的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接