Pixel Depth Offset в Unreal Engine

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

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

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

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

Артефакты

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

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

Самозатенение

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

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

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

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

Начать дискуссию