매터리얼 프로퍼티 값 변경하기
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 미적용
2. GPU Instancing 적용
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 미적용
2. GPU Instancing 적용
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;
}
출처 : 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 |