Выполнение фрагмента DEPTH_TEST в OpenGL

Я могу включить / выключить тестирование глубины в OpenGL с помощью glEnable( GL_DEPTH_TEST ); Но это включает / выключает тест для всего вызова отрисовки.

Я хотел бы управлять тестом для каждого фрагмента.

Это сделано для достижения следующего эффекта: в шаблоне шахматной доски половина пикселей примитива потенциально закрыта, но другая половина всегда отображается, даже если в буфере кадра есть закрывающий объект, который находится ближе к камера.

Чтобы проиллюстрировать это, посмотрите этот пример, где только половина пикселей пирамиды потенциально закрыта прямоугольником перед ней.

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

Также обратите внимание: я буду рисовать объект с помощью специального теста глубины в последнюю очередь, поэтому случай, когда сначала будет нарисован красный прямоугольник, не произойдет.

Для моих целей все объекты, нарисованные таким образом, являются выпуклыми и никогда не закрываются.

иллюстрация эффекта

Я знаю, как получить узор шахматной доски в моем фрагментном шейдере:

                float xm2 = mod( gl_FragCoord.x, 2.0 );
                float ym2 = mod( gl_FragCoord.y, 2.0 );
                if ( int(xm2) != int(ym2) )
                        discard;

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

Я нацелен на OpenGL-ES 3.0.


person Bram    schedule 15.10.2019    source источник
comment
Это просто не то, как работает тест глубины. То, о чем вы просите, просто невозможно. Вы можете добиться такого эффекта, выполнив два вызова отрисовки и переключив тест глубины между ними, рисуя только одну группу вашего шаблона шахматной доски (т.е. используя буфер трафарета, сброс в FS также будет работать, просто намного менее эффективно). Другой подход может заключаться в установке gl_FragDepth в 0 для тех фрагментов, которые вы хотите всегда проходить тест.   -  person derhass    schedule 16.10.2019
comment
Чтобы проиллюстрировать это, посмотрите этот пример, где только половина пикселей пирамиды потенциально закрыта прямоугольником перед ней. Что именно вы хотите, если вы рисуете объекты в обратном порядке ?   -  person Nicol Bolas    schedule 16.10.2019
comment
А что должно произойти, если часть объекта перекрывает сама себя?   -  person Nicol Bolas    schedule 16.10.2019
comment
Я думаю, что X этой проблемы XY - это ситуация, когда OP хочет иметь возможность частично просматривать объект, даже если он скрыт материалом переднего плана. например Делая бросок в игре в гольф, вы хотите видеть мяч, даже если перед ним есть пейзаж. Я думаю, что предложение @derhass gl_FragDepth решит проблему OP, и его следует предлагать как ответ.   -  person Columbo    schedule 16.10.2019
comment
@derhass Ваше первое предложение сработало для меня. Если вы напишете это, я отмечу это как ответ. Установка глубины на 0 не подходила для моего приложения, так как мне нужен неповрежденный z-буфер для выбора объектов.   -  person Bram    schedule 17.10.2019
comment
Что, если бы вы записали глубину (gl_FragCoord.z) в альфа-канал для каждого фрагмента, а затем использовали EXT_shader_framebuffer_fetch, чтобы получить альфа-значение за текущим фрагментом (т.е. ранее записанную глубину)? Возможно, я неправильно понимаю, как они работают: p   -  person Andrea    schedule 06.12.2019


Ответы (1)


Этого легко добиться, дважды нарисовав (красную) сетку:

  • Сначала нарисуйте его как обычно, все фрагменты, с включенным тестом глубины.
  • Затем нарисуйте его снова, без проверки глубины и отбрасывая половину фрагментов.

Решение было подсказано комментарием @derhass.

person Bram    schedule 07.11.2020