Deferred Decal Tangent Space Normal Blend

2026. 4. 13. 23:26·Graphics

Deferred Decal Rendering

Deferred Decal은 별도의 메시를 씬 표면에 덧붙이지 않고도 투영하여 텍스처(Base Color, Normal, Metalic, Roughness 등)를 합성할 수 있는 기법이다. 총알 구멍, 핏자국, 오일 자국, 데칼성 웨더링 등 대부분의 동적/정적 데칼 효과가 이 방식으로 처리된다.

Deferred Decal은 현재 프레임의 Depth를 샘플링하여 데칼 영역 안에 있는 메쉬에 합성을 진행하므로 Depth PrePass가 필요로 하다.

 

Deferred Decal 동작 원리

Decal Bounding Box

데칼의 영향 영역을 위치 / 방향 / 크기만 있는 추상 볼륨이 아닌 Bounding Box로 정의하여 배치하고 해당 박스를 일반 메쉬처럼 렌더링을 진행한다. 다만 각 픽셀에서 Depth Buffer를 샘플링하여 월드 좌표를 복원하고, 해당 좌표가 박스 로컬 공간의 범위 안에 들어오면 데칼 텍스처를 샘플링하여 G-Buffer에 합성한 후에 Lighting Pass을 진행하도록 한다.

PSOutput main(in float4 PixelPos : SV_Position)
{
	// Reconstruct world position from depth
	float2 f2NormXY = float2(2.0, -2.0) * PixelPos.xy * g_Frame.Camera.f4ViewportSize.zw
					+ float2(-1.0, 1.0);
                    
	...
    
	// Reconstruct world position
	float4 ClipPos = float4(f2NormXY, DepthToNormalizedDeviceZ(Depth), 1.0);
	float4 WorldP4  = mul(ClipPos, g_Frame.Camera.mViewProjInv);
	float3 WorldPos = WorldP4.xyz / WorldP4.w;
    
	// Transform to decal local space
	float3 LocalPos = mul(float4(WorldPos, 1.0), g_WorldToDecal).xyz * g_DecalScale;

	if (abs(LocalPos.x) > 0.5 || abs(LocalPos.y) > 0.5 || abs(LocalPos.z) > 0.5)
		discard;
        
	...

    
}

Decal Proejction

데칼은 박스의 로컬 좌표계에서 -Z축을 Projection Direction으로 지정하여 투영하고 UV는 각 픽셀에서 Depth Buffer를 샘플링하여 복원한 월드 좌표를 데칼 공간 즉, 로컬 공간으로 변환하여 XY 평면으로 매핑한다.

 

Deferred Decal의 이점

1. 모든 데칼은 BoundBox 형식으로 렌더링이 진행되고 별도의 패스에서 모아서 그리기 때문에 Batching을 통한 GPU instancing으로 Draw call 최소화가 가능하다.

2. Deferred Decal은 Base Pass에서 GBuffer를 채운 이후 GBuffer에 Decal을 합성하기에 별도의 Lighting 처리를 진행하지 않아도 되므로 재계산이 불필요하고 기존의 Lighting Pass에서 Decal이 합성된 GBuffer를 기반으로 계산한다.

3. 메쉬의 표면에 Decal Plane을 일반 메쉬처럼 배치하는 방식은 Z-Fighting이 빈번하게 일어날 수 있지만 Deferred Decal은 표면 위에 덧그려지는 메쉬가 아니라 깊이 기반 재투영이므로 해당 현상은 일어나지 않는다.

 

Deferred Decal의 한계

1. Depth Buffer에 쓰이지 않은 표면은 데칼의 기준이 될 수 없기에 Translucent 표면에는 적용 불가하다.

2. Bone의 영향을 받는 Skin mesh의 경우 정적인 Decal Bound는 Bone의 영향을 받지 않으므로 특정 본에 attach를 하면 유사하게 보이지만 정확하지는 않을 것이다. 이를 해결하기 위해서는 Decal이 반영되야 할 Polygon들의 UV Space에서 Decal Texture를 투영시켜 DBuffer에 갱신하여 합성하는 과정이 필요로하다.

3. 투영 방향과 거의 평행한 표면에 데칼을 표시하게 되면 늘어지는 아티팩트가 발생한다. 보통 월드에 배치하는 데칼( Dirty Decal, Gravity Decal ... )의 경우 표면에만 표시되도록 매우 얇게 제작하여 해당 아티팩트를 최소화 시킨다.

4. Deferred 특성상 Decal의 영향을 받는 각 픽셀이 어떤 메쉬의 어떤 면에 속하는지를 알 수 없어 World Normal Blending의 경우 곡면이 많은 메쉬에 반영되는 데칼은 비정상적인 Normal Blending이 이루어질 가능성이 높다.

 

Decal Normal Blend 방식

