이 페이지에서

Qt Quick 3D - 볼륨 포그 확장 기능 예제

렌더 확장 기능에서 볼륨 안개를 구현하는 방법을 보여줍니다.

빨강, 초록, 파랑 색상의 볼륨 조명 빔이 비추는 둥근 계단식 무대 위에 서 있는 나뭇가지가 벗겨진 나무와, 조명, 안개, 그림자를 조절할 수 있는 설정 패널

개요

이 예제는 볼륨 포그를 Qt Quick 3D render extension 의 확장 기능으로 구현하며, 해당 확장 기능을 자신의 프로젝트에서 재사용하는 방법을 보여줍니다.

이 확장 기능은 카메라 프러스텀을 프러스텀에 정렬된 복셀( froxels)로 구성된 3D 그리드로 분할하고, 컴퓨트 셰이더를 사용하여 각 셀에서 카메라 쪽으로 산란되는 빛을 누적합니다. 그런 다음 포스트 프로세싱 효과를 통해 그 결과를 렌더링된 프레임에 합성합니다.

조작법

마우스를 드래그하여 카메라를 씬 주위로 회전시킬 수 있습니다. 설정 패널을 사용하여 조명, 안개, 포스트 프로세싱 및 그림자 설정을 변경할 수 있습니다.

구현

참고: 이 확장 기능은 컴퓨트 셰이더를 사용하여 프로셀 그리드에 빛을 주입하므로, 컴퓨트 셰이더를 지원하는 그래픽 API 및 하드웨어가 필요합니다. OpenGL 4.3 이전 버전과 OpenGL ES 3.1 이전 버전은 컴퓨트 기능을 지원하지 않습니다. 자세한 내용은 QRhi::Compute 를 참조하십시오.

VolumetricFogExtension 타입은 볼륨 안개 확장 기능을 구현합니다. 이 타입은 별도의 VFExtension 하위 프로젝트에 포함되어 있으므로, 수정 없이 자신의 프로젝트에 추가할 수 있습니다.

VolumetricFogExtension 에 다음 속성을 설정하십시오:

VolumetricFogExtension {
    id: froxelExtension
    froxelWidth: 160
    froxelHeight: 96
    froxelDepth: 96
    nearPlane: 1.0
    farPlane: 4000.0
    fogVolumes: [ fogSphere ]

    iesTexture: settings.iesLights ? iesAtlasTexture : null
    iesCount: iesTextureData.sources.length
    iesLightProfiles: [
        IESLightProfileIndex { light: pinkSpot; index: settings.iesLightIndex; intensity: 0.5}
    ]
}

froxelWidth, froxelHeight 및 froxelDepth 속성은 컴퓨트 셰이더가 채우는 프로셀 그리드의 해상도를 정의합니다. 해상도가 높을수록 빛의 산란이 더 세밀해지지만, GPU 메모리와 컴퓨트 시간이 더 많이 소모됩니다.

nearPlane 및 farPlane 속성은 볼륨 효과의 적용 깊이 범위를 정의합니다. 이 값들을 PerspectiveCamera 의 클립 거리와 일치시켜야 합니다.

fogVolumes 속성은 씬 내에서 안개가 나타나는 위치를 정의하는 Fog3DVolume 노드 목록을 포함합니다.

IES 광원 프로파일

IES(Illuminating Engineering Society)의 광도 프로파일은 스포트라이트의 각도별 광 분포를 형성합니다. ` iesTexture ` 속성은 ` IESTextureData ` 객체에서 데이터를 가져오는 ` Texture `를 입력으로 받습니다. 해당 객체는 ` .ies ` 파일을 파싱하여 2D 아틀라스 텍스처로 압축합니다. ` iesCount ` 속성은 아틀라스에 포함된 프로파일 수를 지정하며, ` iesLightProfiles `는 ` IESLightProfileIndex ` 객체를 통해 개별 조명을 프로파일 인덱스에 매핑합니다.

Texture {
    id: iesAtlasTexture
    textureData: IESTextureData {
        id: iesTextureData
        sources: [
            "qrc:/assets/l0.ies",
            "qrc:/assets/l1.ies",
            "qrc:/assets/l2.ies",
            "qrc:/assets/l3.ies",
            "qrc:/assets/l4.ies",
            "qrc:/assets/l5.ies",
        ]
    }

    tilingModeHorizontal: Texture.ClampToEdge
    tilingModeVertical: Texture.ClampToEdge
    minFilter: Texture.Linear
    magFilter: Texture.Linear
    generateMipmaps: false
}
View3D에 확장 기능 연결

