유니티 메테리얼 복사본 없이 수정하기 #MaterialPropertyBlock
메티리얼을 직접 수정하면 각 객체에 대해 메모리에 해당 머티리얼의 새로운 인스턴스를 생성하게 됩니다. MaterialPropertyBlock를 사용하여 복사본이 생성되는 문제를 해결할 수 있습니다. MaterialPro
wlsdn629.tistory.com
유니티 OVR 메테리얼 수정을 돕는 MaterialPropertyBlockEditor
OVR SDK 프로젝트를 스터디 하다보면 MaterialPropertyBlockEditor 스크립트를 종종 발견하곤 했습니다. MaterialPropertyBlockEditor 스크립트가 무엇인지 이번 포스팅에서 살펴보고자 합니다😁. MaterialPropertyBloc
wlsdn629.tistory.com
예전에 MaterialPropertyBlock에 대해 간단한 설명과 VR(Meta SDK)에서 사용할 수 있는 방법에 대해서 간단하게 설명드렸습니다.
이번 시간에는 MaterialPropertyBlock에 대해서 좀 더 자세히 알아보고자 합니다!
들어가며
유니티로 개발하다 보면 오브젝트의 색상을 런타임에서 개별적으로 바꾸고 싶을 때가 자주 있습니다.
예를 들어 캐릭터 색상, 하이라이트 효과, 체력에 따라 색상 변화 등...
이럴 때 단순히 아래와 같이 코드를 쓰는 경우가 많습니다.
renderer.material.color = Color.red;
하지만 이게 성능에 매우 치명적인 문제를 일으킨다는 걸 알고 계셨나요?
그렇기에 MaterialPropertyBlock(MPB) 을 사용하는 진짜 이유를 알아보고,
Material 인스턴싱과 GPU Instancing이 깨지는 원인, 그리고 올바른 사용법까지 깔끔하게 알아보겠습니다!
MPB를 쓰는 진짜 이유는?
많은 개발자들이 메테리얼 인스턴싱이 깨지지 않게 하려고 MPB를 쓴다고 말합니다.
맞는 말이긴 하지만, 그 이유는 결국 GPU Instancing을 유지하기 위함입니다.
Material을 직접 수정하면 내부적으로 Material 인스턴스가 복제됩니다.
그리고 Material 인스턴스가 다르면 그 오브젝트들은 GPU Instancing에서 제외되게 됩니다.
Material 인스턴스는 Renderer의 .material 프로퍼티에 처음 접근하는 순간 생성됩니다.
접근할 때마다 새로 생기는 게 아니라, Renderer당 하나씩만 복제됩니다.
// 단 한 번만 인스턴스 생성됨
renderer.material.color = Color.red;
// 이후에 이 material을 계속 변경해도 더 이상 생성되진 않음
renderer.material.SetFloat("_Glossiness", 0.5f);
MaterialPropertyBlock(MPB)은
Material 자체를 바꾸지 않고, GPU에 넘기는 '추가 데이터'만 다르게 설정하는 방식이기 때문에
GPU Instancing이 깨지지 않습니다!!!!
색상 값은 Material이 아니라 Renderer에 붙은 MPB를 통해 GPU로 전달되며,
GPU는 이 값을 인스턴싱용 per-instance 데이터로 인식하고,
Draw Call은 하나로 묶고, 각 인스턴스별로 color 값만 다르게 전달됩니다.
휴 어렵네요!
그니깐, 유니티에 자체적으로 최적화를 신경써서 - MPB를 셰이더에 바인딩되는 추가 인스턴스 데이터로 사용할 수 있게 해준거라고 생각하시면 됩니다!
실제로 GPU Instancing은 per-instance uniforms 혹은 Structured Buffer 같은 구조로,
오브젝트마다 다른 데이터를 GPU로 넘길 수 있게 되어 있다고 하네욤.
올바른 MPB 사용방법 vs 잘못된 방법
// ✔️ 올바른 MPB 사용 예시
MaterialPropertyBlock mpb = new MaterialPropertyBlock();
foreach (var r in renderers)
{
r.GetPropertyBlock(mpb);
mpb.SetColor("_BaseColor", Color.red);
r.SetPropertyBlock(mpb);
}
// 🚫 매번 새 MPB 생성 → Instancing 깨짐
foreach (var r in renderers)
{
var mpb = new MaterialPropertyBlock(); // ← 이게 문제!
r.GetPropertyBlock(mpb);
mpb.SetColor("_BaseColor", Color.red);
r.SetPropertyBlock(mpb);
}
다음 시간에는 MPB를 쉽게 사용할 수 있도록 제가 만든 유틸리티 코드를 공유드리겠습니다 ㅎㅎ니티 메테리얼 복사본 없이 수정하기 #MaterialPropertyBlock
메티리얼을 직접 수정하면 각 객체에 대해 메모리에 해당 머티리얼의 새로운 인스턴스를 생성하게 됩니다. MaterialPropertyBlock를 사용하여 복사본이 생성되는 문제를 해결할 수 있습니다. MaterialPro
wlsdn629.tistory.com
유니티 OVR 메테리얼 수정을 돕는 MaterialPropertyBlockEditor
OVR SDK 프로젝트를 스터디 하다보면 MaterialPropertyBlockEditor 스크립트를 종종 발견하곤 했습니다. MaterialPropertyBlockEditor 스크립트가 무엇인지 이번 포스팅에서 살펴보고자 합니다😁. MaterialPropertyBloc
wlsdn629.tistory.com
예전에 MaterialPropertyBlock에 대해 간단한 설명과 VR(Meta SDK)에서 사용할 수 있는 방법에 대해서 간단하게 설명드렸습니다.
이번 시간에는 MaterialPropertyBlock에 대해서 좀 더 자세히 알아보고자 합니다!
들어가며
유니티로 개발하다 보면 오브젝트의 색상을 런타임에서 개별적으로 바꾸고 싶을 때가 자주 있습니다.
예를 들어 캐릭터 색상, 하이라이트 효과, 체력에 따라 색상 변화 등...
이럴 때 단순히 아래와 같이 코드를 쓰는 경우가 많습니다.
renderer.material.color = Color.red;
하지만 이게 성능에 매우 치명적인 문제를 일으킨다는 걸 알고 계셨나요?
그렇기에 MaterialPropertyBlock(MPB) 을 사용하는 진짜 이유를 알아보고,
Material 인스턴싱과 GPU Instancing이 깨지는 원인, 그리고 올바른 사용법까지 깔끔하게 알아보겠습니다!
MPB를 쓰는 진짜 이유는?
많은 개발자들이 메테리얼 인스턴싱이 깨지지 않게 하려고 MPB를 쓴다고 말합니다.
맞는 말이긴 하지만, 그 이유는 결국 GPU Instancing을 유지하기 위함입니다.
Material을 직접 수정하면 내부적으로 Material 인스턴스가 복제됩니다.
그리고 Material 인스턴스가 다르면 그 오브젝트들은 GPU Instancing에서 제외되게 됩니다.
Material 인스턴스는 Renderer의 .material 프로퍼티에 처음 접근하는 순간 생성됩니다.
접근할 때마다 새로 생기는 게 아니라, Renderer당 하나씩만 복제됩니다.
// 단 한 번만 인스턴스 생성됨
renderer.material.color = Color.red;
// 이후에 이 material을 계속 변경해도 더 이상 생성되진 않음
renderer.material.SetFloat("_Glossiness", 0.5f);
MaterialPropertyBlock(MPB)은
Material 자체를 바꾸지 않고, GPU에 넘기는 '추가 데이터'만 다르게 설정하는 방식이기 때문에
GPU Instancing이 깨지지 않습니다!!!!
색상 값은 Material이 아니라 Renderer에 붙은 MPB를 통해 GPU로 전달되며,
GPU는 이 값을 인스턴싱용 per-instance 데이터로 인식하고,
Draw Call은 하나로 묶고, 각 인스턴스별로 color 값만 다르게 전달됩니다.
휴 어렵네요!
그니깐, 유니티에 자체적으로 최적화를 신경써서 - MPB를 셰이더에 바인딩되는 추가 인스턴스 데이터로 사용할 수 있게 해준거라고 생각하시면 됩니다!
실제로 GPU Instancing은 per-instance uniforms 혹은 Structured Buffer 같은 구조로,
오브젝트마다 다른 데이터를 GPU로 넘길 수 있게 되어 있다고 하네욤.
올바른 MPB 사용방법 vs 잘못된 방법
// ✔️ 올바른 MPB 사용 예시
MaterialPropertyBlock mpb = new MaterialPropertyBlock();
foreach (var r in renderers)
{
r.GetPropertyBlock(mpb);
mpb.SetColor("_BaseColor", Color.red);
r.SetPropertyBlock(mpb);
}
// 🚫 매번 새 MPB 생성 → Instancing 깨짐
foreach (var r in renderers)
{
var mpb = new MaterialPropertyBlock(); // ← 이게 문제!
r.GetPropertyBlock(mpb);
mpb.SetColor("_BaseColor", Color.red);
r.SetPropertyBlock(mpb);
}
다음 시간에는 MPB를 쉽게 사용할 수 있도록 제가 만든 유틸리티 코드를 공유드리겠습니다 ㅎㅎ