이 페이지에서

Qt Quick 3D 아키텍처

Qt Quick 3D 는 3D 콘텐츠의 렌더링을 지원하기 위해 Qt Quick 를 확장합니다. 여기에는 몇 가지 새로운 공개 QML 임포트는 물론, 새로운 내부 씬 그래프와 렌더러를 포함한 광범위한 기능이 추가되었습니다. 이 문서는 공개 API부터 렌더링 파이프라인의 작동 방식에 대한 세부 사항에 이르기까지 Qt Quick 3D 의 아키텍처를 설명합니다.

모듈 개요

Qt Quick 3D 는 추가적인 3D API를 노출하고, 기존 3D 자산을 처리 및 가져오기 위한 유틸리티를 제공하는 여러 모듈과 플러그인으로 구성됩니다.

QML 임포트

  • QtQuick3D - 의 모든 핵심 구성 요소를 포함하는 주요 임포트 Qt Quick 3D
  • QtQuick3D.AssetUtils - 런타임 시 3D 자산을 임포트하기 위한 라이브러리
  • QtQuick3D.Helpers - 3D 디자인 및 3D 씬 디버깅에 활용할 수 있는 추가 구성 요소 라이브러리

C++ 라이브러리

  • QtQuick3D - 유일한 공개 C++ 모듈입니다. QtQuick3D QML 임포트에 노출된 모든 유형의 정의와 몇 가지 C++ API를 포함합니다.
  • QtQuick3DAssetImport - 자산 가져오기를 지원하고 자산을 QML로 변환하는 데 도움을 주는 내부 및 비공개 라이브러리입니다.
  • QtQuick3DRuntimeRender - 공간 씬 그래프 노드와 렌더러를 포함하는 내부 전용 라이브러리입니다.
  • QtQuick3DUtils - 다른 모든 C++ 모듈에서 공통 유틸리티 라이브러리로 사용되는 내부 전용 라이브러리.

AssetImporters 플러그인

애셋 임포트 툴링은 플러그인 기반 아키텍처를 사용하여 구현됩니다. Qt Quick 3D 에 포함된 플러그인들은 애셋 임포터 라이브러리 및 툴인 Balsam의 기능을 확장합니다.

  • Assimp - 이 플러그인은 타사 라이브러리인 libAssimp를 사용하여 3D 교환 형식의 3D 자산을 Qt Quick 3D QML 컴포넌트로 변환합니다.

Qt Quick 3D 가 Qt 그래픽스 스택 내에서 어떤 역할을 하는가

<span translate=Qt Quick 3D 그래픽 스택 아키텍처 다이어그램" src="images/quick3d-graphics-stack.drawio.svg" title="Qt Quick 3D 그래픽 스택 아키텍처 다이어그램"/>

위의 다이어그램은 Qt Quick 3D 가 더 광범위한 Qt 그래픽스 스택 내에서 어떻게 위치하는지 보여줍니다. Qt Quick 3D 는 2D Qt Quick API의 확장으로 작동하며, View3D 와 함께 3D 장면 항목을 사용할 경우 장면은 Qt 렌더링 하드웨어 인터페이스(RHI)를 통해 렌더링됩니다. RHI는 API 호출을 해당 플랫폼에 적합한 네이티브 렌더링 하드웨어 API 호출로 변환합니다. 위의 다이어그램은 각 플랫폼에서 사용할 수 있는 옵션을 보여줍니다. 네이티브 백엔드가 명시적으로 정의되지 않은 경우, Qt Quick 는 각 플랫폼에 대해 렌더링에 적합한 네이티브 백엔드를 기본값으로 사용합니다.

스택의 Qt Quick 3D 구성 요소와 Qt Quick 스택 간의 통합에 대해서는 다음 섹션에서 설명합니다.

2D 내 3D 통합

3D 콘텐츠를 2D로 표시하는 것이 Qt Quick 3D API의 주된 목적입니다. 3D 콘텐츠를 2D에 통합하기 위한 주요 인터페이스는 View3D 컴포넌트입니다.

