[Unity] ScriptableRendererFeature 작성하기
공부용으로 작성되는 페이지입니다. 틀린 부분이나 환경에 따라 오류가 발생할 수 있습니다.
ScriptableRendererFeature?
쉐이더를 작성하면서 ScriptableRendereFeature 부분이 길어져서 따로 작성하게 되었다.
ScriptableRendererFeature는 파이프라인을 커스터마이징할 수 있게 해주는 기능이다.
객체에 단순히 Material을 적용시키는게 아니라, 이미 만들어진 맵에 후처리로 shader를 적용해야할 경우 파이프라인에 추가해서 처리하는 것.
이미 만들어진 씬에 필터 같은 shader를 적용하고 싶을 때 유용하게 쓸 수 있는 기능이다.

작성 과정
세팅된 파이프라인(이 경우 URP)에 Renderer Features를 추가하기 위해서는 ScriptableRendererFeature를 작성해줘야한ㄷ.ㅏ
오늘 쓰게 될 예시는 내가 추후 올릴 Depth Map study에서 작성한 렌더피쳐이다.
1. Rendering 관련 Using 지시문을 추가 및 ScriptableRenderFeature를 상속
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public class DepthMapFeature : ScriptableRenderFeature
2. 필수 메소드 작성 : Create() 와 AddRenderPasses()
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public class DepthMapFeature : ScriptableRenderPass
{
public override void Create()
{ }
public override void AddRenderPasses(ScriptableRenderer renderer,
ref RenderingData renderingData)
{ }
}
- Create: 렌더러 기능 로드, 활성화, 프로퍼티 변경 시 처리하는 역할
- AddRenderPasses: 스크립터블 렌더러에 ScriptableRenderPass 인스턴스를 삽입하는 역할
3. 스크립터블 렌더 패스 생성
class DepthMapPass : ScriptableRenderPass
{
//Exctue() : custom Method
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
throw new System.NotImplementedException();
Debug.Log(message: "The Execute() method runs.");
}
private DepthMapPass _depthMapPass;
public override void Create()
{
_depthMapPass = new DepthMapPass();
}
public override void AddRenderPasses(ScriptableRenderer renderer,ref RenderingData renderingData)
{
renderer.EnqueuePass(_depthMapPass);
}
3. Excute() 추가 작성 : 커스텀 렌더링 로직 구현
Excute메소드의 로직은 다음과 같다
1. 새 커맨드 버퍼를 가져와서 이름 할당 : 내 작업에 맞게 DepthMapPass로 지정함
2. 렌더링 커맨드 추가 : 원하는 렌더링 작업을 커맨드 버퍼에 추가
3. 커맨드 버퍼 실행 : 커맨드 버퍼의 명령을 GPU로 전달
4. 버퍼 해제 : Pool을 통해 재사용하는 방식이므로 마지막에 반드시 해제해줘야함. 즉, 메모리 누수 방지.
private Material _material;
private Mesh _mesh;
public DepthMapPass(Material material, Mesh mesh)
{
_material = material;
_mesh = mesh;
}
//Exctue() : custom Method
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
CommandBuffer cmd = CommandBufferPool.Get(name: "DepthMapPass");
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
Debug.Log(message: "The Execute() method runs.");
}
렌더러에 Renderer Feature 추가하기
렌더러에 렌더러 기능을 추가하는 방법 | Universal RP | 14.0.9
렌더러에 렌더러 기능을 추가하는 방법 | Universal RP | 14.0.9
렌더러에 렌더러 기능을 추가하는 방법 렌더러에 렌더러 기능을 추가하려면 다음 단계를 따르십시오. Project 창에서 렌더러를 선택합니다. 인스펙터 창에 Renderer 프로퍼티가 표시됩니다. 인스펙
docs.unity3d.com
[Project] -> [Setting] -> [Universal Renderer]
위 과정에서 문제없이 따라왔다면 Add Renderer Feature 버튼을 누르면 본인이 작성한 Renderer Feature를 추가해줄 수 있다.


체크해둬야하는 설정들
만약 위의 과정을 진행했음에도 제대로 되지 않는다면 다른 설정들이 제대로 세팅되어있는지 확인해야한다.
- Editor > Project Settings > Quality에 설정된 URP Asset 체크 여부
- 카메라 렌더러 세팅 여부
- 렌더 패스를 그리는 순서를 확인 : Frame Debugger (Window > Analysis > Frame Debugger)
나의 경우 Map overlay - Depth로 따로 설정해서 결과물을 확인할 수 있었다.
참고자료
예제 문서의 내용을 그대로 가져온것이나 다름없으므로, 작성 시 어려움이 있으면 참고하는걸 추천
Example of a complete Scriptable Renderer Feature | Universal RP | 12.1.16