Понимание создания всенаправленной карты теней - PullRequest
0 голосов
/ 26 апреля 2020

В настоящее время я изучаю, как создать всенаправленную карту теней для точечного света из следующего ресурса: https://learnopengl.com/Advanced-Lighting/Shadows/Point-Shadows

Автор говорит о многоуровневом рендеринге, где вместо выполнения 6 проходов для каждой кубической карты Лицом к лицу мы используем один проход и умножаем количество фрагментированных шейдеров на 6 для каждого me sh, используя этап геометрического шейдера для многоуровневого рендеринга.

Он достигает этого с помощью следующих вершинных, геометрических и фрагментных шейдеров соответственно :

#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;
}

Также я хотел бы понять, как можно использовать переменные затухания точечный источник света (постоянная квадратичная c линейная) для расчета дальней плоскости z матрицы проекции для тени отображение.

...