View3D 컴포넌트는 콘텐츠가 포함된 다른 QQuickItem 파생 클래스와 동일하게 작동하며, 가상 함수 ` QQuickItem::updatePaintNode`를 구현합니다. ` Qt Quick `는 동기화 단계에서 ` Qt Quick ` 시나그래프 내의 모든 “변경된(dirty)” 항목에 대해 `updatePaintNode`를 호출합니다. 여기에는 ` View3D`가 관리하는 3D 항목도 포함되며, 이 항목들 또한 `updatePaintNode` 호출의 결과로 동기화 단계를 거치게 됩니다.

View3D 의 updatePaintNode 메서드는 다음 작업을 수행합니다:

  • 아직 존재하지 않는 경우 렌더러와 렌더 타깃을 설정합니다.
  • SceneManager를 통해 3D 씬 내의 항목을 동기화합니다
  • Qt Quick 에 의해 렌더링된 모든 “동적” 텍스처(아래3D 텍스처 경로 내의 2D 텍스처)를 업데이트합니다

그러나 3D 장면의 렌더링은 View3D 의 updatePaintNode 메서드 내에서 이루어지지 않습니다. 대신 updatePaintNode는 Qt Quick 3D 에 대한 렌더러를 포함하는 QSGNode 의 서브클래스를 반환하며, 이 렌더러는 Qt Quick 렌더링 프로세스의 전처리 단계에서 3D 장면을 렌더링합니다.

Qt Quick 3D 가 렌더링되는 방식은 사용되는 View3D::renderMode 에 따라 달라집니다:

오프스크린

View3D 의 기본 모드는 Offscreen 입니다. 오프스크린 모드를 사용할 때 View3D 는 오프스크린 서페이스를 생성하고 그 위에 렌더링함으로써 텍스처 제공자 역할을 합니다. 이 서페이스는 Qt Quick 에서 텍스처로 매핑될 수 있으며, QSGSimpleTextureNode 을 통해 렌더링됩니다.

이 패턴은 Qt Quick 에서 QSGLayerNodes가 이미 작동하는 방식과 매우 유사합니다.

언더레이

Underlay 모드를 사용할 때, 3D 씬은 View3D 를 포함하는 QQuickWindow 에 직접 렌더링됩니다. 렌더링은 QQuickWindow::beforeRenderPassRecording() 신호의 결과로 발생하며, 이는 Qt Quick 의 다른 모든 요소가 3D 콘텐츠 위에 렌더링됨을 의미합니다.

오버레이

Overlay 모드를 사용할 경우, 3D 장면은 View3D 를 포함하는 QQuickWindow 에 직접 렌더링됩니다. 렌더링은 QQuickWindow::afterRenderPassRecording() 신호의 결과로 발생하며, 이는 3D 콘텐츠가 Qt Quick 의 다른 모든 콘텐츠 위에 렌더링된다는 것을 의미합니다.

인라인

Inline 렌더링 모드는 QSGRenderNode 를 사용하며, 이는 오프스크린 표면을 사용하지 않고 Qt Quick 의 렌더 타깃에 직접 렌더링할 수 있게 해줍니다. 이는 Qt Quick Scene의 2D 렌더링 중에 렌더링 명령을 인라인으로 삽입함으로써 이루어집니다.

이 모드는 Qt Quick 렌더러와 동일한 깊이 버퍼를 사용하기 때문에 문제가 발생할 수 있으며, Qt Quick 와 Qt Quick 3D 에서 z 값이 의미하는 바가 완전히 다르기 때문입니다.

3D 내 2D 통합

3D 씬을 렌더링할 때, 2D 요소를 3D에 삽입해야 하는 경우가 많습니다. 3D 씬 내에 2D 콘텐츠를 통합하는 방법에는 두 가지가 있으며, 각각 화면에 표시되기까지의 경로가 다릅니다.

직접 경로

직접 경로는 2D Qt Quick 콘텐츠를 마치 3D 장면 내에 평면 항목으로 존재하는 것처럼 렌더링하는 데 사용됩니다. 예를 들어, 다음 장면 정의를 살펴보겠습니다:

Node {
    Text {
        text: "Hello world!"
    }
}

