Логарифмический буфер глубины 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) Мне нужно иметь возможность извлечь значение, хранящееся в буфере глубины (для этого у меня уже есть кадровый буфер и текстура), а затем преобразовать его в линейную координату пространства вида. Я действительно не знаю, с чего начать, как я делал это раньше, задействовал матрицу обратной проекции, но я не могу сделать это здесь. Любой совет?

Ответы на вопрос(3)

Ваш ответ на вопрос