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.
Ссылка с наглядными примерами: