このページでは

Qt Quick 3D - ボリュームフォグ拡張機能の例

レンダリング拡張機能でヴォリュメトリックフォグを実装する方法を解説します。

赤、緑、青のボリュームライトビームに照らされた、円形の段状ステージの上に立つ葉の落ちた木。ライト、フォグ、シャドウの設定パネルがある。

概要

このサンプルでは、Qt Quick 3Drender extension としてボリュームフォグを実装し、独自のプロジェクトでこの拡張機能を再利用する方法を紹介しています。

この拡張機能は、カメラの視錐台を、視錐台に整列したボクセルである「フロクセル」の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)の測光プロファイルは、スポットライトの角度別光分布を形成します。「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 リストにこの拡張機能を追加します。これにより、レンダリングパイプラインは1フレームごとに1回、拡張機能のコンピュートシェーダーを呼び出します:

View3D {
    extensions: [ froxelExtension ]
}
フォグボリューム

Fog3DVolume ノードは、シーン内のフォグ領域を定義します。type プロパティでは、Fog3DVolume.Sphere またはFog3DVolume.Box の2つの形状のいずれかを選択し、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 プロパティを通じて結果を公開します。これは、各フロクセルに対する蓄積された光散乱データを保持する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 Example」、「Qt Quick 3D - Simple Fog Example」、および「 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.