Использование буфера трафаретов в Direct3D

#textures #direct3d #stencil-buffer

#Текстуры #direct3d #буфер трафаретов

Вопрос:

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

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

1. Пожалуйста, кто-нибудь, дайте мне ссылку на хороший учебник по использованию Stencil Buffer в Direct3D с каким-нибудь базовым примером, таким как маскировка пикселей.

Ответ №1:

Маска трафарета 101:

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

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

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

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

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

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

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

1. Спасибо, было бы полезно, если бы вы могли привести мне какой-нибудь пример кода того, как мы создаем некоторый базовый эффект, используя буфер трафаретов в D3D11.