여기서 일어나는 과정은 다음과 같습니다. QQuickItem 유형의 공간 노드에 자식 컴포넌트가 설정되면, 먼저 QQuick3DItem2D로 감싸집니다. QQuick3DItem2D는 2D 항목에 3D 좌표를 추가하는 단순한 컨테이너입니다. 이를 통해 이후의 모든 2D 자식 요소가 3D 씬에서 올바르게 표시되도록 렌더링되는 데 필요한 기본 3D 변환이 설정됩니다.

씬을 렌더링할 시점이 되면, 이러한 2D 항목들의 QSGNodes가 Qt Quick 렌더러로 전달되어 적절한 렌더링 명령이 생성됩니다. 명령은 인라인으로 수행되고 현재 3D 변환을 고려하기 때문에, 2D 렌더러에서와 똑같이 렌더링되지만 마치 3D로 렌더링된 것처럼 표시됩니다.

이 접근 방식의 단점은 Qt Quick 2D 렌더러에는 조명 개념이 없기 때문에 3D 씬의 조명 정보를 사용하여 2D 콘텐츠에 음영을 줄 수 없다는 점입니다.

텍스처 경로

텍스처 경로는 2D Qt Quick 씬을 사용하여 동적 텍스처 콘텐츠를 생성합니다. 다음 텍스처 정의를 살펴보겠습니다:

Texture {
    sourceItem: Item {
        width: 256
        height: 256
        Text {
            anchors.centerIn: parent
            text: "Hello World!"
        }
    }
}

이 방식은 Qt Quick 에서 레이어 항목이 작동하는 방식과 동일하게 작동합니다. 즉, 모든 것이 최상위 항목 크기의 오프스크린 표면에 렌더링되고, 그 오프스크린 표면은 다른 곳에서 재사용할 수 있는 텍스처로 활용될 수 있습니다.

이 텍스처는 씬 내의 머티리얼에서 아이템에 Qt Quick 콘텐츠를 렌더링하는 데 사용될 수 있습니다.

씬 동기화

씬 매니저

Qt Quick 3D 의 씬 매니저(scene manager)는 3D 씬 내의 공간적 아이템을 추적하고, 동기화 단계에서 아이템이 해당 씬 그래프 노드를 업데이트하도록 하는 역할을 담당합니다. Qt Quick 에서는 2D의 경우 QQuickWindow 가 이 역할을 수행합니다. 씬 매니저는 프론트엔드 노드와 백엔드 씬 그래프 객체 간의 주요 인터페이스입니다.

각 View3D 항목에는 생성 시 내장된 씬 루트에 연결된 SceneManager가 하나 이상 존재합니다. 공간 노드가 View3D 의 자식으로 추가되면, 해당 노드는 View3D 의 SceneManager에 등록됩니다. 임포트된 씬을 사용할 때는, View3D 의 직접 자식이 아닌 노드들을 관리하기 위해 두 번째 SceneManager가 생성되거나(이미 존재하는 경우 참조됩니다). 이는 View3D 와 달리, 임포트된 씬은 참조될 때까지 QQuickWindow 에 존재하지 않기 때문입니다. 추가된 SceneManager는 가져온 장면에 속한 에셋이 참조되는 각 QQuickWindow 에 대해 적어도 한 번씩 생성되도록 보장합니다.

씬 매니저는 내부 API이지만, update() 메서드를 호출하여 변경된 것으로 표시된 모든 객체에 대해 updateSpatialNode를 호출하는 역할을 한다는 점을 알아두는 것이 중요합니다.

프론트엔드/백엔드 동기화

동기화의 목적은 프론트엔드(Qt Quick)에서 설정된 상태가 백엔드(Qt Quick Spatial Scene Graph Renderer)에서 설정된 상태와 일치하도록 하는 것입니다. 기본적으로 프론트엔드와 백엔드는 별도의 스레드에서 실행됩니다. 프론트엔드는 Qt 메인 스레드에서, 백엔드는 Qt Quick 의 렌더링 스레드에서 실행됩니다. 동기화 단계는 메인 스레드와 렌더링 스레드가 안전하게 데이터를 교환할 수 있는 단계입니다. 이 단계에서 씬 매니저는 씬 내의 변경된 노드(dirty node) 각각에 대해 updateSpatialNode를 호출합니다. 이를 통해 렌더러가 사용할 수 있도록 새로운 백엔드 노드를 생성하거나 기존 노드를 업데이트합니다.

