Clothing culler для Unity на основе Stencil Buffer

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

Именно со вторым возникла проблема. Для увеличения количества комбинаций одежды я решил разделить одежду и персонажа на два отдельных объекта, из-за чего во время воспроизведения анимаций кожа персонажа просвечивала сквозь одежду.

Clothing culler для Unity на основе Stencil Buffer

Сначала я решил бороться с проблемой с помощью Stencil Buffer у материалов, и это в принципе работало, но имело большой изъян.

Clothing culler для Unity на основе Stencil Buffer

Теперь одежда просвечивала сквозь конечности, что было еще хуже. Поэтому я забросил этот подход.

Но недавно, перейдя на URP, решил снова попробовать покопаться. В URP есть такая прекрасная вещь, как Renderer Features, которая позволяет добавлять дополнительные проходы рендера.

Первоначально я отключил рендер для персонажа и одежды в настройках URP Render Data

Clothing culler для Unity на основе Stencil Buffer

(достаточно убрать галочки напротив соответствующих слоев, у меня Body и Clothes), чтобы отрисовывать их с помощью Renderer Features. Перейдем к базе: чтобы отрендерить объект, нужно добавить Render Objects и указать слой, на котором находится объект. Основная отбраковка будет проходить так:

  1. Сначала рендерим одежду. Одежда заполнит Stencil Buffer.
  2. Затем рендерим тело. Тело проверит Stencil Buffer на заполненность, и в местах, где он заполнен (т.е. где есть одежда), тело показываться не будет.
Реализация
Реализация

Правда, при таком подходе снова возникнет проблема с конечностями, ведь от простого использования Stencil Buffer прямо сейчас это никак не отличается. Теперь нужно как-то отделить именно просвечивание кожи сквозь одежду от стандартного случая, когда одежда находится за конечностями.

Здесь я использовал другую возможность Render Objects , а именно перезапись Material. Предположение такое: чтобы отделить конечности от просвечиваний, достаточно проверить, находится ли одежда за Backface персонажа. Если да, то показывать одежду не нужно, так как она находится либо за персонажем, либо за его конечностями. Для этого я написал небольшой шейдер:

Shader "Hidden/BackOnly" { SubShader { Tags { "RenderType"="Opaque" } Pass { Cull Front ZWrite On ZTest LEqual ColorMask 0 HLSLPROGRAM #pragma vertex vert #pragma fragment frag #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" struct Attributes { float4 position : POSITION; }; struct Varyings { float4 position : SV_POSITION; }; Varyings vert(Attributes v) { Varyings o; o.position = TransformObjectToHClip(v.position.xyz); return o; } half4 frag(Varyings i) : SV_Target { return 0; } ENDHLSL } } }

Итого, схема Renderer Feature выглядит так (если будете повторять учтите - порядок важен):

Clothing culler для Unity на основе Stencil Buffer

А теперь: до и после

Clothing culler для Unity на основе Stencil Buffer
3
Начать дискуссию