Unity/Rendering&Shader

[RENDERING] Rendering Layers

김성인 2023. 10. 24. 23:26

[RENDERING] Rendering Layers

정보 전달을 위한 글이 아닌, 개인적으로 잊지 않기 위해서 기록하였습니다.


  1.  글의 기록 목적
  2.  테스트 환경
  3.  사용 방법
  4.  렌더링 관련 간단한 테스트 
  5.  성능 관련

글의 기록 목적

 

 게임을 개발하다 보면, 특정 오브젝트에 특정 광원만 영향을 주길 원할 때가 생기게 된다. 이 경우 흔하게 오브제의 Layer, 광원의 Rendering/Culling Mask 이용하여 선택적으로 라이팅을 적용하면 쉽게 해결할 수 있다.

 그렇지만 이렇게 개발을 진행하게 되면 문제점이 생길 수 있다. 특히나 대규모 프로젝트나 MMO, 연출 등 아주 많은 기능들이 붙는 게임일수록 문제점이 생길 수 있는데, Layer의 경우, Tag와 함께 오브젝트의 타입이나 상태 등을 나타내기 위하여 수많은 기능들에 사용되고 있다는 것이다. 거기다 Layer의 최대 개수 32개로 정해져 있다. 32개 중 앞쪽 몇 개는 Unity에서 이미 지정하여 수정할 수 없는 Layer 또한 존재한다.

 

 위의 문제점을 해결하기 위하여 오브젝트의 Layer가 아닌, Rendering Layers를 Unity에서 제공한다. 사실 이 기능은 다른 상용 엔진에서도 많이 사용되고 있다.

오브젝트의 Tag, Layer

 

Rendering Layers는 URP의 Rendering 기능 중 하나이다.


테스트 환경

 

  - UNITY 2022.3.6

  - URP 14.0.8

 렌더링에 최대한 영향을 주지 않도록, 신규 URP 프로젝트를 생성, Unity에서 제공하는 URP-Balanced-Renderer를 기반으로 몇 가지 옵션만 활성화하여 테스트함.

  - Depth, Opaque Texture : OFF

  - SRP Batcher : ON

  - Rendering Path : Forward

 -  Renderer Features 모두 끔


사용방법

 

1. URP Asset의 Lighting/Use Rendering Layers를 활성화한다.

2. UniversalRenderPipelineGlobalSettings에 Rendering Layers에 사용할 Layer를 확인한다.

  > 이 옵션에서 Layer 이름을 지정하고, Layer 수를 변경할 수 있다.

3-1. 위의 1번에서 Use Rendering Layers를 활성화하면, 광원의 General 부분에 Rendering Layers 옵션이 생긴다.

  > 기본적으로 Use Rendering Layers가 비활성화된 상태로 프로젝트가 생성되며, 비활성화되어 있으면 Rendering Layers 옵션이 보이지 않는다.

3-2. 원하는 Layer를 선택한다.

4. 오브젝트의 Additional Settings 부분에 Rendering Layer Mask가 생기고, 원하는 Layer를 선택한다.


렌더링 관련 간단한 테스트 

 

프로젝트에 적용하기 전 Unity 매뉴얼을 확인하고, 간단하게 사용방법, 테스트를 진행해 보았다.


 Sphere 2개, Cube 2개, 바닥에 Plane 하나로 테스트를 진행한다.

 시작은 하나의 PBR Shader, 하나의 Material로 시작하고, 도중에 렌더링 이벤트가 어떻게 변화하는지 알아보기 위하여, 두 개의 Shader, Material로 테스트를 진행한다.

 

 

 - 광원(Directional Light)을 2개 설치 후, 각 광원의 Rendering Layers를 다르게 설정한다.
  > 확인이 쉽도록 각 광원은 붉은색, 파란색으로 색을 다르게 설정하였음.
  > 모든 오브젝트는 모든 광원에 영향을 받도록 하였음.

 렌더링 순서를 확인하면 Main Light Shadow 부분에서 한 번의 드로 콜만 존재한다. 이것은 프로젝트를 세팅하며 SRP Batcher를 활성화해두었기 때문에 한 번의 드로 콜로 처리되고 있음. 이 부분을 보면 SRP Batcher가 우수한 배칭 기술임을 알 수 있다(Unity도 많이 발전하였다).

 

 - 위의 상태에서 오브젝트들의 Layer Mask나 광원의 Rendering Layer를 Nothing으로 처리하면, 하단의 이미지같이 나오게 된다.

 분명 라이트가 존재하지 않는데, 하단의 이미지와 같이 나오는 이유는 Rendering 쪽의 Envrionment 쪽 데이터의 영향을 받기 때문이다.

 

 - 이제 오브젝트에도 layer mask를 원하는 대로 적용하였다. 그럼 하단의 이미지와 같이 위에서 설정한 광원이 의도한 대로 특정 오브젝트에만 영향을 주는 것을 확인할 수 있다.
 아직까지 Shadow, Object는 한 번에 그리고 있다.

 

 - 다른 셰이더와 메테리얼을 만들어 오브젝트에 다르게 적용하여 보았다.
  > 셰이더 또한 다르게 적용한 이유는 SRP Batcher 때문에, 하나의 셰이더에 다른 메테리얼을 이용하면 드로아 콜이 광원의 수와 상관없이 한 번에 계산될 수 있어, 정확한 결과를 알 수 없기 때문이다.

  > 이 경우 그림자 쪽에서 두 번, 오브젝트에서 세 번의 드로아 콜이 발생하였다.
  > 그림자의 경우 각 메테리얼, 셰이더 별로 한 번씩 드로아 콜이 나왔다.

  > 오브젝트의 경우, 각 셰이더별, 메테리얼별로 한 번씩 그린 후, 마지막으로 순서 때문에 바닥에 배치되어 있는 Plane 이렇게 세 번의 드로아 콜이 나왔다.

 

 - 그림자의 경우, 아무런 설정을 하지 않을 경우, 하단의 이미지와 같이 Main Light(주광)에만 그림자가 생긴다.

 

 우선 URP의 Forward Rendering Path의 경우 기본적으로 주광 하나에서만 그림자가 생성되기 이와 같은 현상이 일어나는데, 원하는 오브젝트에서도 그림자가 생기게 하기 위해서는 광원의 Shadows/Custom Shadow Layers를 활성화시킨 후, Layer를 선택해 주면 된다.

 

