Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

최적화(Optimization)

지속적으로 처리해야 하는(그리고 일정량의 제어를 유지해야 하는) 대량(수천 개)의 인스턴스의 경우 :ref:`서버를 직접 사용 <doc_using_servers>`하는 것이 권장되는 최적화입니다.

개체의 양이 수십만 또는 수백만에 도달하면 이러한 접근 방식 중 어느 것도 더 이상 효율적이지 않습니다. 그러나 요구 사항에 따라 최적화가 한 가지 더 가능합니다.

MultiMesh 설정

:ref:`MultiMesh<class_MultiMesh>`는 한 번에 최대 수백만 개의 객체를 그릴 수 있는 단일 그리기 기본 요소입니다. 이를 위해 GPU 하드웨어를 사용하기 때문에 매우 효율적입니다.

유일한 단점은 개별 인스턴스에 대해 가능한 화면 또는 절두체 컬링이 없다는 것입니다. 즉, 전체 MultiMesh의 가시성에 따라 수백만 개의 객체가 항상 또는 절대로 그려지지 않는다는 의미입니다. 사용자 정의 가시성 직사각형을 제공하는 것이 가능하지만 항상 모두 아니면 전무 가시성이 됩니다.

객체가 충분히 단순한 경우(단지 몇 개의 정점) 대부분의 최신 GPU가 이 사용 사례에 최적화되어 있으므로 이는 일반적으로 큰 문제가 되지 않습니다. 해결 방법은 세계의 다양한 영역에 대해 여러 개의 다중 메시를 만드는 것입니다.

또한 정점 셰이더 내에서 일부 논리를 실행할 수도 있습니다(INSTANCE_ID 또는 INSTANCE_CUSTOM 내장 상수 사용). 멀티메시에서 수천 개의 객체에 애니메이션을 적용하는 예는 수천 마리의 물고기 애니메이션 튜토리얼을 참조하세요. 셰이더에 대한 정보는 텍스처를 통해 제공될 수 있습니다(이에 이상적인 부동 소수점 Image 형식이 있습니다).

또 다른 대안은 매우 효율적인 GDExtension 및 C++를 사용하는 것입니다(RenderingServer.multimesh_set_buffer() 함수를 통해 선형 메모리를 사용하여 모든 객체에 대한 전체 상태를 설정하는 것이 가능합니다). 이러한 방식으로 여러 스레드로 배열을 생성한 다음 한 번의 호출로 설정할 수 있어 높은 캐시 효율성을 제공합니다.

마지막으로 모든 MultiMesh 인스턴스를 표시할 필요는 없습니다. 보이는 것의 양은 MultiMesh.visible_instance_count 속성으로 제어할 수 있습니다. 일반적인 작업 흐름은 사용할 최대 인스턴스 양을 할당한 다음 현재 필요한 수에 따라 표시되는 양을 변경하는 것입니다.

타이머(Timer) 예제

다음은 코드에서 MultiMesh를 사용하는 예입니다. 수백만 개의 객체에는 GDScript 이외의 언어가 더 효율적일 수 있지만, 수천 개의 객체에는 GDScript가 괜찮을 것입니다.

extends MultiMeshInstance3D


func _ready():
    # Create the multimesh.
    multimesh = MultiMesh.new()
    # Set the format first.
    multimesh.transform_format = MultiMesh.TRANSFORM_3D
    # Set the mesh that will be duplicated.
    multimesh.mesh = BoxMesh.new()
    # Then resize (otherwise, changing the format is not allowed).
    multimesh.instance_count = 10000
    # Maybe not all of them should be visible at first.
    multimesh.visible_instance_count = 1000

    # Set the transform of the instances.
    for i in multimesh.visible_instance_count:
        multimesh.set_instance_transform(i, Transform3D(Basis(), Vector3(i * 20, 0, 0)))