이슈 개요

- Unity 2023.1.0 DX11 API

URP 데칼 렌더피처에는 뎁스 정보를 활용하는 ScreenSpace와 디퍼드 렌더링의 데칼 버퍼를 활용하는 DBuffer 2가지 모드가 있다.

Screen Space 데칼 모드에서 Rendering Layer 기능을 활성화 상태로 Depth Priming Mode와 MSAA가 활성화되어 있으면 GameView에서만 Opaque 오브젝트가 렌더링되지 않는 이슈가 있다.
뎁스 테스트를 하지 않는 Transparent 오브젝트는 렌더링이 잘된다.

 

 

데칼 레이어 구조

URP 15버전 기준 Lit 쉐이더를 보면 Forward와 DepthNormal 패스에서 Mesh RenderingLayer 정보를 출력하는 코드가 있는데 데칼 레이어는 해당 정보를 활용해 레이어 필터링하는 방식이다.
(GbufferPass에서도 출력하지만 디퍼드 렌더링 관련 내용은 생략)

 

_WRITE_RENDERING_LAYERS multi complie 분기처리 되어 있으며 쉐이더에서는 아래와 같이 RenderingLayers.hlsl파일을 Include하고 URP Core 렌더피처의 DrawObjectPass와 DepthNormalOnly에서 해당 키워드를 제어한다 .

(URP 15에서는 hlsl파일 내부에서 #pragma 구문까지 읽을 수 있는 include 문법이 가능하다)

DrawObjectsPass.cs

 

RenderingLayer는 URP12버전에서 LightLayer 기능에서 발전된 시스템으로 원래 라이트 레이어 정보와 자기 자신 메쉬 레이어 정보를 비교하여 라이트 연산을 필터링하는 기능으로 활용되었다.

대표적으로 아래처럼 쉐이더 코드는 Lighting.hlsl에서 라이트 레이어가 일치하는지 검사하는 코드가 있다.


현재 URP15에서는 _WRITE_RENDERING_LAYERS 분기가 활성화되어 있을 경우 자기 자신 메쉬 레이어를 SV_Target1로 출력하게 되어 있고 데칼 레이어와 같이 다른 메쉬의 레이어 정보 읽기가 필요한 시스템이 활성화되면 자동으로 분기가 활성화된다.

LitForwardPass.hlsl / LitPassFragment


_WRITE_RENDERING_LAYERS 분기는 여러 패스 중에 먼저 렌더링되는 패스에만 활성화되고 나머지 패스는 비활성화 상태가 유지된다. 

예를 들어 DepthNormal 패스가 프리패스로 먼저 렌더링되면 Forward패스는 해당 분기가 비활성화 된다.

 

 

 

이슈 발생 조건

일반적으로 ScreenSpace 데칼은 뎁스 정보를 사용하지만 특이한 점은 MSAA를 활성화하면 DepthNormalPrepass가 활성화되어 DepthPass대신 DepthNormal 정보를 사용하게 된다.

ScreenSpace 데칼가 데칼 레이어를 사용한다고 해서 DepthNormal 정보를 사용하는 이유를 못 찾았고 명확한 이유가 진짜 없으면 이 현상은 유니티 버그 가능성이 높을 것 같다.

좌 : MSAA Off 우 : MSAA On


문제는 데칼 레이어와 MSAA가 활성화된 상태로 Depth Priming Mode를 활성화하면 DepthNormalPrepass에 MSAA 처리가 들어가면서 렌더링되지 않는 이슈가 발생한다.

아래와 같이 동일하게 DepthNormalPrepass가 프레임 디버거에 찍히지만 이슈가 발생하는 경우 그냥 렌더링되지 않는다.

따라서 DepthNormalPrepass에 정보가 없는 상태에서 뎁스 테스트 컬링이 동작하게 되어 불투명 오브젝트가 렌더링되지 않는 결과가 나온다.

좌 : Depth Priming Mode Off 우 : Depth Priming Mode On

 


데칼 레이어 대신 DepthNormalPass를 사용하는 SSAO로 동일한 조건을 만들면 이슈가 발생하지 않고 렌더링된다.

이점을 보아선 DepthNormalPrepass에 MSAA가 적용되서 문제가 발생하는게 아니라 데칼 레이어 내부 시스템에 의한 문제로 원인이 좁혀진다.

 

 

결론

1. ScreenSpace 데칼 레이어를 활성화 상태로 MSAA를 활성화하면 DepthNormalPrepass를 강제로 사용한다. 이 부분은 유니티 버그로 추측된다.

2. 1번 상태에서 Depth Priming Mode가 활성화되면 DepthNormalPrepass에 아무것도 렌더링되지 않아 불투명 오브젝트가 렌더링되지 않는다. (GameView에서만 문제가 발생하고 SceneView는 정상 렌더링된다.)

3. 데칼이 아닌 SSAO로 동일한 조건을 만들면 이슈가 발생하지 않는다.

 

 


WRITTEN BY
CatDarkGame
Technical Artist dhwlgn12@gmail.com

,