보통 에디터에서 사전에 월드에 배치하는 정적 데칼의 경우 붙여야하는 월드 메쉬의 표면 영역에 맞게 데칼 영역을 축 정렬을 하여 배치를 하게되면 비정상적인 Normal Blending 아티팩트가 발생하지 않아 보이게 할 수 있다. 다만 평평한 면이라면 문제가 없겠지만 굴곡이 심한 메쉬라면 이야기가 달라진다. 이를 해결하기 위해서는 어떤 방식을 적용해야할지 고민하던 도중 정확한 데칼의 혼합을 위해서는 데칼의 BoundBox 기준이 아닌 투영 대상의 Tangent / Bitangent / Normal을 사용하여 메쉬의 World Normal 계산 흐름에 포함시키면 될 것이라는 생각으로 작업을 진행했다.

 

World Space Normal Blending

아래의 그림과 같이 Decal의 World Space Normal을 투영 대상 메쉬의 GBuffer 작업이 끝난 이후 혼합을 하게되면 비정상적인 Normal Blending 결과가 나타나게 된다.

0123
최종 화면 / Base Color / Normal / Roughness Metalic

 

Tangent Space Normal Blending

정상적인 Normal Blending을 위해 Tangent Space에서의 합성을 하려면 먼저 투영 대상 메쉬가 GBuffer를 기록하기 전에 Decal 전용의 DBuffer를 구성하여 World Space Normal이 아닌 Tangent Space Normal을 기록하여 투영 대상 메쉬가 GBuffer를 기록하는 시점에 DBuffer를 샘플링하여 해당 메쉬의 Normal Map과 혼합하여 최종 World Space Normal을 GBuffer에 기록하도록 하여야 한다.

0123
최종 화면 / Base Color / Normal / Roughness Metalic

 

Decal Normal Blend 운용 방식은?

아무래도 한가지 방법으로 통용하기에는 어려움이 있어보인다. Tangent Space에서 혼합을 하려면 Decal 영역에 포함된 객체들을 사전에 선별하여 해당 객체들의 Base Pass에서 추가로 DBuffer를 샘플링하여 혼합해야 하므로 PSO 교체에 대한 고려도 필요하다.

 

1. 월드에 사전에 배치하는 Decal의 경우에는 아트 작업자가 적절히 배치를 하면 큰 아티펙트 없이 World Space Normal Blending을 해도 큰 문제가 없을 것으로 보인다.

2. 인게임에서 동적으로 생성되는 혈흔 및 스프레이와 같은 범위가 넓은 Decal의 경우 Tangent Space Normal Blending을 진행하는 편이 나아보인다.

3. 정밀한 표현보다 성능이 중요한 경우 기존 메쉬의 World Normal과 Decal의 World Normal을 적절한 비율로 혼합하여 사용하는 것도 방법 중 하나이다.

 

Stencil Ref를 활용한 Object Type Tagging

Decal의 수신 여부를 처리하기 위해 각 객체의 타입을 Stencil Ref로 등록하여 Depth Prepass에서 Stencil 비트를 할당하도록 한다. 이후 Decal이 렌더링이 될 때 Stencil Test를 진행하여 Decal의 대상 타입과 메쉬의 타입이 같다면 그리는 방식으로 처리한다.

 

Mesh - Decal 타입이 같은 경우 Stencil Test 결과

012
최종 화면 / Decal_0 / Decal_1

 

Mesh - Decal 타입이 다른 경우 Stencil Test 결과

012
최종 화면 / Decal_0 / Decal_1

 

적용 영상

저작자표시 비영리 변경금지 (새창열림)

'Graphics' 카테고리의 다른 글

Volumetric Ray Marching  (0) 2026.04.26
Two-Pass HZB Occlusion Culling  (0) 2026.04.10
Animation Compression  (0) 2025.04.22
Animation Retargeting  (0) 2025.04.16
Texture Block Compression  (0) 2025.04.15
'Graphics' 카테고리의 다른 글
  • Volumetric Ray Marching
  • Two-Pass HZB Occlusion Culling
  • Animation Compression
  • Animation Retargeting
KyuHwang
KyuHwang
  • KyuHwang
    DirectX Engine
    KyuHwang
  • 전체
    오늘
    어제
    • 분류 전체보기 (53)
      • C++ (4)
      • Graphics (35)
      • DLL (2)
      • Shader (7)
      • Project (4)
      • ETC (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • YouTube
  • 공지사항

  • 인기 글

  • 태그

    Shader Reflection
    rigging chain
    std::is_base_of
    Order Independent Transparency
    Shader Macro
    Implicit Linking
    Directx11
    Hash Code
    animation retargeting
    dll
    Return Type Operator
    std::enable_if
    C ++
    Win API
    RunTime Compile Shader
    hlsl
    mobile format
    shader
    texture block compression
    Alpha Blending
    bc format
    Define Function
    Shader Resource 관리
    Define Macro
    Project
    DLL Interface
    nvtt
    Explicit Linking
    DirectX 2D
    animation constraint
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
KyuHwang
Deferred Decal Tangent Space Normal Blend
상단으로

티스토리툴바