개요

유니티 URP 환경에서 Universal Renderer Data에 다양한 렌더피처를 추가 할 수 있습니다.

보통 커스텀 렌더 패스로 활용하기 때문에 그래픽 퀄리티 옵션 제어가 필요한 경우가 많습니다.

이번 포스팅에서 C# 스크립트에서 Universal Renderer Data에 접근해서 원한느 RendererFeature를 활성화 & 비활성화하는 스크립트를 소개합니다.

 

 


샘플 코드 & 설명

프로젝트 환경

  • Unity 2021.3.30f1 (유니티 버전에 따라 API 변경될 수 있음)
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering;
using System.Reflection;

public class RendererFeatureControllSample : MonoBehaviour 
{
    /* 사용 샘플 코드
     * SetActiveRendererFeature<FXAARenderFeature>(toggle); 
     */
    public void SetActiveRendererFeature<T>(bool active) where T : ScriptableRendererFeature
    {
        // URP Asset의 Renderer List에서 0번 인덱스 RendererData 참조
        ScriptableRendererData rendererData = GetRendererData(0);
        if (rendererData == null) return;
   
        List<ScriptableRendererFeature> rendererFeatures = rendererData.rendererFeatures;
        if (rendererFeatures == null || rendererFeatures.Count <= 0) return;
 
        for (int i = 0; i < rendererFeatures.Count; i++)
        {
            ScriptableRendererFeature rendererFeature = rendererFeatures[i];
            if (!rendererFeature) continue;
            if (rendererFeature is T) rendererFeature.SetActive(active);
        }
        #if UNITY_EDITOR
        rendererData.SetDirty();
        #endif
    }


    public ScriptableRendererData GetRendererData(int rendererIndex = 0)
    {
        // 현재 Quality 옵션에 세팅된 URP Asset 참조
        UniversalRenderPipelineAsset pipelineAsset = GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset;
        if (!pipelineAsset) return null;
  
        // URP Renderer List 리플렉션 참조 (Internal 변수라서 그냥 참조 불가능)
        FieldInfo propertyInfo = pipelineAsset.GetType().GetField("m_RendererDataList", BindingFlags.Instance | BindingFlags.NonPublic);
        ScriptableRendererData[] rendererDatas = (ScriptableRendererData[])propertyInfo.GetValue(pipelineAsset);
        if (rendererDatas == null || rendererDatas.Length <= 0) return null;
        if (rendererIndex < 0 || rendererDatas.Length <= rendererIndex) return null;

        return rendererDatas[rendererIndex];
    }
}

 

 

현재 Quality 옵션에 세팅된 URP Asset 참조

UniversalRenderPipelineAsset pipelineAsset = GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset;
if (!pipelineAsset) return null;

위 코드는 현재 퀄리티 상태의 Universal Render Pipeline Asset을 참조합니다.

퀄리티 옵션이 변경되면 해당 에셋을 참조하게 됩니다.

 

 

URP RendererData List 참조

FieldInfo propertyInfo = pipelineAsset.GetType().GetField("m_RendererDataList", BindingFlags.Instance | BindingFlags.NonPublic);
ScriptableRendererData[] rendererDatas = (ScriptableRendererData[])propertyInfo.GetValue(pipelineAsset);

참조한 Universal Render Pipeline Asset 내부의 Renderer List를 참조하는 코드입니다.

URP 내장 코드에서 Internal로 선언되어 직접 참조는 불가능하여 리플렉션 참조를 해야합니다.

 

다음, RendererList에서 원하는 인덱스를 참조합니다.

  • rendererDatas[rendererIndex];

 

Universal RendererData 내부 RendererFeatures 참조

List<ScriptableRendererFeature> rendererFeatures = rendererData.rendererFeatures;
if (rendererFeatures == null || rendererFeatures.Count <= 0) return;

위 코드를 통해 URP RendererData 내부의 RendererFeature 리스트를 참조할 수 있습니다.

 

샘플 코드에서는 제네릭 문법을 활용해 찾는 RendererFeature 클래스를 선택 할 수 있게 만들 었습니다.

원하는 RendererFeature를 참조하면 SetActive 함수로 활성화 & 비활성화 가능합니다.

 

 

 

 

참고자료


WRITTEN BY
CatDarkGame
Technical Artist dhwlgn12@gmail.com

,