首页 > 解决方案 > 了解全向阴影贴图的生成

问题描述


我目前正在学习如何从以下资源生成点光的全向阴影贴图: https ://learnopengl.com/Advanced-Lighting/Shadows/Point-Shadows

作者谈论的是分层渲染,我们不是为每个立方体贴图面执行 6 次传递,而是使用一次传递,并通过使用几何着色器阶段将每个网格的片段着色器数量乘以 6 进行分层渲染。

他分别使用以下顶点、几何和片段着色器实现了这一点:

#version 330 core
layout (location = 0) in vec3 aPos;

uniform mat4 model;

void main()
{
    gl_Position = model * vec4(aPos, 1.0);
}  
#version 330 core
layout (triangles) in;
layout (triangle_strip, max_vertices=18) out;

uniform mat4 shadowMatrices[6];

out vec4 FragPos; // FragPos from GS (output per emitvertex)

void main()
{
    for(int face = 0; face < 6; ++face)
    {
        gl_Layer = face; // built-in variable that specifies to which face we render.
        for(int i = 0; i < 3; ++i) // for each triangle vertex
        {
            FragPos = gl_in[i].gl_Position;
            gl_Position = shadowMatrices[face] * FragPos;
            EmitVertex();
        }    
        EndPrimitive();
    }
}  
#version 330 core
in vec4 FragPos;

uniform vec3 lightPos;
uniform float far_plane;

void main()
{
    // get distance between fragment and light source
    float lightDistance = length(FragPos.xyz - lightPos);

    // map to [0;1] range by dividing by far_plane
    lightDistance = lightDistance / far_plane;

    // write this as modified depth
    gl_FragDepth = lightDistance;
}  

我很难理解的是,为什么还要FragPos在几何着色器和片段着色器之间保留?

我知道他用它来计算到灯光位置的线性距离,但为什么我们不能像这样得到线性 z 坐标:

#version 330 core

uniform float u_Near;
uniform float u_Far;

float linearizeDepth(float depth)
{
    float z = depth * 2.0 - 1.0; // back to NDC 
    return (2.0 * u_Near * u_Far) / (u_Far + u_Near - z * (u_Far - u_Near));
}

void main()
{
    float depth = linearizeDepth(gl_FragCoord.z);
    gl_FragDepth = depth;
}

此外,我想了解如何使用点光的衰减变量(常数二次线性)来计算投影矩阵的远 z 平面以进行阴影映射。

标签: openglgraphicsglsllightshadow-mapping

解决方案


推荐阅读