Qt Quick Spatial Scene Graph

Qt Quick 3D 는 Qt Quick 와 동일한 프론트엔드/백엔드 분리 패턴을 사용하도록 설계되었습니다. 프론트엔드 객체는 Qt Quick 엔진에 의해 제어되는 반면, 백엔드 객체는 씬을 렌더링하기 위한 상태 데이터를 포함합니다. 프론트엔드 객체는 QObject 를 상속받으며 Qt Quick 엔진에 노출됩니다. QML 소스 파일의 항목들은 프론트엔드 객체에 직접 매핑됩니다.

이러한 프론트엔드 객체의 속성이 업데이트되면 하나 이상의 백엔드 노드가 생성되어 씬 그래프에 배치됩니다. 3D 씬 렌더링은 2D 렌더링보다 훨씬 더 많은 상태를 포함하기 때문에, 3D 씬 객체의 상태를 표현하기 위한 별도의 특화된 씬 그래프 노드 세트가 존재합니다. 이 씬 그래프는 ‘ Qt Quick ’ 공간 씬 그래프로 알려져 있습니다.

프론트엔드 객체와 백엔드 노드 모두 두 가지 클래스로 분류될 수 있습니다. 첫 번째는 3D 공간의 어딘가에 존재한다는 의미에서 ‘공간적(spatial)’인 것입니다. 실제로 이는 각 유형이 변환 행렬을 포함한다는 것을 의미합니다. 공간적 항목의 경우, 각 자식 항목이 부모의 변환을 상속받기 때문에 부모-자식 관계가 중요합니다.

다른 유형의 항목은 리소스입니다. 리소스 항목은 3D 공간 내의 특정 위치를 가지지 않으며, 다른 항목에서 사용되는 상태에 불과합니다. 이러한 항목들 사이에도 부모-자식 관계가 존재할 수 있지만, 이는 소유권 외에는 다른 의미를 갖지 않습니다.

Qt Quick 의 2D 씬 그래프와 달리, 공간 씬 그래프는 리소스 노드를 사용자에게 직접 노출합니다. 예를 들어, Qt Quick 에서 QSGTexture 는 공개 API이지만, 이 객체를 직접 노출하는 QQuickItem 는 없습니다. 대신 사용자는 텍스처의 출처와 렌더링 방법을 모두 설명하는 Image 아이템을 사용하거나, QSGTexture 자체를 조작하는 C++ 코드를 작성해야 합니다. Qt Quick 3D 에서는 이러한 리소스가 QML API에서 직접 노출됩니다. 이는 리소스가 씬 상태의 중요한 부분이기 때문에 필요합니다. 이러한 리소스는 씬 내의 많은 객체에서 참조될 수 있습니다. 예를 들어, 여러 Material이 동일한 Texture를 사용할 수 있습니다. 또한 런타임에 Texture의 속성을 설정하여, 예를 들어 텍스처 샘플링 방식을 직접 변경하는 것도 가능합니다.

공간 객체

모든 공간 객체는 Node 컴포넌트의 서브클래스이며, 이 컴포넌트에는 3D 공간에서의 위치, 회전, 크기를 정의하는 속성이 포함되어 있습니다.

리소스 객체

리소스 오브젝트는 ‘ Object3D ’ 컴포넌트의 서브클래스입니다. ‘ Object3D ’는 ‘ QObject ’의 서브클래스일 뿐이며, 씬 매니저와 함께 사용하기 위한 몇 가지 특수한 헬퍼 기능을 갖추고 있습니다. 리소스 오브젝트에는 부모/자식 관계가 존재하지만, 이는 주로 리소스 소유권을 관리하는 데 유용합니다.

View3D 및 렌더 레이어

