延迟渲染和移动点光

时间:2011-08-28 15:57:18

标签: opengl shader lighting deferred-rendering

我知道网上有几个关于同样问题的线程,但我没有得到这些帮助,因为我的实现方式不同。

我将视图空间中的颜色,法线和深度渲染为纹理。第二,我用全屏四边形绑定纹理并计算光照。方向灯似乎工作正常,但点光源随着相机移动。

我分享了相应的着色器代码:

照明步骤顶点着色器

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

我将着色器作为制服发送给着色器:

shader->set("lightPosition", (viewMatrix * modelMatrix).inverse().transpose() * vec4(0, 10, 0, 1.0));

viewmatrix是相机矩阵,而modelmatrix只是这里的身份。

为什么点光源是用相机而不是模型进行平移的?

欢迎任何建议!

1 个答案:

答案 0 :(得分:3)

除了Nobody的评论之外,您计算的所有向量都必须进行标准化,您必须确保它们都在同一个空间中。如果使用视图空间位置作为视图矢量,法线矢量也必须在视图空间中(必须在第一遍中写入G缓冲区之前通过逆转置模型视图矩阵进行变换)。并且光矢量也必须在视图空间中。因此,您必须通过视图矩阵(或模型视图矩阵,如果光源位置不在世界空间中)而不是其反转置来变换光源位置。

shader->set("lightPosition", viewMatrix * modelMatrix * vec4(0, 10, 0, 1.0));

编辑:对于定向光,如果将光线方向指定为光线方向,则反向移调实际上是一个好主意(如{ - 1}}指向的光线 - z方向)。