Использование трафаретного буфера в Direct3D - PullRequest
1 голос
/ 31 мая 2011

Я пытаюсь использовать трафаретные буферы на ID3D11Texture2D для наложения части одной текстуры на другую текстуру. Я планирую сделать это, нарисовав нужную фигуру в буфере трафарета, а затем скопировав текстуру. Пожалуйста, предложите хороший учебник с примером кода для 2D текстур, чтобы научиться использовать трафаретный буфер. (или какой-то другой способ сделать это)

1 Ответ

14 голосов
/ 21 июня 2011

Трафаретная маска 101:

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

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

Трафаретные маски на самом деле довольно просто генерировать:

  • Очистить буфер трафарета
  • Включить состояние трафарета для написания трафарета («заменить» на «stencilref 1» или «увеличить» вместо «сохранить»)
  • Нарисуйте многоугольник. Обратите внимание, что использование 'discard' в шейдере предотвратит обновление трафарета, то есть, как вы загружаете текстуру в буфер трафарета (но только в виде двоичной маски)

  • Отключить запись трафарета, включить проверку трафарета

  • (в идеале) также отключить глубину записи
  • Нарисуйте свой эффект, который требует маскировки трафарета
...