인스턴스 렌더링
소개
Qt Quick 3D Model 객체의 인스턴싱을 지원합니다. 인스턴싱이란 단일 드로우 호출로 하나의 객체를 여러 번 렌더링하는 기법을 말합니다. (예: OpenGL 함수 ` `.) glDrawElementsInstanced
인스턴싱을 사용하면 변형이 가해진 모델을 복제할 수 있습니다. ` Repeater3D`를 사용하는 것과는 달리, 모델과 그에 따른 그래픽 리소스는 단 한 번만 할당됩니다. 복제된 인스턴스의 렌더링은 GPU에서 저수준으로 처리됩니다. 모델의 복잡도에 따라, 이를 통해 성능이 몇 배나 향상될 수 있습니다.
실제로 인스턴싱은 각 인스턴스가 기본 모델에 비해 어떻게 수정되는지를 지정하는 테이블을 정의함으로써 수행됩니다.
인스턴싱 API
인스턴싱 API의 주요 원칙은 명시적이라는 점입니다. 즉, 기존 API 내에서 인스턴싱이 가능한 부분을 자동으로 감지하려고 하지 않습니다. 대신, 각 모델의 ` instancing ` 속성을 ` Instancing ` 객체를 참조하도록 설정하여 개별적으로 표시합니다. 동일한 `Instancing` 객체를 여러 모델에 동시에 사용할 수 있습니다.
Instancing 객체는 각 복제본이 어떻게 렌더링될지를 정의하는 테이블을 지정합니다. 적용 가능한 변환은 다음과 같습니다:
- 변환: 위치, 회전, 크기
- color: 모델의 머티리얼과 블렌딩되는 색상
- 사용자 정의 데이터: 사용자 정의 머티리얼에서 사용할 수 있는 데이터
Qt Qml은 Instancing을 상속하는 세 가지 Qml 유형을 제공합니다:
- InstanceList 모든 인스턴스를 열거하고 각 인스턴스의 속성에 바인딩할 수 있게 해줍니다.
- RandomInstancing 정의된 범위 내에서 무작위 인스턴스를 생성하여 신속하게 테스트하고 프로토타입을 제작할 수 있는 방법을 제공합니다.
- FileInstancing 외부 파일에서 인스턴스 테이블을 읽어옵니다.
인스턴싱 예제는 QML API를 사용하여 씬을 만드는 방법을 보여줍니다.
QQuick3DInstancing 를 서브클래싱하여 C++에서 다른 종류의 인스턴스 테이블을 정의할 수 있습니다. 예를 들어, particle system 는 내부적으로 자체 인스턴싱 테이블을 사용합니다. 이 테이블은 ModelParticle3D.instanceTable 에서 확인할 수 있습니다.
사용자 정의 셰이더 코드를 작성하면 인스턴싱을 사용하여 물리 기반 렌더링 변수, 스켈레탈 애니메이션 가중치, 왜곡 또는 사용자 정의 머티리얼로 표현할 수 있는 기타 속성과 같은 추가 속성을 제어할 수 있습니다. 인스턴싱 테이블의 사용자 정의 데이터는 4개의 부동 소수점 숫자로 구성됩니다.
사용자 정의 인스턴싱 예제에서는 사용자 정의 머티리얼과 C++로 구현된 인스턴스 테이블을 결합하는 방법을 보여줍니다.
알파 블렌딩 및 인스턴싱
올바른 알파 블렌딩을 위해서는 반투명 오브젝트가 뒤에서 앞으로 렌더링되어야 합니다. 이러한 이유로 QtQuick3D 는 불투명 오브젝트와 반투명 오브젝트를 별도로 정렬하여 올바른 순서대로 렌더링합니다. 그러나 인스턴싱을 사용할 경우, ‘ depth-sorting ’가 활성화되지 않은 상태라면 GPU는 인스턴싱 테이블에 지정된 순서대로 인스턴스를 렌더링합니다. 성능상의 이유로, QtQuick3D 는 인스턴스 수가 많을 경우 정렬에 오랜 시간이 소요될 수 있으므로 기본적으로 테이블을 정렬하지 않습니다. 즉, 반투명 인스턴스가 서로 겹치거나 다른 반투명 객체와 겹칠 경우 결과가 올바르지 않게 보일 수 있습니다. 일반적으로 불투명도가 낮을수록 이러한 오류는 덜 눈에 띕니다.
Qt는 불투명 객체 뒤쪽에 객체가 그려지는 것을 방지하기 위해 깊이 버퍼 테스트를 사용하므로, 완전히 불투명한 객체와 겹치지 않는 반투명 객체는 항상 올바르게 렌더링됩니다. 그러나 정렬이 이루어지지 않는다는 점은 불투명 객체에 잠재적인 성능 문제를 야기할 수 있습니다. 즉, 객체가 최적의 순서로 렌더링되지 않을 수 있으며, 이로 인해 동일한 픽셀이 여러 번 그려져 프래그먼트 셰이더의 부하가 증가할 수 있습니다.
렌더러는 인스턴싱 테이블의 내용을 검사하지 않으므로, 인스턴스 테이블에 반투명한 알파 값이 포함된 경우 이를 명시적으로 지정해야 합니다. 렌더러가 알파 블렌딩을 활성화하도록 하려면 ` hasTransparency ` 속성을 ` true `로 설정하십시오. 이는 모든 인스턴스에 적용됩니다. 완전히 불투명한 인스턴스조차도 깊이 테스트 없이 렌더링되어 눈에 띄는 오류가 발생할 수 있습니다.
모델의 ‘ depth bias ’을 설정하여 씬의 나머지 부분에 대한 렌더링 순서를 조정할 수 있습니다.
변환 및 인스턴싱
각 인스턴스는 인스턴스 테이블에 고유한 변환을 가지고 있습니다. 이는 인스턴스화된 모델의 변환과 결합됩니다. 사용 사례가 여러 가지이므로 이 과정은 다소 복잡합니다:
- 모델에 변환을 적용하여 각 개별 인스턴스에 반영하는 경우입니다. 이를 통해 인스턴스 테이블을 변경할 필요 없이 모든 인스턴스를 한 번에 회전시키는 등 효율적인 애니메이션 구현이 가능합니다.
- 인스턴스 그룹 전체에 한 번에 변환을 적용하는 경우.
- 모델 계층 구조를 인스턴싱하는 경우.
이러한 모든 경우를 지원하기 위해 모델의 변환은 로컬 인스턴스 변환과 전역 인스턴스 변환, 두 부분으로 나뉩니다. 개념적으로 인스턴싱은 다음과 같이 수행됩니다:
- 먼저 모델이 로컬 인스턴스 변환에 따라 변환됩니다.
- 그런 다음 인스턴스 테이블 변환을 적용하여 각 인스턴스를 계산합니다.
- 마지막으로, 인스턴스화된 오브젝트 전체 그룹이 전역 인스턴스 변환에 따라 변환됩니다.
기본적으로 모델의 로컬 인스턴스 변환은 모델의 스케일과 회전으로 구성되며, 나머지는 전역 인스턴스 변환에 포함됩니다.
이는 모델의 ` instanceRoot ` 속성을 설정하여 제어할 수 있습니다. 이 속성은 인스턴스의 좌표계 원점을 정의합니다. 가장 일반적인 용도는 모델 계층 구조를 인스턴싱할 때입니다. 예를 들어, 큐브 주위를 공전하는 구체의 경우:
Model {
id: cube
instancing: someInstanceTable
source: "#Cube"
materials: DefaultMaterial { diffuseColor: "lightgray" }
Node {
Model {
source: "#Sphere"
instanceRoot: cube
instancing: cube.instancing
x: 150
materials: DefaultMaterial { diffuseColor: "gray" }
}
NumberAnimation on eulerRotation.y {
from: 0
to: 360
duration: 4000
loops: Animation.Infinite
}
}
}instanceRoot 는 구체 인스턴스가 마치 큐브의 구성 요소인 것처럼 배치되어야 함을 명시하는 데 필요합니다. 계층 구조 내의 각 모델은 여전히 instancing 속성을 지정해야 합니다. 일반적인 경우, 이 속성은 모두 동일한 Instancing 객체로 설정되어야 합니다.
instanceRoot 단일 모델을 인스턴싱할 때도 사용할 수 있습니다. 예를 들어, 중심이 아닌 지점을 중심으로 회전하는 원통:
Node {
id: parentNode
Model {
source: "#Cylinder"
instanceRoot: parentNode
instancing: anotherInstanceTable
x: 25
materials: DefaultMaterial { diffuseColor: "white" }
}
NumberAnimation on eulerRotation.y {
from: 0
to: 360
duration: 1000
loops: Animation.Infinite
}
}선택 및 인스턴스화
Picking 는 사용자 인터페이스 상호 작용을 통해 모델을 선택할 수 있게 해주는 메커니즘입니다. 인스턴스화된 렌더링에서는 동일한 모델에 대한 여러 표현이 존재하므로, 선택 결과에는 instance index 가 포함됩니다. 인스턴스화된 선택 기능은 기본 모델의 pickable 속성을 설정하여 활성화할 수 있습니다.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.