Трафаретная маска 101:
- Все основные графические процессоры используют 8-битный буфер трафарета, и они привязаны к буферу глубины, поэтому вы должны выбрать формат буфера, который включает трафарет (прежде всего D24S8)
- Очистите глубину и трафарет для начала каждого кадра, чтобы избежать проблем с производительностью между кадрами * (см. Примечание ниже)
- Если вы не знаете, что делаете, всегда используйте 0xFF для маски чтения и записи.
- По соображениям производительности не включайте запись глубины при выполнении тестов на чтение трафаретов
- По соображениям производительности, если это вообще возможно, держите тесты чтения трафарета ограниченными == 0 и! = 0 и очищайте до нуля
- Если вы используете D3D9, вы можете использовать обрезки ножниц в сочетании с очисткой буфера трафарета, это немного быстрее, чем рендеринг четырехугольника вручную, чтобы установить буфер в ноль.
- Нет способа получить доступ к информации трафарета в шейдере, поэтому эффекты постобработки не могут определить состояние трафарета смежных пикселей без маски, находящейся в обычной цели рендеринга и сэмплированной как текстура.
- Значения буфера трафарета могут быть изменены из следующих условий:
- Проверка трафарета не пройдена
- Проверка глубины не пройдена
- Испытания трафарета и глубины прошли 1024 *
- Какое бы условие ни было первым, оно определяет действие, которое может быть
- keep (оставить значение шаблона в покое)
- заменить (заменить значение трафарета на значение 'stencilref')
- приращение (добавить 1 к текущему буферу)
- декремент (sub 1 из буфера трафарета)
- ноль (установить значение равным нулю, полезно, когда одному из других условий необходимо использовать текущее значение stencilref)
* Невыполнение большинства этих правил обычно приводит к ухудшению производительности трафарета: ваш пиксельный шейдер выполняется для каждого пикселя и не выполняет раннее отклонение для пикселей, маскированных трафаретом. Кроме того, на старых картах Geforce это также может привести к нарушению раннего отклонения глубины для всех последующих вызовов отрисовки, которое не будет исправлено до тех пор, пока не будет очищен следующий кадр или буфер и трафарет глубины.
Трафаретные маски на самом деле довольно просто генерировать:
- Очистить буфер трафарета
- Включить состояние трафарета для написания трафарета («заменить» на «stencilref 1» или «увеличить» вместо «сохранить»)
Нарисуйте многоугольник. Обратите внимание, что использование 'discard' в шейдере предотвратит обновление трафарета, то есть, как вы загружаете текстуру в буфер трафарета (но только в виде двоичной маски)
Отключить запись трафарета, включить проверку трафарета
- (в идеале) также отключить глубину записи
- Нарисуйте свой эффект, который требует маскировки трафарета