ShovelingLife
A Game Programmer
ShovelingLife
전체 방문자
오늘
어제
  • 분류 전체보기 (1072) N
    • 그래픽스 (57)
      • 공통 (19)
      • 수학 물리 (22)
      • OpenGL & Vulkan (1)
      • DirectX (14)
    • 게임엔진 (183)
      • Unreal (69)
      • Unity (103)
      • Cocos2D-X (3)
      • 개인 플젝 (8)
    • 코딩테스트 (221)
      • 공통 (7)
      • 프로그래머스 (22)
      • 백준 (162)
      • LeetCode (19)
      • HackerRank (2)
      • 코딩테스트 알고리즘 (8)
    • CS (235)
      • 공통 (21)
      • 네트워크 (44)
      • OS & 하드웨어 (55)
      • 자료구조 & 알고리즘 (98)
      • 디자인패턴 (6)
      • UML (4)
      • 데이터베이스 (7)
    • 프로그래밍 언어 (348) N
      • C++ (167)
      • C# (90) N
      • Java (9)
      • Python (33)
      • SQL (30)
      • JavaScript (8)
      • React (7)
    • 그 외 (9)
      • Math (5)
      • 일상 (5)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • Source Code 좌측 상단에 복사 버튼 추가 완료
  • 언리얼 엔진 C++ 빌드시간 단축 꿀팁
  • 게임 업계 코딩테스트 관련
  • 1인칭 시점으로 써내려가는 글들

인기 글

태그

  • string
  • 백준
  • c#
  • 언리얼
  • C++
  • 그래픽스
  • 함수
  • 파이썬
  • 오블완
  • Unity
  • 배열
  • 포인터
  • C
  • 유니티
  • SQL
  • 프로그래머스
  • 문자열
  • 티스토리챌린지
  • 클래스
  • 알고리즘

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
ShovelingLife

A Game Programmer

[Unity] 셰이더 프로퍼티 값 (예,색상 변경하기)
게임엔진/Unity

[Unity] 셰이더 프로퍼티 값 (예,색상 변경하기)

2023. 5. 19. 15:45

매터리얼 프로퍼티 값 변경하기

MeshRenderer.material.Set~ 메소드를 통해

스크립트에서 마테리얼 특정 프로퍼티의 값을 실시간으로 변경할 수 있다.

하지만 이렇게 .material에 접근하여 프로퍼티를 수정하면

이런식으로 마테리얼이 개별 인스턴스로 복제되어, 배칭이 깨지게 된다.
(.material에 접근하기만 해도 바로 개별 인스턴스가 생성된다.)


이를 방지할 수 있는 것이 Material Property Block, GPU Instancing이다.
Material Property Block을 이용하여 프로퍼티 값을 수정할 경우,
마테리얼의 복사본을 생성하지 않고 값을 수정할 수 있다.
그리고 GPU Instancing을 적용하면 동일 마테리얼에 대해
드로우콜을 통합하여 동적 배칭을 적용할 수 있다.

1. 프로퍼티 값을 그냥 수정하는 경우

private MeshRenderer[] renderers;

private void Start()
{
    renderers = GetComponentsInChildren<MeshRenderer>();
    SetRandomProperty();
}

private void SetRandomProperty()
{
    foreach (var r in renderers)
    {
        r.material.SetColor("_Color", UnityEngine.Random.ColorHSV());
        r.material.SetFloat("_Metallic", UnityEngine.Random.Range(0f, 1f));
    }
}

1. GPU Instancing 미적용

Batches:172 배칭이 전혀 되지 않는다

2. GPU Instancing 적용

Batches: 96 일부 배칭된다

2. Material Property Block을 통해 수정하는 경우

MaterialPropertyBlock 객체를 생성하고,
MaterialPropertyBlock.Set~ 메소드를 통해 프로퍼티 값을 수정한 뒤
MeshRenderer.SetPropertyBlock() 메소드를 통해 수정된 값을 적용한다.
마테리얼마다 MaterialPropertyBlock 객체를 따로 생성해도 되고, 객체를 재사용해도 된다.

private MeshRenderer[] renderers;
private MaterialPropertyBlock mpb;

private void Start()
{
    renderers = GetComponentsInChildren<MeshRenderer>();
    mpb = new MaterialPropertyBlock();
    SetRandomPropertyWithMPB();
}

private void SetRandomPropertyWithMPB()
{
    foreach (var r in renderers)
    {
        mpb.SetColor("_Color", UnityEngine.Random.ColorHSV());
        mpb.SetFloat("_Metallic", UnityEngine.Random.Range(0f, 1f));
        r.SetPropertyBlock(mpb);
    }
}

1. GPU Instancing 미적용

Batches 172:&nbsp;Material Property Block을 통해 프로퍼티를 수정해도GPU Instancing을 적용하지 않으면 배칭이 되지 않는다.

2. GPU Instancing 적용

Batches : 52,&nbsp;프로퍼티 블록을 쓰지 않는 것보다는 더 많이 배칭된다.

3. GPU Instancing + Instancing Buffer

스크립트를 통해 수정할 프로퍼티들을 쉐이더에서 Instancing Buffer 내에 선언해준다.

 

기존 쉐이더 코드 (Surface Shader 예제)

fixed4 _Color;
half _Metallic;

void surf (Input IN, inout SurfaceOutputStandard o)
{
    fixed4 c = _Color;
    o.Metallic = _Metallic;

    o.Albedo = c.rgb;
}

변경된 쉐이더 코드

UNITY_INSTANCING_BUFFER_START(Props)

    UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color)
    UNITY_DEFINE_INSTANCED_PROP(half, _Metallic)

UNITY_INSTANCING_BUFFER_END(Props)

void surf (Input IN, inout SurfaceOutputStandard o)
{
    fixed4 c   = UNITY_ACCESS_INSTANCED_PROP(Props, _Color);
    o.Metallic = UNITY_ACCESS_INSTANCED_PROP(Props, _Metallic);

    o.Albedo = c.rgb;
}

Batches : 8, 이제 완벽히 배칭되는 것을 확인할 수 있다.

출처 : https://rito15.github.io/posts/unity-material-property-block/

저작자표시 (새창열림)

'게임엔진 > Unity' 카테고리의 다른 글

[Unity] 오브젝트의 활성화 상태 확인  (0) 2023.06.01
[Unity] RectTransform 내 피벗 Top과 Bottom 설정  (0) 2023.05.31
[Unity] GUI, GUIStyle 및 GUILayout  (0) 2023.05.11
[Unity] JSON 파일 저장 및 읽기  (0) 2023.05.11
[Unity] 이동, 회전, 크기변경 정리  (2) 2023.05.05
    '게임엔진/Unity' 카테고리의 다른 글
    • [Unity] 오브젝트의 활성화 상태 확인
    • [Unity] RectTransform 내 피벗 Top과 Bottom 설정
    • [Unity] GUI, GUIStyle 및 GUILayout
    • [Unity] JSON 파일 저장 및 읽기
    ShovelingLife
    ShovelingLife
    Main skill stack => Unity C# / Unreal C++ Studying Front / BackEnd, Java Python

    티스토리툴바