Как эмулировать GL_DEPTH_CLAMP_NV?

#opengl-es #shader #depth

#opengl-es #шейдер #глубина

Вопрос:

У меня есть платформа, на которой это расширение недоступно (не NVIDIA). Как я мог бы эмулировать эту функциональность? Мне это нужно для решения проблемы отсечения дальней плоскости при рендеринге теневых объемов трафарета с помощью алгоритма z-fail.

Комментарии:

1. Я пытаюсь эмулировать это расширение во фрагментном шейдере с помощью gl_FragDepth = clamp( gl_FragCoord.z, gl_DepthRange.near, gl_DepthRange.far ); , но оно работает не так, как должно.

2. Причина, по которой сжатие выходного z-значения не работает, заключается в том, что правила растеризации треугольника в первую очередь предотвращают генерацию фрагментов.

Ответ №1:

Поскольку вы говорите, что используете OpenGL ES, но также упомянули попытку зажать gl_FragDepth, я предполагаю, что вы используете OpenGL ES 2.0, так что вот трюк с шейдером:

Вы можете эмулировать ARB_depth_clamp, используя отдельную переменную для z-компонента.

Вершинный шейдер:

 varying float z;
void main()
{
    gl_Position = ftransform();

    // transform z to window coordinates
    z = gl_Position.z / gl_Position.w;
    z = (gl_DepthRange.diff * z   gl_DepthRange.near   gl_DepthRange.far) * 0.5;

    // prevent z-clipping
    gl_Position.z = 0.0;
}
  

Фрагмент шейдера:

 varying float z;
void main()
{
    gl_FragColor = vec4(vec3(z), 1.0);
    gl_FragDepth = clamp(z, 0.0, 1.0);
}
  

Комментарии:

1. Было бы правильно закрепить z уже в вершинном шейдере? Улучшит ли это производительность?

Ответ №2:

«Отступить» к ARB_depth_clamp ?

Проверьте, NV_depth_clamp существует ли вообще? Например, моя карта ATI поддерживает пять расширений GL «только для NVidia».