View3D 의 ‘ extensions ’ 목록에 확장 기능을 추가합니다. 그러면 렌더 파이프라인이 프레임당 한 번씩 확장 기능의 컴퓨트 셰이더를 호출합니다:

View3D {
    extensions: [ froxelExtension ]
}
안개 볼륨

Fog3DVolume 노드는 씬 내의 안개 영역을 정의합니다. type 속성은 두 가지 모양( Fog3DVolume.Sphere 또는 Fog3DVolume.Box) 중 하나를 선택하며, extents 속성은 경계 치수를 설정합니다. color 및 density 속성은 외관을 제어합니다.

매 프레임마다 ` noiseOffset ` 값을 증가시키면 노이즈가 애니메이션됩니다. 높이에 따라 밀도가 점차 감소하도록 하려면 ` heightEnabled `을 ` true `로 설정하고 ` leastIntenseY`, ` mostIntenseY`, ` heightCurve`을 조정하십시오:

Fog3DVolume {
    id: fogSphere
    type: Fog3DVolume.Sphere
    extents: Qt.vector3d(5000, 5000, 5000)
    color: settings.fogVolumeColor
    density: settings.fogVolumeDensity
    noiseOffset: Qt.vector3d(baseNode.time * 0.1 * settings.fogSpeed,
                             baseNode.time * 0.02 * settings.fogSpeed,
                             baseNode.time * 0.01 * settings.fogSpeed)
    noiseScale: settings.fogVolumeNoiseScale
    heightEnabled: settings.fogVolumeHeightEnabled
    leastIntenseY: settings.fogVolumeHeightLeastY
    mostIntenseY: settings.fogVolumeHeightMostY
    heightCurve: settings.fogVolumeHeightCurve
}
VolumetricFogEffect

이 확장 기능은 읽기 전용 froxelTexture 속성을 통해 결과를 노출하며, 이 속성은 각 프로셀(froxel)에 대한 누적된 빛 산란 데이터를 포함하는 3D RGBA 텍스처입니다. 해당 텍스처를 활용하려면 ExtendedSceneEnvironment 에 VolumetricFogEffect 후처리 효과를 추가하십시오. 이 효과는 프로셀 텍스처를 따라 레이 마칭을 수행하고, 렌더링된 프레임에 볼륨광을 합성합니다:

effects: [
    VolumetricFogEffect {
        froxelTexture: froxelExtension.froxelTexture
        cameraPosition: camera.scenePosition
        cameraForward: camera.forward
        invViewMatrix: camera.sceneTransform
        marchSteps: froxelExtension.froxelDepth
        nearPlane: froxelExtension.nearPlane
        farPlane: froxelExtension.farPlane
        frameBaseJitter: se.temporalAAEnabled &&
                         se.temporalAAMode === SceneEnvironment.TAAMotionVector &&
                         se.antialiasingMode !== SceneEnvironment.MSAA ? 1.0 : 0.0
        jitterIntensity: settings.jitterIntensity
    }
]

marchSteps 속성은 레이 마칭 단계 수를 제어합니다. 이 값을 froxelDepth 과 일치시켜야 합니다. frameBaseJitter 및 jitterIntensity 속성은 시간적 디더링을 활성화하며, 이는 장면에서 시간적 앤티앨리어싱을 함께 사용할 때 발생하는 밴딩 아티팩트를 줄여줍니다.

자신의 프로젝트에서 확장 기능 재사용하기

VFExtension 하위 프로젝트는 독립적인 QML 모듈로 빌드됩니다. 다른 프로젝트에서 이를 사용하려면 디렉터리를 복사하고, ` add_subdirectory()`을 사용하여 추가한 다음, 라이브러리를 대상 프로젝트에 링크하십시오:

add_subdirectory(VFExtension)

target_link_libraries(myapp PRIVATE VFExtension)

그런 다음 QML에서 모듈을 임포트합니다:

import VFExtension

참고: 이 확장 기능에는 비공개 Qt Quick 3D 헤더가 포함되어 있으며, Qt6::Quick3DPrivate 에 링크되어 있습니다. 비공개 API는 소스 또는 바이너리 호환성을 보장하지 않으므로, 더 새로운 Qt 버전으로 전환할 때 확장 기능을 수정해야 할 수 있습니다.

code.qt.io의 예제 프로젝트

또한 Qt Quick 3D - Stencil Outline Extension 예제, Qt Quick 3D - 간단한 안개(Fog) 예제, 그리고 Qt Quick 3D 의 사용자 정의 렌더 패스를참조하십시오 .

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