본문으로 건너뛰기
CHOI HONGSU
1 min read

VAT Outline

 

 

Problem

The existing CH_Lit-based outline could not be used on VAT + GPU Indirect characters.

  1. CH_Lit has no Outline pass — there is no Pass to render an outline at all
  2. Cannot extrude along the normal without VAT position recovery — outline normal extrusion must be based on the actual skinned position; extruding without VAT sampling produces an outline in T-pose
  3. No access to GPU Indirect data — team color and frame are packed into unity_ObjectToWorld._m31/_m32, which a normal shader won't read

Approach

VAT_Lit 전용 셰이더 + OutlinePass 제작

Chosen

Pros

  • Includes only the buffers needed for VAT, no impact on CH_Lit

Cons

CH_Lit에 Outline pass 추가

Pros

  • Requires full VAT code port, risk of regressing all existing characters

Cons

Post-process 외곽선

Pros

  • Cannot distinguish team color, unrelated to GPU Indirect

Cons

Why VAT_Lit 전용 셰이더 + OutlinePass 제작: Solved the team color problem by unpacking the color from _m32, passing it through vertex color, and applying it to the outline via the OUTLINE_TINTCOLOR keyword — no dedicated parameter slot needed.

Architecture

VAT_Lit.shader
├── Outline pass (LightMode = "Outline")
│ └── OutlinePass.hlsl
│ ├── VAT position recovery (_m31 = frame)
│ ├── World-space normal extrusion
│ └── Team color (_m32 unpack → vertex color → OUTLINE_TINTCOLOR)
├── ForwardLit pass → LitForwardPass.hlsl (VAT + CUSTOMINDIRECT)
└── ShadowCaster pass → same VAT handling

 

 

URP Renderer Feature — GnomeOutline
Event: BeforeRenderingOpaques
LightMode Tag: "Outline"
Depth Test: Always ← the outline is drawn first and is then overwritten by the character

Implementation

  1. 01

    1. Order: VAT position recovery → normal extrusion

     
  2. 02

    2. Pass team color to the outline

     
  3. 03

    3. URP Renderer Feature setup

    The combination of BeforeRenderingOpaques + Depth Test: Always — writes the outline to depth first, then the character body (Opaque) renders on top and overwrites the inside, leaving only the silhouette.

Tradeoffs & Future Work

Tradeoffs

  • Kept CH_Lit separate — can be unified into CH_Lit later, but currently isolated to VAT only
  • SRP Batcher incompatible — a structural limitation because _CUSTOM_INDIRECT uses ObjectToWorld for custom purposes
  • Vertex ID baked into UV1 — texcoord1.x is used instead of SV_VertexID — must be pre-baked in the VAT baking pipeline

Architecture