프론트엔드/백엔드 분리에 관해, 사용자 관점에서 볼 때 View3D 가 분리의 기준점이 됩니다. 왜냐하면 View3D 가 렌더링할 장면 콘텐츠를 정의하기 때문입니다. Qt Quick 의 공간 씬 그래프(Spatial Scene Graph)에서, 렌더링될 씬의 루트 노드는 Layer 노드입니다. Layer 노드는 View3D 가 View3D 의 속성과 SceneEnvironment 의 속성을 조합하여 생성합니다. View3D 을 위해 씬을 렌더링할 때, 씬을 렌더링하기 위해 렌더러로 전달되는 것은 바로 이 Layer 노드입니다.

씬 렌더링

Qt Quick 3D 렌더링 그래프 흐름도

렌더 타겟 설정

렌더링 과정의 첫 번째 단계는 씬 렌더 타겟을 결정하고 설정하는 것입니다. SceneEnvironment 에 설정된 속성에 따라 실제 렌더 타겟은 달라집니다. 가장 먼저 결정해야 할 사항은 콘텐츠가 창 표면에 직접 렌더링될지, 아니면 오프스크린 텍스처에 렌더링될지 여부입니다. 기본적으로 View3D 는 오프스크린 텍스처로 렌더링합니다. 포스트 프로세싱 효과를 사용할 때는 오프스크린 텍스처로 렌더링해야 합니다.

씬 렌더 타겟이 결정되면 몇 가지 전역 상태가 설정됩니다.

  • 창 크기 - 창으로 렌더링하는 경우
  • 뷰포트 - 렌더링되는 씬 영역의 크기
  • 가위 사각형(scissor rect) - 뷰포트가 클리핑되어야 하는 창 영역의 부분 집합
  • 지우기 색상 - 필요한 경우, 렌더 타겟을 지울 때 사용할 색상

렌더링 준비

렌더링의 다음 단계는 준비 단계로, 이 단계에서 렌더러는 주어진 프레임에 대해 무엇을 렌더링해야 하는지 파악하고, 필요한 모든 리소스가 사용 가능하고 최신 상태인지 확인하기 위한 내부 정리를 수행합니다.

준비 단계 자체는 두 가지 단계로 나뉩니다. 하나는 렌더링 대상과 필요한 리소스를 결정하는 고수준 준비 단계이고, 다른 하나는 RHI를 사용하여 렌더링 파이프라인과 버퍼를 실제로 설정하고 메인 씬 패스의 렌더링 종속성을 설정하는 저수준 준비 단계입니다.

고수준 렌더링 준비

이 단계의 목적은 공간 씬 그래프의 상태를 추출하여 렌더링 명령을 생성하는 데 활용할 수 있는 형태로 변환하는 것입니다. 개략적으로 설명하자면, 렌더러는 일련의 조명 상태를 가진 단일 카메라의 관점에서 렌더링할 지오메트리 및 머티리얼 조합 목록을 생성합니다.

가장 먼저 수행되는 작업은 모든 콘텐츠에 대한 전역 공통 상태를 결정하는 것입니다. 조명 프로브( SceneEnvironment )가 환경 맵( lightProbe)을 정의하는 경우, 해당 조명 프로브 텍스처와 연관된 환경 맵이 로드되었는지 확인하고, 로드되지 않았다면 새로운 환경 맵을 로드하거나 생성합니다. 환경 맵 생성은 소스 텍스처를 큐브 맵으로 컨볼루션 처리하는 일련의 패스로 이루어집니다. 이 큐브 맵에는 스페큘러 반사 정보와 함께 머티리얼 셰이딩에 사용되는 조도 정보가 모두 포함됩니다.

다음으로, 렌더러는 장면에서 사용할 카메라를 결정해야 합니다. ` View3D`를 통해 활성 카메라가 명시적으로 정의되지 않은 경우, 장면에서 사용 가능한 첫 번째 카메라가 사용됩니다. 장면에 카메라가 없는 경우, 콘텐츠가 렌더링되지 않고 렌더러는 처리를 중단합니다.

