Joe's CGСтатьи

Эффективное использование Early Rejection Tests при визуализации мягких теней

Автор:

А что тут понимать, собственно? Подумаешь, бином Ньютона...
Тоже мне - психологические бездны. В институте мы на плохом счету,
средств на экспедицию нам не дают. Эх..  набьем-ка  мы  наш  рюкзак
всякими манометрами-дерьмометрами, проникнем в Зону  нелегально... 
И  все здешние чудеса поверим алгеброй. Никто в мире про Зону понятия не  имеет.
И  тут,  конечно, сенсация!  Телевидение,  поклонницы  кипятком  писают, 
лавровые  веники несут... появляется наш  Профессор  весь  в  белом 
и  объявляет: мене-мене, текел, упарсин. Ну, натурально, все разевают рты и
хором кричат: Нобелевскую ему!..

Аркадий и Борис Стругацкие. Сталкер

Данная статья ставит своей целью объяснить важность использования аппаратного отсечения фрагментов при визуализации мягких теней с использованием алгоритма Penumbra Wedges.

Область пенумбры на экране определяется теми пикселями, точки которых (с оконными координатами (x, y) и координатой глубины z) расположены внутри пенумбральных клиньев. Однако, пенумбральные клинья обычно охватывают намного больше пикселей, которые расположены вне их геометрии. Для этих пикселей нет необходимости выполнять сложный фрагментный шейдер, производящий штриховку тени. В обычных условиях, однако, фрагментный шейдер будет выполняться для всей площади экрана, которую охватывают клинья, а следовательно, производительность процесса рисования будет неудовлетворительной.

Поэтому, в идеале, фрагментный шейдер должен выполняться только в тех пикселях, которые расположены внутри клиньев, а все остальные пиксели, расположенные извне, должны отсекаться. Такое отсечение может быть выполнено с использованием двух проходов и комбинацией теста глубины и теста трафарета. Этот метод был описан авторами алгоритма Penumbra Wedges в документе "An Optimized Soft Shadow Volume Algorithm with Real-Time Performance" (в описании есть небольшая опечатка).

Wedges01 | Эффективное использование Early Rejection Tests при визуализации мягких теней

Рис. 1. Процесс растеризации пенумбрального клина и области пенумбры с использованием тестов глубины и трафарета.

На рис. 1. показана идея метода. В типичной ситуации пенумбральный клин занимает площадь, значительно больше площади самой пенумбры (a). Сперва, в буфер трафарета рисуются лицевые треугольники клина. Тест глубины устанавливается как LESS, т. е. проходят только те фрагменты, которые ближе к глазу наблюдателя. При этом значение в буфере трафарета увеличивается на единицу (b). После этого устанавливается фрагментный шейдер и в буфер цвета рисуются тыльные треугольники клина, при этом включаются оба теста глубины и трафарета. Тест трафарета устанавливается только для тех фрагментов, значения в которых не равно 0, а тест глубины устанавливается как GREATER, т. е. проходят только те фрагменты, которые дальше от глаза наблюдателя (c). Если один из этих тестов провален, то это означает, что точка находится вне геометрии клина, и отбрасывается с конвейера. В итоге, фрагментный шейдер выполняется только в тех пикселях, где необходимо заштриховать тень (d).

Чтобы фрагмент был отброшен, крайне важно, чтобы видеоускоритель был способен выполнять ранний тест глубины (early depth test) и ранний тест трафарета (early stencil test). В противном случае, на экране будет заштрихована только требуемая область, но фрагментный шейдер всё равно будет выполнен везде, что приведёт к низкой производительности. К сожалению, эти виды тестов не являются стандартными для графического конвейера и реализуются производителями аппаратного обеспечения опционально, как средство ускорения рендеринга. Однако они всё же присутствуют в современном графическом железе (например, в NV4x и выше, в R5xx и выше) и их можно задействовать с переменным успехом. Как показали проведённые OpenGL-тесты, early rejection очень хорошо работает на видеокартах ATI, а у видеокарт NVidia существуют определённые проблемы с выполнением раннего теста трафарета. При определённых условиях можно задействовать этот тест во внеэкранном P-буфере, который имеет front и back буферы.

Чтобы предотвратить отключение (или неэффективную работу) early rejection, фрагментный шейдер не должен менять значение глубины или выполнять discard фрагмента.

15 октября 2007