#textures #direct3d #stencil-buffer
#Текстуры #direct3d #буфер трафаретов
Вопрос:
Я пытаюсь использовать буферы трафаретов на ID3D11Texture2D
для наложения части одной текстуры на другую текстуру. Я планирую сделать это, нарисовав желаемую форму в буфере трафаретов, а затем скопировав текстуру. Пожалуйста, предложите какой-нибудь хороший учебник с примерами кода для 2D-текстур, чтобы изучить использование буфера трафаретов. (или какой-либо альтернативный способ сделать это)
Комментарии:
1. Пожалуйста, кто-нибудь, дайте мне ссылку на хороший учебник по использованию
Stencil Buffer
вDirect3D
с каким-нибудь базовым примером, таким как маскировка пикселей.
Ответ №1:
Маска трафарета 101:
- Все основные графические процессоры используют 8-разрядный буфер трафаретов, и они привязаны к буферу глубины, поэтому вы должны выбрать формат буфера, который включает трафарет (в первую очередь D24S8)
- Очистите глубину и трафарет для начала каждого кадра, чтобы избежать проблем с производительностью между кадрами * (см. Примечание ниже)
- Если вы не знаете, что делаете, всегда используйте 0xFF для маски чтения и записи.
- По соображениям производительности не включайте запись глубины при выполнении тестов чтения трафарета
- По соображениям производительности, если это вообще возможно, ограничьте тесты чтения трафарета значениями ==0 и !=0 и очистите до нуля
- Если вы используете D3D9, вы можете использовать прямые ножницы в сочетании с очисткой буфера трафаретов, это немного быстрее, чем отрисовка квадрата вручную, чтобы вернуть буферу значение нуля.
- Нет способа получить доступ к информации о трафарете в шейдере, поэтому эффекты постпроцесса не могут определить состояние трафарета соседних пикселей, если маска также не находится в обычном режиме визуализации и не сэмплируется как текстура.
- Значения буфера трафаретов могут быть изменены в соответствии со следующими условиями:
- Сбой теста трафарета
- Ошибка проверки глубины
- Тесты трафарета и глубины прошли
- Какое бы условие ни было первым, оно определяет действие, которое может быть
- сохранить (оставить значение трафарета в покое)
- заменить (замените значение трафарета значением ‘stencilref’)
- увеличить (добавить 1 к текущему буферу)
- уменьшение (под 1 из буфера трафаретов)
- ноль (установите значение равным прямому нулю, полезно, когда в одном из других условий необходимо использовать текущее значение stencilref)
* Несоблюдение большинства из этих правил обычно приводит к наихудшей производительности трафарета: ваш пиксельный шейдер выполняется для каждого пикселя и не выполняет раннее отклонение для пикселей, замаскированных трафаретом. Кроме того, на старых картах Geforce это также может привести к отключению раннего отклонения глубины для всех последующих вызовов рисования, что не будет исправлено до очистки следующего кадра или буфера глубины и трафарета.
Трафаретные маски на самом деле довольно легко создавать:
- Очистите буфер трафаретов
- Включите состояние трафарета для записи трафарета (‘replace’ на stencilref 1 или ‘increment’ вместо ‘keep’)
-
Нарисуйте многоугольник. Обратите внимание, что использование ‘discard’ в шейдере предотвратит обновление трафарета, именно так вы загружаете текстуру в буфер трафарета (но только в виде двоичной маски)
-
Отключить запись по трафарету, включить проверку трафарета
- (В идеале) также отключите запись в глубину
- Нарисуйте свой эффект, требующий маскировки трафарета
Комментарии:
1. Спасибо, было бы полезно, если бы вы могли привести мне какой-нибудь пример кода того, как мы создаем некоторый базовый эффект, используя буфер трафаретов в D3D11.