카메라가 결정되면 해당 프레임에 대한 투영 행렬을 계산할 수 있습니다. 각 렌더링 대상은 어떻게 투영되어야 하는지 알아야 하므로 이 시점에서 계산이 이루어집니다. 이는 또한 어떤 렌더링 대상 항목을 렌더링해야 하는지 계산할 수 있게 되었음을 의미합니다. 모든 렌더링 가능한 항목의 목록을 바탕으로, 비활성화되었거나 완전히 투명하여 보이지 않는 모든 항목을 제거합니다. 그런 다음, 활성 카메라에서 프러스텀 컬링이 활성화된 경우, 각 렌더링 가능한 항목을 검사하여 해당 항목이 카메라 프러스텀의 시야 범위를 완전히 벗어났는지 확인하고, 그렇다면 렌더링 가능한 항목 목록에서 제거합니다.

카메라 투영 외에도, 셰이딩 코드에서 조명 계산을 수행하는 데 필요하기 때문에 카메라 방향도 계산됩니다.

씬에 라이트 노드가 있는 경우, 사용 가능한 최대 라이트 수만큼의 길이를 가진 목록에 이 노드들이 모아집니다. 씬에 렌더러가 지원하는 라이트 수보다 많은 라이트 노드가 존재하는 경우, 해당 한도를 초과하는 추가 라이트 노드는 무시되며 씬의 조명에 기여하지 않습니다. 라이트 노드의 범위를 지정할 수는 있지만, 범위를 설정하더라도 각 라이트의 조명 상태는 조명이 적용된 모든 머티리얼로 전송된다는 점에 유의해야 합니다. 다만 범위 내에 포함되지 않은 라이트의 경우 밝기가 0으로 설정되므로, 실제로는 해당 라이트가 해당 머티리얼의 조명에 기여하지 않습니다.

이제 렌더러블 목록이 다소 줄어들었기를 바라며, 각 항목을 씬의 현재 상태를 반영하도록 업데이트해야 합니다. 각 렌더러블에 대해 적절한 머티리얼이 로드되었는지 확인하고, 그렇지 않은 경우 새로운 머티리얼을 생성합니다. 머티리얼은 셰이더와 렌더링 파이프라인의 조합으로, 드로우 콜을 생성하는 데 필요합니다. 또한 렌더러는 렌더러블을 렌더링하는 데 필요한 모든 리소스(예: 모델에 설정된 지오메트리 및 텍스처)가 로드되었는지 확인합니다. 아직 로드되지 않은 리소스는 이 단계에서 로드됩니다.

머티리얼 및 이펙트에 대한 셰이더의 디스크 기반 캐싱 에 대한 설명은 ‘셰이더의 디스크 기반 캐싱’을 참조하십시오.

그런 다음 렌더러블 목록은 3개의 목록으로 정렬됩니다.

  • 불투명(Opaque) 항목: 이 항목들은 앞쪽에서 뒤쪽 순서, 즉 카메라에 가장 가까운 항목부터 카메라에서 가장 먼 항목 순으로 정렬됩니다. 이는 하드웨어 오클루전 컬링이나 프래그먼트 셰이더의 조기 Z 검출 기능을 활용하기 위함입니다.
  • 2D 항목: 이들은 ‘ QtQuick ’ 항목으로, ‘ Qt Quick ’ 렌더러에 의해 렌더링됩니다.
  • 투명 오브젝트: 이 오브젝트들은 뒤에서 앞으로, 즉 카메라에서 가장 멀리 있는 오브젝트부터 가장 가까운 오브젝트 순으로 정렬됩니다. 이는 투명 오브젝트가 그 뒤에 있는 모든 오브젝트와 블렌딩되어야 하기 때문입니다.

저수준 렌더링 준비

