过去两周我一直在尝试实现延迟渲染。我终于来到了使用模板缓冲区和线性化深度的聚光灯通道部分。我持有 3 个帧缓冲纹理:反照率、法线+深度(X、Y、Z、EyeViewLinearDepth)、光照纹理。所以我画了我的光(球体)并应用这个片段着色器:
void main(void)
{
vec2 texCoord = gl_FragCoord.xy * u_inverseScreenSize.xy;
float linearDepth = texture2D(u_normalDepth, texCoord.st).a;
// vector to far plane
vec3 viewRay = vec3(v_vertex.xy * (-farClip/v_vertex.z), -farClip);
// scale viewRay by linear depth to get view space position
vec3 vertex = viewRay * linearDepth;
vec3 normal = texture2D(u_normalDepth, texCoord.st).xyz*2.0 - 1.0;
vec4 ambient = vec4(0.0, 0.0, 0.0, 1.0);
vec4 diffuse = vec4(0.0, 0.0, 0.0, 1.0);
vec4 specular = vec4(0.0, 0.0, 0.0, 1.0);
vec3 lightDir = lightpos - vertex ;
vec3 R = normalize(reflect(lightDir, normal));
vec3 V = normalize(vertex);
float lambert = max(dot(normal, normalize(lightDir)), 0.0);
if (lambert > 0.0) {
float distance = length(lightDir);
if (distance <= u_lightRadius) {
//CLASSICAL LIGHTING COMPUTATION PART
}
}
vec4 final_color = vec4(ambient + diffuse + specular);
gl_FragColor = vec4(final_color.xyz, 1.0);
}
您需要知道的变量:v_vertex 是(球体)顶点的眼睛空间位置,lightpos 是眼睛空间中光线的位置/中心,linearDepth 是在眼睛空间中的几何传递阶段生成的。
问题是,如果检查 : ,代码会失败if (distance <= u_lightRadius)
。在我删除距离检查之前,永远不会计算灯光。我确信我正确传递了这些值,半径为 170.0,灯光位置距离模型仅 40-50 个单位。肯定有问题,但我无法以某种方式找到它。我尝试了半径和其他变量的许多可能性。