Инвертированная геометрия позиции gBuffer для перспективы. Орфография в порядке? - PullRequest
3 голосов
/ 10 ноября 2019

У меня есть отложенный рендер, который, кажется, работает правильно, глубина, цвет и тени отображаются правильно. Однако буфер положения подходит для орфографии, в то время как геометрия выглядит «перевернутой» (или глубина отключена) при использовании перспективной проекции.

Я получаю следующие выходные данные буфера для орфографии.

depth

normals

positions

С окончательным заштрихованным изображением, в настоящее время выглядящим правильным.

enter image description here

Однакокогда я использую перспективную проекцию, я получаю следующие буферы ...

enter image description here

enter image description here

enter image description here

И с окончательным изображением все в порядке, хотя в данный момент я не включаю информацию о буфере позиции (NB Только делаю затенение 'фары' на данный момент)

enter image description here

Хотя конечное изображение выглядит правильно, буфер глубины, похоже, игнорируется для моего буфера позиции ... (в glDisable (GL_DEPTH_TEST) неткод.

Глубина и нормальные буферы выглядят хорошо для меня, это только буфер 'position', который, кажется, игнорирует глубину? Конвейер рендеринга точно такой же для илиtho и перспектива с единственной разницей, являющейся матрицей проекции.

Я использую glm::ortho и glm::perspective, и я вычисляю мои ближние / дальние расстояния отсечки на лету, основываясь на сцене AABB. Для орфографии мой ближний / дальний - 1 и 11,4734 соответственно, а для перспективы - 11,0875 и 22,5609 ... Значения ширины и высоты одинаковы, для перспективной проекции - 45.

У меня есть эти вызовыперед рисованием любой геометрии ...

glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Что я использую для компоновки различных слоев как часть конвейера рендеринга.

Я что-то здесь не так делаю? или я что то недопонимаю?

Вот мои шейдеры ... Вершинный шейдер gBuffer ...

#version 430 core

layout (std140) uniform MatrixPV
{
    mat4 P;
    mat4 V;
};

layout(location = 0) in vec3 InPoint;
layout(location = 1) in vec3 InNormal;
layout(location = 2) in vec2 InUV;

uniform mat4 M;

out vec4 Position;
out vec3 Normal;
out vec2 UV;

void main()
{
    mat4 VM = V * M;
    gl_Position = P * VM * vec4(InPoint, 1.0);
    Position = P * VM * vec4(InPoint, 1.0);
    Normal = mat3(M) * InNormal;
    UV = InUV;
}

Фрагмент шейдера gBuffer ...

#version 430 core

layout(location = 0) out vec4 gBufferPicker;
layout(location = 1) out vec4 gBufferPosition;
layout(location = 2) out vec4 gBufferNormal;
layout(location = 3) out vec4 gBufferDiffuse;

in vec3 Normal;
in vec4 Position;

vec4 Diffuse();
uniform vec4 PickerColour;

void main()
{
    gBufferPosition = Position;
    gBufferNormal = vec4(Normal.xyz, 1.0);
    gBufferPicker = PickerColour;
    gBufferDiffuse = Diffuse();
}

А вот и 'шейдер второго прохода для визуализации буфера позиции ...

#version 430 core

uniform sampler2D debugBufferPosition;

in vec2 UV;
out vec4 frag;

void main()
{
    vec3 val = texture(debugBufferPosition, UV).xyz;
    frag = vec4(val.xyz, 1.0);
}

Я еще не использовал данные буфера позиции, и я знаю, что могу восстановить их, не сохраняя их в другом буфере, однакопозиции полезны для меня по другим причинам, и я хотел бы знать, почему они выходят так, как они для перспективы?

1 Ответ

1 голос
/ 10 ноября 2019

То, что вы на самом деле записываете в буфер позиции, это координата пространства клипа

Position = P * VM * vec4(InPoint, 1.0);

Координата пространства клипа представляет собой Однородные координаты и преобразуется в нормализованнуюCooridnate устройства (который является декартовой координатой на Перспективное деление .

ndc = gl_Position.xyz / gl_Position.w;

При ортографической проекции компонент w равен 1, но при перспективной проекции,компонент w содержит значение, которое зависит от компонента z (глубина) (декартовой) координаты пространства обзора.

Я рекомендую сохранять нормализованную координату устройства в буфере положения, а не вкоордината пространства клипа, например:

gBufferPosition = vec4(Position.xyz / Position.w, 1.0);
...