이 프레임에서 고려해야 할 모든 사항이 결정되었으므로, 이제 메인 렌더 패스에 대한 인프라 및 의존성을 다룰 수 있습니다. 이 단계에서 가장 먼저 수행되는 작업은 메인 패스에 필요한 모든 프리패스를 렌더링하는 것입니다.

  • DepthPass 렌더링 - 스크린 스페이스 앰비언트 오클루전(SSAO)이나 섀도잉과 같은 특정 기능에는 깊이 프리패스가 필요합니다. 이 패스는 모든 불투명 오브젝트를 깊이 텍스처에 렌더링하는 것으로 구성됩니다.
  • SSAO 패스 렌더링 — 스크린 스페이스 앰비언트 오클루전(SSAO) 패스의 목적은 앰비언트 오클루전 텍스처를 생성하는 것입니다. 이 텍스처는 나중에 머티리얼에서 셰이딩 시 특정 영역을 어둡게 만드는 데 사용됩니다.
  • 쉐도우 패스 렌더링 - 씬 내에서 그림자 기능이 활성화된 각 광원은 추가적인 쉐도우 패스를 생성합니다. 렌더러는 두 가지 서로 다른 쉐도잉 기법을 사용하므로, 광원 유형에 따라 다른 패스가 생성됩니다. 방향광에서 그림자를 렌더링할 때는, 방향광의 방향과 카메라 프러스텀의 크기를 조합하여 2D 오클루전 텍스처로 장면을 렌더링합니다. 포인트광이나 스팟광에서 그림자를 렌더링할 때는, 광원의 오클루전 텍스처가 광원의 각 면 방향에 대한 오클루전 기여도를 나타내는 큐브 맵이 됩니다.
  • Render ScreenTexture - 이 패스는 굴절(refraction)과 같은 렌더링 기법에 사용될 수 있는 스크린 텍스처가 필요한 쉐도우 모달( CustomMaterial )을 사용할 때만 발생합니다. 이 패스는 깊이 패스(depth pass)와 유사하게 작동하지만, 모든 불투명 오브젝트를 컬러 텍스처로 렌더링합니다.

의존성 렌더링이 완료된 후, 나머지 패스는 준비되지만 렌더링되지는 않습니다. 이 준비 과정에는 상위 수준의 준비 단계에서 수집된 상태를 그래픽 프리미티브로 변환하는 작업이 포함되며, 여기에는 유니폼 버퍼 값 생성/업데이트, 샘플러를 종속성 텍스처에 연결, 셰이더 리소스 바인딩 설정, 그리고 드로우 콜을 수행하는 데 필요한 파이프라인 상태를 생성하는 데 관련된 모든 작업이 포함됩니다.

씬 렌더링

이제 힘든 준비 작업이 끝났으니, 메인 씬의 콘텐츠를 구성하는 명령을 실행하는 쉬운 단계만 남았습니다. 이 렌더링은 다음 순서로 진행됩니다:

  • 클리어 패스(Clear Pass) - 엄밀히 말해 패스(pass)는 아니지만, ` SceneEnvironment`에 설정된 `backgroundMode`에 따라 여기서 다양한 처리가 이루어질 수 있습니다. 배경 모드가 transparent 또는 color인 경우, 색상 버퍼는 투명도 또는 지정된 색상으로 지워집니다. 반면, 배경 모드가 SkyBox로 설정된 경우, 카메라의 시점에서 SkyBox를 렌더링하는 패스가 실행되며, 이 과정에서 버퍼에 초기 데이터가 채워집니다.
  • 불투명 패스(Opaque Pass) - 다음으로 모든 불투명 오브젝트가 그려집니다. 이 단계에서는 파이프라인 상태를 설정하고, 이 시점에서 이미 정렬되어 있으므로 목록의 순서대로 각 오브젝트에 대한 드로잉 명령을 실행하기만 하면 됩니다.
  • 2D 패스 - 씬에 2D 오브젝트가 있는 경우, Qt Quick 렌더러가 호출되어 해당 오브젝트를 렌더링하는 데 필요한 렌더링 명령을 생성합니다.
  • 투명 패스(Transparent Pass) - 마지막으로, 장면 내의 투명 항목들이 불투명 항목과 동일한 방식으로 하나씩 렌더링됩니다.

이것으로 장면의 렌더링이 완료됩니다.

후처리

포스트 프로세싱 기능이 활성화된 경우, 씬 렌더러의 결과물은 포스트 프로세싱 단계의 입력으로 사용되는 텍스처라고 간주할 수 있습니다. 모든 포스트 프로세싱 메서드는 이 씬 입력 텍스처를 대상으로 작동하는 추가 패스입니다.

후처리 단계의 모든 단계는 선택 사항이며, 내장 기능이나 사용자 정의 효과 중 어느 것도 활성화되지 않은 경우, 씬 렌더링의 출력이 최종 렌더 타깃으로 사용됩니다. 단, ‘ tonemapping ’는 기본적으로 활성화되어 있다는 점에 유의하십시오.

