그래픽 성능 최적화
최적의 퍼포먼스를 위한 캐릭터 모델링

드로우콜(Draw call) 배칭

스크린에 오브젝트를 렌더링하기 위해 렌더링 엔진은 OpenGL이나 Direct3D 그래픽 API에 그리기 요청(draw call)을 해야 합니다. 그래픽 API 모든 그리기 요청(draw call)은 CPU 상의 상당한 퍼포먼스 오버헤드를 일으킵니다.

Unity uses several techniques to address this:

  • Static Batching: combine static (i.e. not moving) objects into big meshes, and render them in a faster way.
  • Dynamic Batching: for small enough meshes, transform their vertices on the CPU, group many similar ones together, and draw in one go.

Built-in batching has several benefits compared to manually merging objects together (most notably, the objects can still be culled individually). But it also has some downsides too (static batching incurs memory and storage overhead; and dynamic batching incurs some CPU overhead).

Material Setup For Batching

동일한 메터리얼 을 공유하는 오브젝트만 배칭할 수 있습니다. 따라서 보다 효과적인 배칭하려면 가능한 한 다른 오브젝트 간에 많은 메터리얼을 공유해야 합니다.

다른 텍스쳐에 있는 두개의 독립적인 매터리얼을 하나의 큰 텍스쳐로 결합 할 수 있습니다.(텍스처 아틀라스라는 과정입니다). 일단 텍스처를 동일 아틀라스로 해버리면 단일 메테리얼로 사용할 수 있게 됩니다.

만약 스크립트에서 공유하는 메테리얼 속성을 액세스한다면 다음의 정보가 중요합니다 : [Renderer.material](ScriptRef : Renderer-material.html)의 변화는 메테리얼의 복사가 생깁니다. 공유하는 자료를 유지하고 싶은 경우라면 이것 대신 [Renderer.sharedMaterial](ScriptRef : Renderer-sharedMaterial.html)를 사용합시다.

While rendering shadow casters, they can often be batched together even if their materials are different. Shadow casters in Unity can use dynamic batching even with different materials, as long as the values in materials needed by the shadow pass are the same. For example, many crates could use materials with different textures on them, but for shadow caster rendering the textures are not relevant – in that case they can be batched together.

다이나믹(동적) 배칭

동일한 메테리얼을 공유하고 다른 조건을 만족하면, Unity는 자동으로 움직이고 있는 오브젝트를 배칭합니다. 동적 배칭이 자동으로 처리되므로 어떤 노력이 필요하다는 것은 아닙니다.

  • 동적 오브젝트의 배칭은 정점마다 어느 정도 오버 헤드가 있습니다. 그래서 배칭은 총 정점 수가 900 이하의 메쉬로 밖에 적용되지 않습니다.
  • 셰이더가 정점 위치와 법선이나 다른 UV 정보를 사용한다면 300 정점까지 입니다. 한편 정점 위치, 법선, UV0, UV1 탄젠트를 사용한다면 180 정점까지 입니다.
  • 주의 : 이 제한은 향후 변경될 수 있습니다
  • Objects will not be batched if they contain mirroring on the transform, for example object A with +1 scale and object B with –1 scale can not be batched together.
  • 다른 메테리얼의 인스턴스를 사용하는 경우, (기본적으로 같은 것을 바탕으로 하고 있어도) 함께 배칭되지 않습니다.
  • 라이트 맵을 가진 오브젝트는 추가 렌더러 메테리얼 파라미터를 가지고 있습니다 :( 라이트 맵 및 오프셋 / 스케일). 따라서 일반적으로 동적으로 라이트 매핑된 오브젝트가 완전히 동일한 라이트 맵의 위치가 아닌 한 배칭되지 않습니다.
  • Multi-pass shaders will break batching.
  • 멀티 패스 쉐이더는 배칭을 억제합니다. Unity가 지원하는 대부분의 쉐이더는 포워드 렌더링에서 여러 라이트를 지원하고 있습니다만, 그들은 효과적으로 추가 경로를 사용하고 있습니다. “addtional per-pixel lights”의 그리기 요청은 배칭되지 않습니다.
    • Legacy Deferred (light pre-pass) rendering path has dynamic batching disabled, because it has to draw objects twice.

Since it works by transforming all object vertices into world space on the CPU, it is only a win if that work is smaller than doing a “draw call”. How exactly expensive is a draw call depends on many factors, primarily on the graphics API used. For example, on consoles or modern APIs like Apple Metal the draw call overhead is generally much lower, and often dynamic batching can not be a win at all.

스태틱(정적) 배칭

한편, 정적 배칭은 어떤 크기의 형상이라도 그리기 요청을 줄일 수 있습니다(움직이지 않고 동일한 메테리얼을 공유하는 것이 조건입니다). 정적 배칭은 동적 배칭보다 눈에 띄게 효과가 나옵니다. CPU 파워를 줄일 필요가 있다면 꼭 정적 배칭을 선택하십시오.

정적 배칭을 이용하려면 오브젝트가 게임 중 움직이거나 회전하거나 스케일 하는 것이 __없다__는 것을 명시적으로 설정해야 합니다. Inspector의 Static 확인란을 선택하면 해당 설정이 됩니다. :

정적 배칭을 사용하면 결합된 형상 정보를 저장하는 메모리가 좀 더 많이 필요해집니다. 만약 정적 배칭 전에 여러 오브젝트에 동일한 형상을 공유하고 있는 경우, 오브젝트마다 형상의 복사가 일어납니다(편집기에서도 런타임에서도). 이 때문에 언제든지 권장하는 방법은 아닙니다. 즉, 경우에 따라서는 작은 메모리 사용량을 유지하기 위해 정적 배칭을 피하고, 렌더링 성능을 희생해야 하는 경우도 있을 것입니다. 예를 들어, 밀집한 숲에서 나무를 정적 배칭하면 메모리에 상당한 부담이 될 수 있습니다.

Internally, static batching works by transforming the static objects into world space and building a big vertex + index buffer for them. Then for visible objects in the same batch, a series of “cheap” draw calls are done, with almost no state changes in between. So technically it does not save “3D API draw calls”, but it saves on state changes done between them (which is the expensive part).

기타 배칭 Tips

현재는 메쉬 렌더러(class-MeshRenderer) 및 파티클 시스템(Particle Systems) 만 배칭됩니다. 즉 스킨 메쉬 크로스 트레일 렌더러 및 기타 유형의 렌더링 컴포넌트는 배칭 되지 않습니다.

반투명한 쉐이더는 종종 뒤 에서 앞으 위치로의 오브젝트의 순서로 렌더링하지 않으면 투명도가 제대로 반영하지 않을 수 있습니다. Unity는 먼저 오브젝트를 순서대로 렌더링을 지시하고 배칭하려고 합니다 - 그러나 순서를 엄격하게 적용해야 하는 경우, 불투명 오브젝트와 비교하여 배칭은 보다 적게된다는 것을 의미합니다.

Manually combining objects that are close to each other might be a very good alternative to draw call batching. For example, a static cupboard with lots of drawers often makes sense to just combine into a single mesh, either in a 3D modeling application or using Mesh.CombineMeshes.

그래픽 성능 최적화
최적의 퍼포먼스를 위한 캐릭터 모델링