Приоритизация выбранных линейных объектов над другими путем манипулирования gl_FragDepth - PullRequest
0 голосов
/ 17 сентября 2018

В нашем текущем проекте у нас есть вероятность, что некоторые линии будут нарисованы в одном и том же месте.Чем мы имеем такой мерцающий эффект.

Я пытаюсь манипулировать значениями gl_FragDepth в зависимости от типов геометрии, чтобы преодолеть эту проблему.В моем фрагментном шейдере у меня есть что-то вроде:

if ( offset > 0.0 )
   gl_FragDepth =  gl_FragCoord.z - offset*0.001;

Некоторые строки имеют приоритеты над другими объектами, и я манипулирую единой переменной «смещение», чтобы добиться этого.

Результат немного лучше на первый взгляд:

enter image description here

Даже объект, имеющий определенное положение, выглядит лучше. У меня проблемыв нормальном случае объекты прыгают друг на друга.

Мои вопросы:

1 - Является ли манипулирование gl_FragDepth с наименьшей возможной глубиной z для определенных приоритетных объектов хорошей стратегией?

2 - Если это так, вместо назначения gl_FragCoord.z ​​я должен использовать что-то вроде , описанное здесь .?

Что я пробовал, вызвав эту функцию:

 float findRealDepth(in highp mat4 modelViewProjectinMatrix,
                     in highp vec4 objectPosition)
        {
            float far=gl_DepthRange.far; float near=gl_DepthRange.near;
            vec4 clip_space_pos = modelViewProjectinMatrix * vec4(objectPosition.xyz, 1.0);
            float ndc_depth = clip_space_pos.z / clip_space_pos.w;
            return (((far-near) * ndc_depth) + near + far) / 2.0;
        };

1 Ответ

0 голосов
/ 20 сентября 2018

Значение, которое записывается в gl_FragDepth в фрагментном шейдере , указывает значение глубины для обрабатываемого фрагмента. Это значение записывается в буфер глубины.
Как правило, значение глубины должно находиться в диапазоне [0, 1] (за исключением того, что glDepthRange указано другое отображение).

Если gl_FragDepth не задан в фрагментном шейдере, то значение, которое записывается в буфер глубины, является нормализованной пространством устройства z координата, отображаемая из диапазона [- 1, 1] в диапазоне [0, 1] .

Это означает, что значение глубины можно выразить следующим образом:

depth = 0.5 + 0.5 * gl_Position.z / gl_Position.w;

Во фрагментном шейдере это значение можно прочитать из компонента z встроенной входной переменной Fragment gl_FragCoord.

Это означает, что выражение

gl_FragDepth = gl_FragCoord.z;

сохранит в буфере глубины то же значение, которое будет автоматически сохранено в нем, без записи в gl_FragDepth.

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

gl_FragDepth =  gl_FragCoord.z - offset;  

Значение offset должно быть больше или равно минимальному значению, которое можно сохранить в буфере глубины.

Если используется формат буфера глубины с фиксированной запятой (например, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24), тогда глубина 0.0 представляется всеми битами 0, а глубина 1.0 представляется всеми битами 1.
Минимальное значение - это значение, в котором установлен младший значащий бит, а все остальные биты равны нулю.

Это означает, что для буфера глубины с фиксированной точкой с 24 битами (GL_DEPTH_COMPONENT24) минимальное значение, которое может быть представлено:

1 / (2^24 - 1)

в GLSL:

1.0 / (exp2(24.0) - 1.0) 

Из-за соотношения между gl_Position, gl_FragCoord и gl_FragDepth, как описано выше, смещение глубины также может применяться к gl_Position в вершинном шейдере, после того как gl_Position было установлено:

gl_Position.z = gl_Position.z - offset * 2.0 * gl_Position.w;

Обратите внимание, что манипулирование координатой z пространства вида постоянным значением не может обеспечить тот же эффект (в перспективной проекции). Координата z пространства представления не преобразуется линейно в нормализованную координату z устройства (из-за разрыва перспективы).
См. Как линейно визуализировать глубину в современном OpenGL с gl_FragCoord.z ​​во фрагментном шейдере?

...