후처리 렌더 패스 그래프

내장 후처리

ExtendedSceneEnvironment 및 그 상위 유형인 ‘ SceneEnvironment ’는 3D 장면에서 가장 일반적으로 사용되는 효과는 물론, 렌더러에서 생성된 높은 다이내믹 레인지(HDR) 색상 값을 0-1 LDR 범위로 매핑하는 데 사용되는 톤 매핑 기능도 제공합니다. 이 효과에는 피사계 심도, 글로우/블룸, 렌즈 플레어, 비네팅, 색상 조정 및 그레이딩, 안개, 앰비언트 오클루전이 포함됩니다.

후처리 효과

애플리케이션은 ` SceneEnvironment::effects ` 속성에서 순서가 지정된 목록 형태로 자체적인 사용자 정의 후처리 효과를 지정할 수 있습니다. 이 목록이 비어 있지 않을 경우, 목록에 포함된 효과는 ` ExtendedSceneEnvironment`에서 제공하는 내장 효과 보다 먼저 적용됩니다. 각 후처리 효과는 체인의 일부로, 이전 효과의 출력이 다음 효과의 입력으로 사용됩니다. 이 체인의 첫 번째 효과는 씬 렌더러 단계의 출력에서 직접 입력을 받습니다. 또한 효과는 씬 렌더러의 깊이 텍스처 출력에 접근할 수도 있습니다.

이 프로세스의 각 효과는 여러 하위 패스로 구성될 수 있으며, 이는 콘텐츠를 중간 버퍼에 렌더링할 수 있음을 의미합니다. 다중 패스 효과의 최종 패스는 후처리 단계의 다음 단계에서 사용될 색상 데이터를 포함하는 단일 텍스처를 출력해야 합니다.

시간 기반 및 점진적 앤티앨리어싱

시간 기반 및 점진적 앤티앨리어싱 단계는 ‘ SceneEnvironment ’의 속성을 설정하여 선택적으로 활성화할 수 있습니다. 엄밀히 말해 후처리 단계의 일부는 아니지만, 시간 기반 및 점진적 앤티앨리어싱의 실제 결과는 후처리 단계에서 구현됩니다.

시간 기반 앤티앨리어싱은 씬이 활발하게 업데이트될 때 수행됩니다. 이 기능이 활성화되면, 활성 카메라는 씬을 렌더링하는 동안 프레임마다 카메라 방향을 아주 미세하게 조정합니다. 그런 다음 현재 프레임을 이전에 렌더링된 프레임과 블렌딩하여 렌더링된 결과를 부드럽게 만듭니다.

프로그레시브 앤티앨리어싱은 장면이 업데이트되지 않을 때만 수행됩니다. 이 기능이 활성화되면 업데이트가 강제 실행되며, 활성 카메라의 방향을 아주 미세하게 조정하여 장면의 현재 상태가 렌더링됩니다. 최대 8개의 프레임이 누적되어 미리 정의된 가중치를 적용해 합성됩니다. 이는 애니메이션이 없는 장면을 부드럽게 만드는 효과가 있지만, 업데이트할 때마다 몇 개의 추가 프레임이 렌더링되므로 성능에 부담이 따릅니다.

슈퍼 샘플링 앤티앨리어싱(SSAA)

슈퍼 샘플링 앤티앨리어싱은 장면을 부드럽게 만드는 무차별적인 방식입니다. 이 방식은 요청된 장면 크기의 배수인 텍스처로 렌더링한 다음, 이를 대상 크기로 다운샘플링하는 방식으로 작동합니다. 예를 들어 2X SSAA가 요청되면, 장면은 의도된 크기의 2배인 텍스처로 렌더링된 후 이 단계에서 다운샘플링됩니다. 이는 성능과 리소스 사용량에 막대한 영향을 미칠 수 있으므로 가능하면 피해야 합니다. 또한 이 방법을 사용하기에는 ‘ View3D ’ 크기가 너무 클 수도 있습니다. 이 방법에 필요한 텍스처가 렌더링 하드웨어에서 지원하는 크기보다 클 수 있기 때문입니다.

© 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.