avatarcommunity
Gamedev4 недели назад

Pixel Depth Offset в Unreal Engine

Смещение глубины пикселей может потребоваться, когда речь идёт о создании процедурных поверхностей без смещения/добавления вершин. То есть, условные тесселяция или displacement mapping не требуют смещения глубины пикселей, а вот параллакс маппинг или маршировка лучей требуют, так как это техники для пиксельных шейдеров. Без коррекции PDO сцена не будет в курсе рельефа, который вы насочиняли для каждого пикселя, поэтому свет и тени лягут неправильно.

image

На PDO подаётся положительное скалярное значение. Если буквально, это расстояние, на которое нужно сместить вглубь сцены пиксель по вектору, выпущенному из камеры. Звучит непонятно - смотрим на картинку:

Да, пэинт, вопросы
Да, пэинт, вопросы

С теорией хватит, теперь к проблемам.

Если вы используете большие значения PDO, рискуете столкнуться с чёрной рябью на поверхности. Лучшее решение, которое я находил на форумах: "просто не используйте большие значения, лмао". Но есть и нормальное решение - MakePrecise.

Насколько я понял, это прослойка для HLSL квалификатора Precise, который запрещает компилятору некоторые оптимизации. Используется просто: между вашими расчётами и входом PDO создаётся кастомная нода. Подаёте на вход ноды некоторый результат вычислений X, а на выходе выдаёте "return MakePrecise(X);". И рябь исчезает. Но все расчёты, необходимые для X могут подрасти на десяток-другой инструкций.

При смещении глубины пикселя исходная поверхность начинает отбрасывать тени на себя. Вопрос никак вообще не решается авторами движка, а на форумах какие-то важные чуваки в пассивно-агрессивной манере защищают эту проблему. Так что здесь на выбор 2 костыля: прокси-тени и колдовство с нодой Shadow Pass Switch

С прокси тенями всё просто: выключаем тени у самого объекта, подставляем внутрь  приблизительно похожий по форме лоу поли объект, рендерим от него только тень, готово.

Shadow Pass Switch довольно интересный инструмент. С его помощью можно смещать тени, а можно вообще нарисовать что-то другой формы.

image

Для этого между вычислениями и входами WPO/Opacity Mask размещаем SPS. На выход Default посылаются вычисления для самого объекта, на выход Shadow, соответственно, для теней. Если вам нужно изменить только тень, на Default можно просто послать 0/1.

Ссылка с наглядными примерами.

23
23комментария
Ваш опыт на этом сайте будет улучшен за счет использования cookies. Принимая все cookies, вы соглашаетесь с нашим использованием cookies для предоставления и поддержания наших услуг и сайта.