- 최종 결과물


성능 관련하여서는 정확하게 테스트해 보지 않았지만, 다행스럽게도 Unity 쪽에서 매뉴얼로 제공해 주고 있다. 

Performance

This section contains information related to the impact of Rendering Layers on performance.

  • Keep the Rendering Layer count as small as possible. Avoid creating Rendering Layers that you don't use in the project.
  • When using Rendering Layers for decals, increasing the layer count increases the required memory bandwidth and decreases the performance.
  • When using Rendering Layers only for Lights in the Forward Rendering Path, the performance impact is insignificant.
  • Performance impact grows more significantly when the Rendering Layer count exceeds a multiple of 8. For example: increasing the layer count from 8 to 9 layers has a bigger relative impact than increasing the layer count from 9 to 10 layers.

 

번역하면...

 

성능

  • 렌더링 레이어 수를 가능한 작게 유지하십시오. 프로젝트에서 사용하지 않는 렌더링 레이어를 생성하는 것을 피하십시오.
  • 데칼용으로 렌더링 레이어를 사용할 때, 레이어 수를 늘리면 필요한 메모리 대역폭이 늘어나고 성능이 감소합니다.
  • Forward 렌더링 패스에서 렌더링 레이어를 조명에만 사용하는 경우, 성능 영향은 미미합니다.
  • 렌더링 레이어 수가 8의 배수를 초과하는 경우 성능 영향이 더 크게 나타납니다. 예를 들어, 레이어 수를 8에서 9로 늘리는 것은 레이어 수를 9에서 10으로 늘리는 것보다 상대적인 영향이 큽니다.

메뉴얼을 해석 하면 이렇다.

  • 렌더링의 레이어 수를 가능한 작게 유지하는 것은 정확한 이유를 알 수 없다.
      하지만 유추는 할 수 있다.

     1. 렌더링 레이어 수가 적을수록 GPU가 처리해야 할 작업이 줄어든다.  동시에 SRP 배칭 처리가 없다면, 각 레이어마다 렌더링 패스를 처리해야 하기 때문이다.

    2. 렌더링 레이어는 GPU의 메모리를 사용한다. 당연한 거지만 메모리는 적게 사용할수록 유리하다. 특히 모바일 게임의 경우는 더욱더...

    3. 렌더링 레이어 수가 적을 수록 내가 컨트롤하기 쉬워진다.  이 말은 즉, 개발을 더욱 쉽게 할 수 있고, 유지 보수도 쉬워진다는 말이다.

  • 데칼용 렌더링 레이어 관련해서는 Unity 매뉴얼을 보면 렌더링 레이어에 Decal을 싣기 때문이다.  그렇다면 위와 같은 결론이 된다.

  • 렌더링 레이어 수가 8의 배수를 초과하는 경우 성능에 악영향을 주는 이유는 GPU의 워크 그룹 단위 때문인 것 같다.
    GPU는 CPU와 다르게 병렬 처리 시스템이다.  그리고 워크 그룹은 이 병렬 처리되는 작업의 단위를 말하며, 일반적으로 8, 16, 32, 64, 128식으로 커지기 때문에 만약 워크 그룹이 8개라면, 분명 8개와 9개는 GPU의 코어 하나를 이용하느냐, 2개를 이용하느냐 차이이기 때문일 것이다.

     

유니티 메뉴얼 링크

https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@16.0/manual/features/rendering-layers.html