В моем отложенном рендере мне удалось успешно восстановить позицию фрагмента из буфера глубины … в основном. Сравнивая мои результаты с положением, сохраненным в дополнительном буфере, я заметил, что я получаю много всплывающих сообщений далеко от экрана. Вот скриншот того, что я вижу:
Зеленая и желтая части в верхней части — это просто скайбокс, где буфер положения содержит (0, 0, 0), но алгоритм реконструкции интерпретирует его как обычный фрагмент с глубиной = 0.0 (или 1.0?).
Сцена отображается с использованием fragColor = vec4(0.5 + (reconstPos - bufferPos.xyz), 1.0);
Таким образом, в любом месте, где результирующий фрагмент будет точно (0,5, 0,5, 0,5), где реконструкция и буфер имеют одинаковое значение. Следует ожидать неточности в задней части буфера глубины, но этот пурпурный и синий кажется немного странным.
Вот как я реконструирую позицию из буфера глубины:
vec3 reconstructPositionWithMat(vec2 texCoord)
{
float depth = texture2D(depthBuffer, texCoord).x;
depth = (depth * 2.0) - 1.0;
vec2 ndc = (texCoord * 2.0) - 1.0;
vec4 pos = vec4(ndc, depth, 1.0);
pos = matInvProj * pos;
return vec3(pos.xyz / pos.w);
}
куда texCoord = gl_FragCoord.xy / textureSize(colorBuffer, 0);
, а также matInvProj
является обратной матрицей проекции, используемой для рендеринга gbuffer.
Прямо сейчас мой буфер позиции GL_RGBA32F
(так как это только для проверки точности, меня не волнует пропускная способность и потеря памяти), и мой буфер глубины GL_DEPTH24_STENCIL8
(Я получил аналогичные результаты от GL_DEPTH_COMPONENT32
и да, мне нужен трафаретный буфер).
Мой znear — 0,01f, а Zfar — 1000,0f. Я рендеринг одного квадра в качестве моей земли, которая имеет размер 2000.0f x 2000.0f (я хотел, чтобы он был достаточно большим, чтобы он мог обрезать с дальней плоскости).
Этот уровень неточности считается приемлемым? Как люди могут обойти эту проблему? Что-то не так с тем, как я восстанавливаю положение вида / пространства глаз?
Задача ещё не решена.
Других решений пока нет …