오브젝트를 렌더링할 때 기본적으로 Renderer 컴포넌트의 sharedMaterial 이 사용된다. 이는 에디터에서 오브젝트에 설정해둔 재질과 정확히 일치한다. 즉 sharedMaterial 은 매트리얼 에셋과 대응한다. 이를 확인하는 방법은 실행 중에 sharedMaterial 의 속성을 변경해보는 것이다. 그럼 에셋이 바뀌어 있는 것을 확인할 수 있다. 심지어 종료해도 변경 상태가 남아있게 되므로 주의..

기본적으로, 매트리얼에 수정을 가하지 않으면 sharedMaterial 을 참조하여 렌더링된다. 그리고 이는 배치 렌더링의 핵심이다. 동일한 재질을 지녀야 한번에 렌더링할 수 있기 때문.

그러나 상당히 많은 경우에서 특정 오브젝트의 재질 속성을 변경할 필요가 생긴다( 일시적으로라도 ). 컬러값, 빛의 세기, 텍스처 등.. 이러한 이유 때문에 sharedMaterial 과 함께 material 이 존재한다. 유니티는 sharedMaterial 이 아닌 material 에 접근하는 순간 sharedMaterial 의 사본을 생성하여 material 에 할당해준다. material 은 Renderer 에 존재하며 다시 Renderer 는 오브젝트가 소유하므로 즉 오브젝트에 할당된 재질이다. 따라서 다른 오브젝에 영향을 주지 않으면서 재질 속성을 달리할 수가 있게 된다. 이렇게 사본이 생성되면 에디터상에서 오브젝트의 재질을 확인했을 때 (Instance) 라는게 붙는다는 것을 알 수 있다.

사본이 생성되는 순간 이 오브젝트는 배치 렌더링을 포기하게 되는 것이다. 한번 material 을 사용하게 되면 해당 오브젝트는 다시는 배치 렌더링을 할 수 없게 된다. 그리고 material 의 값을 변경하지 않더라도 참조하는 순간 사본이 생성된다( material, material.color, 이하 material 을 참조하는 순간.. ).

다행히, 일시적으로 재질 속성을 변경하기 위한 좋은 대안이 있는데 바로 재질 속성 블럭( Material Property Block ) 이다. 방법부터 정리하면 아래와 같다.

 

// 재질 속성 블럭을 생성한다. 생성은 한 번만 하면 되므로 Awake 같은 곳에서 호출하자
MaterialPropertyBlock mpb = new MaterialPropertyBlock();

// 방금 생성한  객체에 변경하길 원하는 재질 속성들을 설정한다
mpb.SetColor(Shader.PropertyToID("_Color"), Color.black);

// 렌더러에 객체를 설정해준다( 만약 이후에 재질 속성 블럭을 수정했다면 다시 아래 코드를 호출해줄 것 )
renderer.SetPropertyBlock(materialProp);

// 재질 속성을 원래대로 돌리는건 아래처럼 해주면 된다
renderer.SetPropertyBlock(null);

 

위처럼 재질 속성 블럭을 이용하면 사본이 생성되지 않으며 객체가 set 되어 있는 동안에만 배칭되지 않는다.

'유니티 - 최적화' 카테고리의 다른 글

NGUI 최적화의 핵심  (1) 2016.01.14
텍스처 최적화  (0) 2016.01.13
최적화의 기본  (0) 2016.01.08
Update 와 FixedUpdate  (0) 2016.01.08
Application.Integrate Assets in Background 에서 렉이 발생하는 경우  (0) 2016.01.08
Posted by 카코데몬
,