라이트맵 및 글로벌 일루미네이션
소개
참고: Qt 6.4부터 라이트맵 베이킹은 초기 기술 프리뷰 상태입니다. 향후 릴리스에서 기능, 품질 및 API가 변경될 수 있습니다.
베이크된 라이트맵을 사용하면 DirectionalLight, PointLight, SpotLight 와 같은 라이트에서 직접 조명을 미리 생성하고 라이트가 드리우는 그림자까지 생성할 수 있습니다. 런타임에 조각 셰이더에서 적절한 계산을 수행하고 그림자의 경우 잠재적으로 비용이 많이 드는 그림자 맵을 실시간으로 생성하는 대신 미리 생성된 이미지 맵을 샘플링합니다.
라이트맵은 Model 당 생성됩니다. Model 에 여러 개의 서브메쉬가 있어 여러 머티리얼과 연관된 경우에도 전체 모델에 대해 하나의 단일 라이트맵 이미지가 생성됩니다.
라이트맵은 본질적으로 적절한 오클루전("빛이 벽을 통과하지 않음")과 조명 및 그림자 매핑을 위한 실시간 기술보다 더 사실적인 그림자를 제공하는 레이트레이싱을 사용하여 생성됩니다.
더 중요한 점은 라이트맵을 사용하면 간접 조명을 베이킹하여 전역 조명을 위한 솔루션을 제공할 수 있다는 점입니다. 여기에는 씬의 다른 표면에서 반사되는 광선이 고려됩니다.
아래는 간단한 예시입니다. 이 씬에는 아래쪽을 가리키는 DirectionalLight 과 PointLight 이 있는 네 개의 직사각형과 구 모델이 있습니다. 직사각형 모델은 0도와 90도로 회전되어 모두 DirectionalLight 의 방향과 평행하거나 수직이기 때문에 실시간 조명 계산의 한계가 과장되어 있습니다.
두 번째 이미지에서는 다섯 모델 모두에 대해 라이트맵을 베이크한 후 라이트맵을 활성화한 상태로 씬을 렌더링했습니다. 두 조명 모두 완전히 베이크된 것으로 설정되어 있어 직접 조명과 간접 조명이 모두 베이크됩니다. 간접 조명은 256개 samples 와 최대 3개 bounces 를 사용합니다. 그런 다음 결과 라이트맵의 노이즈를 제거했습니다. 이렇게 하면 훨씬 더 사실적인 이미지를 얻을 수 있습니다.
실시간 조명
완전히 베이크된 조명
아래는 라이트맵 결과가 어떻게 구현되었는지 보여주는 스니펫입니다. usedInBakedLighting , bakeMode, bakedLightmap 속성에 차이가 있습니다. 이 예제에서는 디스크 공간을 절약하고 애플리케이션 로드 시간을 줄이기 위해 texelsPerUnit 속성을 사용하여 라이트맵 크기를 줄였습니다.
DirectionalLight { bakeMode: Light.BakeModeAll eulerRotation.x: -90 brightness: 0.5 castsShadow: true shadowFactor: 75 } PointLight { bakeMode: Light.BakeModeAll y: 200 z: 100 color: "#d9c62b" castsShadow: true shadowFactor: 75 } Model { usedInBakedLighting: true bakedLightmap: BakedLightmap { enabled: true key: "sphere1" } source: "#Sphere" materials: PrincipledMaterial { } y: 100 } Model { usedInBakedLighting: true bakedLightmap: BakedLightmap { enabled: true key: "rect1" } source: "#Rectangle" materials: PrincipledMaterial { } eulerRotation.x: -90 scale: Qt.vector3d(10, 10, 10) } // ... three additional Rectangle models, with rotations 0, 90, and -90
위의 예시에서는 완전히 베이크된 조명을 사용했습니다. 직접 조명과 그림자 매핑을 실시간으로 수행하면서 간접 조명에는 베이크된 조명만 사용하도록 조명을 구성할 수도 있습니다. 아래 장면에는 5개의 포인트 라이트가 있으며, 두 번째 스크린샷의 경우 모두 BakeModeIndirect 로 설정되어 있습니다. 직접 조명과 그림자는 동일하게 보이지만 두 번째 이미지는 어느 정도의 전역 조명이 추가되었기 때문에 훨씬 더 좋아 보입니다.
실시간 조명
베이크된 간접 조명이 추가된 경우
라이트맵으로 작업할 때 중요한 고려 사항
베이크된 조명에 기여하는 조명은 bakeMode 속성이 Light.BakeModeIndirect 또는 Light.BakeModeAll 로 설정됩니다. 후자는 해당 특정 조명에 대한 직접 및 간접 기여가 모두 라이트맵에서 제공됨을 나타냅니다. 직접 기여에는 항상 그림자도 포함됩니다. 반면, 특정 조명에 대한 간접 조명만 씬에 추가하고 직접 조명은 실시간으로 계산(섀도 매핑 수행)하는 것이 라이트맵의 의도라면 Light.BakeModeIndirect 대신 을 사용해야 합니다.
참고: 일반적으로 라이트맵은 트랜스폼, 지오메트리 및 머티리얼과 관련하여 정적인 모델에 적합합니다. 베이크된 조명에 참여하는 라이트에도 동일하게 적용됩니다.
예를 들어 eulerRotation 프로퍼티를 애니메이션하여 Model 를 회전하는 씬에서 해당 Model 에 라이트맵을 적용하면 시각적으로 잘못된 결과가 나타납니다. 미리 생성된 라이트맵은 오브젝트에 대해 하나의 회전 상태만 캡처하므로 해당 특정 Model 에 대한 렌더링 결과가 올바르지 않습니다. 다른 예를 들어 모델의 서브메시 중 하나의 머티리얼이 시간(애니메이션) 또는 일부 사용자 상호 작용에 따라 baseColor 속성을 동적으로 변경하는 경우에도 마찬가지입니다. 라이트맵은 주어진 머티리얼 baseColor 하나만 캡처할 수 있습니다. 라이트도 마찬가지입니다. 예를 들어 시간에 따라 회전하고 밝기, 색상 등을 변경하는 DirectionalLight 은 베이크된 조명에 적합하지 않습니다.
참고: 반면에 라이트매핑을 언제 사용할지는 항상 디자이너의 선택입니다. 특히 BakeModeIndirect 조명을 사용하면 라이트매핑된 장면의 일부 오브젝트가 동적 동작을 사용하더라도 시각적으로 만족스러운 결과를 얻을 수 있는 장면이 있을 수 있습니다.
라이트매핑은 복잡한 엔진 및 툴링 기능입니다. 엔진의 렌더링 파이프라인의 여러 부분을 대체하고 다시 구현합니다. 라이트맵을 베이크할 때 근본적으로 다른 렌더링 모델을 사용하지만 동일한 씬 구조, 에셋 데이터, 엔진 데이터 구조를 사용하고 상호 운용합니다. 레이트레이싱 기반 결과물은 종종 실시간 대안보다 월등히 뛰어나기도 하지만, 모델과 라이트의 필수 정적 특성, 때로는 라이트매핑 특유의 품질 및 렌더링 아티팩트 문제와 같은 한계가 존재합니다.
실제로 어떤 유형의 조명을 언제 사용할지는 디자이너의 예술적 선택에 따라 결정됩니다. 세 가지 bakeMode 설정 모두 용도가 있으며, 복잡하고 큰 씬에서는 씬의 특정 부분에 적합하다고 판단되는 조명과 모델, 재질, 동적 동작의 종류에 따라 세 가지를 모두 활용할 수도 있습니다. 라이트매핑은 모든 장면과 애플리케이션에 사용할 수 있는 단순한 온/오프 유형의 토글 스위치가 아니라 주어진 장면의 조명 요구 사항을 신중하게 평가해야 하는 강력한 기능으로, 최종 접근 방식과 관련 설정을 결정하기 전에 다양한 라이트맵 베이킹 및 품질 설정을 탐색하고 테스트하는 테스트 및 조정 루프와 함께 장면 콘텐츠와 동작을 적절히 설계해야 하는 경우가 많습니다.
참고: 라이트맵은 양면 표면을 지원하지 않습니다. 실시간 라이팅을 사용하면 cull mode Material.NoCulling
의 머티리얼은 조각의 방향에 따라 노멀을 적절하게 자동으로 반전시킵니다. 라이트맵 베이킹은 뷰 공간에서 작동하지 않으므로 라이트맵에는 이 옵션이 적용되지 않습니다. 따라서 이에 의존하는 모델에는 베이크된 조명을 사용하지 마십시오.
라이트맵 베이킹
직접 및 간접 조명을 캡처하고 애플리케이션의 후속 실행에서 렌더러가 사용할 수 있는 이미지 맵을 생성하는 오프라인 프로세스를 의미하는 라이트맵 베이킹과 관련된 속성 및 유형입니다:
- Model::usedInBakedLighting
- Model::lightmapBaseResolution,
- Light::bakeMode,
- Lightmapper 과 SceneEnvironment::lightmapper
- BakedLightmap 와 Model::bakedLightmap
Qt 6.4부터 라이트맵 베이킹 프로세스는 수동으로 트리거해야 합니다. 명령줄 인수 --bake-lightmaps
가 있거나 환경 변수 QT_QUICK3D_BAKE_LIGHTMAPS
가 1
(또는 0이 아닌 다른 값)으로 설정되어 있으면 엔진은 베이킹 모드에서 작동하고 베이킹이 완료되면 애플리케이션을 종료합니다. 베이킹 프로세스의 단계는 디버그 출력에 인쇄된 메시지를 확인하여 확인할 수 있습니다. 그 결과 씬의 모든 베이크된 라이트맵이 포함된 바이너리 파일(기본값은lightmaps.bin
)이 현재 작업 디렉터리에 기록됩니다. 또한 전체 라이트맵과 노이즈 제거에 필요한 일부 추가 데이터가 포함된 .raw
파일이 생성됩니다. 각 라이트맵은 BakedLightmap::key 의 고유 키로 파일에서 고유하게 식별됩니다.
라이트맵 씬을 준비하려면 다음과 같은 주요 단계를 거칩니다:
- 어떤 모델이 라이트맵을 사용해야 하는지, 어떤 모델이 라이트맵에 기여해야 하는지 식별합니다. 라이트매핑된 씬의 일부인 모델은 Model::usedInBakedLighting 을 true로 설정해야 합니다. 라이트매핑되는 모델(즉, 라이트맵이 구워지는 모델)은 Model::bakedLightmap 을 활성화된 BakedLightmap 객체로 설정하여 특정 모델 객체 인스턴스를 지속적으로 식별하는 고유 키를 제공해야 합니다(이는 Qt가 영구 디스크 스토리지에서 모델 데이터를 식별하기 위해 키가 필요하기 때문입니다). 정적 지오메트리, 변환 및 머티리얼이 있는 모델만 런타임에 라이트매핑할 때 올바른 결과를 보장합니다. 일반적으로 동적으로 변경되거나 애니메이션이 적용된 위치, 회전, 스케일 등 시간이 지남에 따라 정적이지 않은 월드 트랜스폼을 유발하는 모든 요소는 모델 참여 자격을 박탈합니다. 그러나 특히 베이크된 간접 조명에만 기여하고 그 자체로는 라이트맵이 적용되지 않는 모델의 경우 예술적 요구가 이를 무시할 수 있습니다. 이러한 경우 동적 트랜스폼이 시각적으로 허용되는 경우가 많지만 이는 항상 모델과 해당 씬에 따라 달라집니다.
- 어떤 조명이 어느 정도 기여해야 하는지 파악하세요. Light::bakeMode 에서 세 가지 옵션을 제공합니다:
- 기본값인 Light.BakeModeDisabled는 모든 라이트 매핑에서 조명을 효과적으로 무시합니다.
- 씬의 전역 조명(간접 조명) 수준을 유지하면서 다른 방식으로 조명 렌더링 결과에 영향을 주지 않는 것이 유일한 목표인 경우 Light.BakeModeIndirect가 "안전한" 선택인 경우가 많습니다. 이 모드에서는 렌더러가 표준 실시간 기술을 사용하여 이 조명에 대한 디퓨즈, 스페큘러, 하늘/환경 기여도 및 그림자 매핑을 포함한 모든 조명을 계속 수행합니다. 그러나 라이트는 미리 베이크된 데이터를 사용하여 간접 조명에 기여하므로 표준 실시간 조명 계산에 영향을 받지 않는 표면을 비추게 될 수 있습니다.
- Light.BakeModeAll은 주어진 씬에 적합하다고 판단되는 디자이너의 평가에 따라 특정 조명에만 사용할 수 있는 옵션입니다. 이 모드에서는 그림자를 포함하여 라이트의 모든 기여도가 구워집니다. Qt 6.4부터 스페큘러 조명은 베이크된 조명의 일부로 지원되지 않으므로 이러한 조명에는 스페큘러 기여도가 없습니다. 반면에 레이트레이싱된 구운 그림자를 생성하고 빛에 대한 적절한 오클루전(예: 벽을 통과하지 않음)을 갖는데, 이는 빛으로 인한 모든 직접 조명 기여도가 런타임에 계산되는 대신 라이트맵 베이크 타임에 레이트레이싱되기 때문입니다. 또한 간접 조명은 BakeModeIndirect와 마찬가지로 베이크됩니다.
- 베이킹 모드에서 씬(애플리케이션)을 실행하면 라이트맵이 성공적으로 생성되는지 확인할 수 있습니다. Qt 6.4부터는 애플리케이션이 라이트맵된 장면이 가장 먼저 표시되거나
qml
툴과 같은 Qt QML 뷰어로 해당 장면을 로드할 수 있는 방식으로 구조화될 예정입니다. 베이킹이 완료되면 콘솔/디버그 출력에서 진행 상황을 추적할 수 있으며 애플리케이션이 종료됩니다. - 씬(애플리케이션)을 정상적으로 실행하여 라이트맵이 로드된 상태에서 어떻게 보이는지 확인합니다. 그런 다음 튜닝을 시작할 수 있습니다:
- 일부 모델의 경우 texelsPerUnit 을 기본값에서 더 작은 값으로 줄이는 것이 좋습니다. 이는 특히 기본 제공 프리미티브와 지오메트리가 충분히 단순한 모든 것에 적용됩니다. 이렇게 하면 라이트맵이 작아지고 베이크 시간이 빨라집니다. 처음 베이킹할 때는 기본값으로 충분하며 나중에 값을 조정할 수 있습니다.
- 라이트매퍼 오브젝트는 합리적인 기본값을 가진 수많은 설정을 노출하지만, 이 중 일부는 디자이너의 기대에 맞게 조정해야 할 가능성이 높습니다. 예를 들어 samples 및 bounces 은 간접 조명의 품질에 영향을 주도록 변경할 수 있으며 indirectLightFactor 은 간접 조명을 더 두드러지게 만들 수 있습니다. 특히 그림자 주변에 아티팩트가 발생하는 경우 bias 을 미세 조정할 수 있습니다.
- 라이트맵 생성 시 노이즈 제거는 필수입니다. 간접 조명은 경로 추적을 사용하여 계산되며, 사용된 samples 의 수에 따라 노이즈가 있는 이미지를 생성합니다. 샘플 수를 늘리면 노이즈가 줄어들지만 라이트맵을 생성하는 데 필요한 시간이 늘어납니다. 샘플 수에 관계없이 바이너리 파일에 저장된 32비트 RGBA 부동 소수점 이미지인 생성된 라이트맵에서 노이즈 제거기를 실행하는 것이 거의 항상 합리적입니다.
Qt 6.5부터 런타임 솔루션은 DebugView 을 통해 대화형으로 제공됩니다. 이제 도구 아래에 누르면 베이킹 프로세스를 트리거하는 버튼이 있습니다. 현재 프로세스를 보여주는 창이 나타납니다. 취소 버튼을 누르거나 이 창을 닫으면 취소할 수 있습니다. 완료되면 라이트맵 바이너리를 현재 디렉토리에 씁니다.
노이즈 제거
아래는 256개 samples 와 최대 3개 bounces 로 베이크된 라이트맵을 사용하여 먼저 렌더링한 코넬 박스 씬의 예시입니다. 두 번째 예제에서는 생성된 이미지 파일에 노이즈를 제거했으며, 노이즈가 대부분 제거되어 결과가 훨씬 좋아 보입니다.
원본
노이즈 제거
노이즈 제거는 베이크된 모든 라이트맵에서 자동으로 수행됩니다. 작업 디렉토리에 기존에 베이크된 .raw
라이트맵 파일이 있는 경우 DebugView 에서 Denoise
버튼을 클릭하여 노이즈 제거만 수행할 수도 있습니다. --denoise-lightmaps
인수를 사용하여 애플리케이션을 호출하여 노이즈 제거를 수행할 수도 있습니다. 노이즈 제거 강도를 조정하려면 denoiseSigma 프로퍼티를 사용할 수 있습니다.
라이트맵 UV
라이트맵 UV 좌표는 일반 텍스처링과 동일한 UV 데이터를 사용하지 않습니다. 라이트맵으로 렌더링할 때 렌더러는 라이트맵을 샘플링할 때 UV0 또는 UV1 데이터를 사용하지 않습니다. 대신 메시에는 라이트매핑의 목적에 적합한 방식으로 배치된 UV 차트가 포함된 추가 전용 UV 채널이 있습니다. 여기에는 중첩을 피하고 적절한 곳에 패딩을 적용하는 것이 포함됩니다. 일반 UV 데이터의 경우 이러한 요구 사항이 없으며, 두 개 이상의 버텍스에 동일한 U 및 V 좌표를 사용하는 것이 좋습니다.
적절한 UV 세트를 생성하는 과정을 라이트맵 UV 언래핑이라고 합니다. Qt는 라이트맵을 베이킹할 때 이 작업을 수행하고 결과 메시를 라이트맵 파일에 저장하여 호환 가능한 메시가 항상 생성된 라이트맵에 로드되고 사용되도록 합니다. 즉, 모델이 항상 베이크된 조명을 사용하는 경우 소스 메시 파일을 애플리케이션과 함께 제공할 필요가 없습니다.
라이트맵 텍스처 크기
모든 서브메시를 포함한 각 모델에 대해 라이트맵 베이킹 프로세스는 라이트맵 UV 생성 단계에서 적절한 라이트맵 텍스처 크기를 결정합니다. 이는 품질, 성능 및 리소스 사용량(디스크 및 메모리 모두)에 영향을 미칩니다.
특히 복잡도가 중간에서 높은 모델의 경우 기본값이 적합하며 조정할 필요가 없는 경우가 많습니다.
그러나 매우 단순한 모델의 경우 라이트맵 크기가 작아도 시각적으로 보기 좋은 결과를 얻을 수 있고 에셋(라이트맵 이미지) 크기를 줄이면 디스크 공간과 메모리를 모두 절약할 수 있으므로 수동으로 크기를 줄이는 것이 바람직할 수 있습니다. 이렇게 하려면 texelsPerUnit 을 적절히 작은 숫자로 설정합니다. 그러면 실제 라이트맵 너비와 높이는 모델의 크기와 지오메트리에 따라 텍셀 밀도를 근사화하여 texelsPerUnit 와 일치하도록 시도합니다.
값을 변경할 때는 항상 라이트맵을 다시 베이킹하고 변경된 라이트맵 크기의 효과를 평가하기 위해 결과를 시각적으로 검사해야 합니다.
런타임에 라이트맵 사용
런타임에 미리 구운 라이트맵을 사용할 때 관련된 속성 및 유형은
베이킹이 성공적으로 완료되면 명령줄 인수나 환경 변수 설정 없이 애플리케이션을 정상적으로 실행하면 생성된 라이트맵 이미지가 선택되어 올바르게 렌더링되며, 이는 라이트맵이 먼저 베이크되기 전에는 불가능합니다. 원하는 경우 애플리케이션에서 다른 위치에 배치하거나 Qt 리소스 시스템을 통해 실행 파일의 일부로 전송할 수 있습니다. 이는 source 속성으로 활성화할 수 있습니다.
위의 구와 네 개의 직사각형이 있는 예제 코드를 예로 들면, 베이킹 프로세스는 모든 베이크된 메시와 라이트맵을 포함하는 lightmaps.bin
파일을 생성합니다. 애플리케이션은 이 파일을 엔진에서 찾을 수 있도록 source 에 지정된 위치로 전송해야 합니다.
Qt Quick 3D - 베이크된 라이트맵 예시도 참고하세요.
© 2025 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.