Логарифмический буфер глубины OpenGL
Мне удалось реализовать логарифмический буфер глубины в OpenGL, в основном благодаря статьям изOuterra (Вы можете прочитать ихВот, Вот, а такжеВот). Тем не менее, у меня есть некоторые проблемы, и я не уверен, являются ли эти проблемы присущими использованию логарифмического буфера глубины или есть какой-то обходной путь, о котором я не могу думать.
Для начала, вот как я вычисляю логарифмическую глубину в вершинном шейдере:
gl_Position = MVP * vec4(inPosition, 1.0);
gl_Position.z = log2(max(ZNEAR, 1.0 + gl_Position.w)) * FCOEF - 1.0;
flogz = 1.0 + gl_Position.w;
И вот как я фиксирую значения глубины во фрагментном шейдере:
gl_FragDepth = log2(flogz) * HALF_FCOEF;
кудаZNEAR = 0.0001
, ZFAR = 1000000.0
, FCOEF = 2.0 / log2(ZFAR + 1.0)
, а такжеHALF_FCOEF = 0.5 * FCOEF
. C
в моем случае это 1.0, чтобы упростить мой код и сократить вычисления.
Для начала, я очень доволен уровнем точности, которую я получаю. При нормальной буферизации глубины (znear = 0.1, zfar = 1000.0) я получаю немного z-боев по направлению к краю расстояния просмотра. Прямо сейчас, с моим НАМНОГО большим znear: zfar, я положил вторую плоскость земли на 0,01 единицы ниже первой, и я не могу найти z-бой, независимо от того, насколько далеко я уменьшаю камеру (я получаю немного z- борьба, когда он всего в 0,0001 (0,1 мм), но ме).
У меня есть некоторые проблемы / проблемы, однако.
1) Я получаю больше отсечения в плоскости, чем с обычным буфером глубины, и это выглядит ужасно. Это происходит в тех случаях, когда, по логике, это действительно не должно. Вот несколько скриншотов того, что я имею в виду:
Стричь землю. Отсечение сетки.
Оба эти случая - вещи, которые я не испытывал с моим обычным буфером глубины, и я бы предпочел не видеть (особенно первый). РЕДАКТИРОВАТЬ: проблема 1 официально решается с помощьюglEnable(GL_DEPTH_CLAMP)
.
2) Чтобы заставить это работать, мне нужно написать gl_FragDepth. Я пытался не делать этого, но результаты были неприемлемы. Запись в gl_FragDepth означает, что моя видеокарта не может выполнять ранние z-оптимизации. Это неизбежно приведет меня к стене, и поэтому я хочу исправить это, как только смогу.
3) Мне нужно иметь возможность извлечь значение, хранящееся в буфере глубины (для этого у меня уже есть кадровый буфер и текстура), а затем преобразовать его в линейную координату пространства вида. Я действительно не знаю, с чего начать, как я делал это раньше, задействовал матрицу обратной проекции, но я не могу сделать это здесь. Любой совет?