diff options
-rw-r--r-- | examples/quick3d/sceneeffects/SettingsPage.qml | 13 | ||||
-rw-r--r-- | src/quick3d/qquick3dscenerenderer_p.h | 8 | ||||
-rw-r--r-- | src/runtimerender/CMakeLists.txt | 35 | ||||
-rw-r--r-- | src/runtimerender/graphobjects/qssgrenderlayer_p.h | 5 | ||||
-rw-r--r-- | src/runtimerender/qssgrendershadercache.cpp | 4 | ||||
-rw-r--r-- | src/runtimerender/qssgrendershadercache_p.h | 3 | ||||
-rw-r--r-- | src/runtimerender/rendererimpl/qssglayerrenderdata.cpp | 3 | ||||
-rw-r--r-- | src/runtimerender/rendererimpl/qssglayerrenderdata_p.h | 2 | ||||
-rw-r--r-- | src/runtimerender/rendererimpl/qssgrendererimplshaders_rhi.cpp | 7 | ||||
-rw-r--r-- | src/runtimerender/rendererimpl/qssgrenderpass.cpp | 3 | ||||
-rw-r--r-- | src/runtimerender/res/effectlib/tonemapping.glsllib | 8 | ||||
-rw-r--r-- | tests/baseline/data/view3d/SceneEffecsExposure.qml | 107 |
12 files changed, 189 insertions, 9 deletions
diff --git a/examples/quick3d/sceneeffects/SettingsPage.qml b/examples/quick3d/sceneeffects/SettingsPage.qml index 27afe9f7..1867951b 100644 --- a/examples/quick3d/sceneeffects/SettingsPage.qml +++ b/examples/quick3d/sceneeffects/SettingsPage.qml @@ -207,6 +207,19 @@ Page { } Label { + text: "Probe Exposure (" + (toolPage.sceneEnvironment.probeExposure).toFixed(2) + ")" + Layout.fillWidth: true + } + Slider { + Layout.fillWidth: true + from: 0.0 + to: 10.0 + value: toolPage.sceneEnvironment.probeExposure + onValueChanged: + toolPage.sceneEnvironment.probeExposure = value + } + + Label { enabled: !(toolPage.sceneEnvironment.tonemapMode === SceneEnvironment.TonemapModeLinear || toolPage.sceneEnvironment.tonemapMode === SceneEnvironment.TonemapModeNone) text: "White Point (" + (toolPage.sceneEnvironment.whitePoint).toFixed(2) + ")" Layout.fillWidth: true diff --git a/src/quick3d/qquick3dscenerenderer_p.h b/src/quick3d/qquick3dscenerenderer_p.h index 33bafdd0..c22c08ec 100644 --- a/src/quick3d/qquick3dscenerenderer_p.h +++ b/src/quick3d/qquick3dscenerenderer_p.h @@ -48,8 +48,12 @@ public: static QSSGRenderLayer::TonemapMode getTonemapMode(const QQuick3DSceneEnvironment &environment) { - return environment.useBuiltinTonemapper() ? QSSGRenderLayer::TonemapMode(environment.tonemapMode()) - : QSSGRenderLayer::TonemapMode::None; + if (environment.useBuiltinTonemapper()) + return QSSGRenderLayer::TonemapMode(environment.tonemapMode()); + + // Special case for the extend scene environment... + return (environment.tonemapMode() != QQuick3DSceneEnvironment::QQuick3DEnvironmentTonemapModes::TonemapModeNone) ? QSSGRenderLayer::TonemapMode::Custom + : QSSGRenderLayer::TonemapMode::None; } protected: diff --git a/src/runtimerender/CMakeLists.txt b/src/runtimerender/CMakeLists.txt index f05d78c5..0c194fcc 100644 --- a/src/runtimerender/CMakeLists.txt +++ b/src/runtimerender/CMakeLists.txt @@ -332,6 +332,41 @@ qt_internal_add_shaders(Quick3DRuntimeRender "res_shaders_skybox_rgbe_none" DEFINES QSSG_ENABLE_RGBE_LIGHT_PROBE=1 ) +qt_internal_add_shaders(Quick3DRuntimeRender "res_shaders_skybox_hdr_custom" + SILENT + PRECOMPILE + OPTIMIZED + MULTIVIEW + GLSL "300es,150" + PREFIX + "/" + FILES + res/rhishaders/skybox.vert + res/rhishaders/skybox.frag + OUTPUTS + res/rhishaders/skybox_hdr_custom.vert.qsb + res/rhishaders/skybox_hdr_custom.frag.qsb + DEFINES + QSSG_FORCE_IBL_EXPOSURE=1 +) +qt_internal_add_shaders(Quick3DRuntimeRender "res_shaders_skybox_rgbe_custom" + SILENT + PRECOMPILE + OPTIMIZED + MULTIVIEW + GLSL "300es,150" + PREFIX + "/" + FILES + res/rhishaders/skybox.vert + res/rhishaders/skybox.frag + OUTPUTS + res/rhishaders/skybox_rgbe_custom.vert.qsb + res/rhishaders/skybox_rgbe_custom.frag.qsb + DEFINES + QSSG_ENABLE_RGBE_LIGHT_PROBE=1 + QSSG_FORCE_IBL_EXPOSURE=1 +) qt_internal_add_shaders(Quick3DRuntimeRender "res_shaders_skybox_hdr_linear" SILENT PRECOMPILE diff --git a/src/runtimerender/graphobjects/qssgrenderlayer_p.h b/src/runtimerender/graphobjects/qssgrenderlayer_p.h index 33a223fd..73cefdd8 100644 --- a/src/runtimerender/graphobjects/qssgrenderlayer_p.h +++ b/src/runtimerender/graphobjects/qssgrenderlayer_p.h @@ -90,9 +90,10 @@ struct Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRenderLayer : public QSSGRenderNode Linear, Aces, HejlDawson, - Filmic + Filmic, + Custom }; - static size_t constexpr TonemapModeCount = 5; + static size_t constexpr TonemapModeCount = 6; enum class LayerFlag { diff --git a/src/runtimerender/qssgrendershadercache.cpp b/src/runtimerender/qssgrendershadercache.cpp index b5a2e827..d022c083 100644 --- a/src/runtimerender/qssgrendershadercache.cpp +++ b/src/runtimerender/qssgrendershadercache.cpp @@ -75,7 +75,9 @@ static constexpr DefineEntry DefineTable[] { { "QSSG_ENABLE_OPAQUE_DEPTH_PRE_PASS", QSSGShaderFeatures::Feature::OpaqueDepthPrePass }, { "QSSG_ENABLE_REFLECTION_PROBE", QSSGShaderFeatures::Feature::ReflectionProbe }, { "QSSG_REDUCE_MAX_NUM_LIGHTS", QSSGShaderFeatures::Feature::ReduceMaxNumLights }, - { "QSSG_ENABLE_LIGHTMAP", QSSGShaderFeatures::Feature::Lightmap } + { "QSSG_ENABLE_LIGHTMAP", QSSGShaderFeatures::Feature::Lightmap }, + { "QSSG_DISABLE_MULTIVIEW", QSSGShaderFeatures::Feature::DisableMultiView }, + { "QSSG_FORCE_IBL_EXPOSURE", QSSGShaderFeatures::Feature::ForceIblExposure } }; static_assert(std::size(DefineTable) == QSSGShaderFeatures::Count, "Missing feature define?"); diff --git a/src/runtimerender/qssgrendershadercache_p.h b/src/runtimerender/qssgrendershadercache_p.h index a19297f0..ec66e23e 100644 --- a/src/runtimerender/qssgrendershadercache_p.h +++ b/src/runtimerender/qssgrendershadercache_p.h @@ -81,6 +81,8 @@ enum class Feature : FlagType ReflectionProbe = (1 << 21) + 13, ReduceMaxNumLights = (1 << 22) + 14, Lightmap = (1 << 23) + 15, + DisableMultiView = (1 << 24) + 16, + ForceIblExposure = (1 << 25) + 17, LastFeature }; @@ -105,6 +107,7 @@ void disableTonemapping() set(Feature::AcesTonemapping, false); set(Feature::FilmicTonemapping, false); set(Feature::HejlDawsonTonemapping, false); + set(Feature::ForceIblExposure, false); } inline friend QDebug operator<<(QDebug stream, const QSSGShaderFeatures &features) diff --git a/src/runtimerender/rendererimpl/qssglayerrenderdata.cpp b/src/runtimerender/rendererimpl/qssglayerrenderdata.cpp index 62ee1e1d..691b46c8 100644 --- a/src/runtimerender/rendererimpl/qssglayerrenderdata.cpp +++ b/src/runtimerender/rendererimpl/qssglayerrenderdata.cpp @@ -2191,6 +2191,9 @@ void QSSGLayerRenderData::prepareForRender() } else { layer.lightProbe = nullptr; } + + const bool forceIblExposureValues = (features.isSet(QSSGShaderFeatures::Feature::LightProbe) && layer.tonemapMode == QSSGRenderLayer::TonemapMode::Custom); + features.set(QSSGShaderFeatures::Feature::ForceIblExposure, forceIblExposureValues); } // Gather Spatial Nodes from Render Tree diff --git a/src/runtimerender/rendererimpl/qssglayerrenderdata_p.h b/src/runtimerender/rendererimpl/qssglayerrenderdata_p.h index 7ab3e0bf..21ae3819 100644 --- a/src/runtimerender/rendererimpl/qssglayerrenderdata_p.h +++ b/src/runtimerender/rendererimpl/qssglayerrenderdata_p.h @@ -371,6 +371,8 @@ public: tonemapMode == QSSGRenderLayer::TonemapMode::HejlDawson); features.set(QSSGShaderFeatures::Feature::FilmicTonemapping, tonemapMode == QSSGRenderLayer::TonemapMode::Filmic); + features.set(QSSGShaderFeatures::Feature::ForceIblExposure, + tonemapMode == QSSGRenderLayer::TonemapMode::Custom); } QSSGPrepContextId getOrCreateExtensionContext(const QSSGRenderExtension &ext, diff --git a/src/runtimerender/rendererimpl/qssgrendererimplshaders_rhi.cpp b/src/runtimerender/rendererimpl/qssgrendererimplshaders_rhi.cpp index e014ae5b..9137f535 100644 --- a/src/runtimerender/rendererimpl/qssgrendererimplshaders_rhi.cpp +++ b/src/runtimerender/rendererimpl/qssgrendererimplshaders_rhi.cpp @@ -77,6 +77,8 @@ static inline constexpr size_t getSkyboxIndex(QSSGRenderLayer::TonemapMode tonem return 3 + (size_t(isRGBE) * QSSGRenderLayer::TonemapModeCount); case QSSGRenderLayer::TonemapMode::Filmic: return 4 + (size_t(isRGBE) * QSSGRenderLayer::TonemapModeCount); + case QSSGRenderLayer::TonemapMode::Custom: + return 5 + (size_t(isRGBE) * QSSGRenderLayer::TonemapModeCount); } Q_UNREACHABLE_RETURN(0); @@ -91,11 +93,14 @@ QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiSkyBoxShader(QSSGRende "skybox_hdr_aces", "skybox_hdr_hejldawson", "skybox_hdr_filmic", + "skybox_hdr_custom", "skybox_rgbe_none", "skybox_rgbe_linear", "skybox_rgbe_aces", "skybox_rgbe_hejldawson", - "skybox_rgbe_filmic" }; + "skybox_rgbe_filmic", + "skybox_rgbe_custom", + }; const size_t skyboxIndex = getSkyboxIndex(tonemapMode, isRGBE); return getBuiltinRhiShader(QByteArray::fromRawData(variant[skyboxIndex], std::char_traits<char>::length(variant[skyboxIndex])), m_skyBoxRhiShader[skyboxIndex]); diff --git a/src/runtimerender/rendererimpl/qssgrenderpass.cpp b/src/runtimerender/rendererimpl/qssgrenderpass.cpp index e37bba61..279292e0 100644 --- a/src/runtimerender/rendererimpl/qssgrenderpass.cpp +++ b/src/runtimerender/rendererimpl/qssgrenderpass.cpp @@ -822,7 +822,8 @@ void SkyboxPass::renderPass(QSSGRenderer &renderer) // Note: We get the shader here, as the screen map pass might modify the state of // the tonemap mode. - QSSGRenderLayer::TonemapMode tonemapMode = skipTonemapping ? QSSGRenderLayer::TonemapMode::None : layer->tonemapMode; + + QSSGRenderLayer::TonemapMode tonemapMode = skipTonemapping && (layer->tonemapMode != QSSGRenderLayer::TonemapMode::Custom) ? QSSGRenderLayer::TonemapMode::None : layer->tonemapMode; const auto &shaderCache = renderer.contextInterface()->shaderCache(); auto shaderPipeline = shaderCache->getBuiltInRhiShaders().getRhiSkyBoxShader(tonemapMode, layer->skyBoxIsRgbe8); QSSG_CHECK(shaderPipeline); diff --git a/src/runtimerender/res/effectlib/tonemapping.glsllib b/src/runtimerender/res/effectlib/tonemapping.glsllib index 23d657b5..87fe6493 100644 --- a/src/runtimerender/res/effectlib/tonemapping.glsllib +++ b/src/runtimerender/res/effectlib/tonemapping.glsllib @@ -23,6 +23,9 @@ #ifndef QSSG_ENABLE_FILMIC_TONEMAPPING #define QSSG_ENABLE_FILMIC_TONEMAPPING 0 #endif +#ifndef QSSG_FORCE_IBL_EXPOSURE +#define QSSG_FORCE_IBL_EXPOSURE 0 +#endif // The following methods are described in this article: // http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html @@ -148,10 +151,11 @@ vec4 qt_tonemap(vec4 color) vec3 qt_exposure(vec3 color, float exposure) { -#if QSSG_ENABLE_ACES_TONEMAPPING || QSSG_ENABLE_HEJLDAWSON_TONEMAPPING || QSSG_ENABLE_FILMIC_TONEMAPPING || QSSG_ENABLE_LINEAR_TONEMAPPING +#if QSSG_ENABLE_ACES_TONEMAPPING || QSSG_ENABLE_HEJLDAWSON_TONEMAPPING || QSSG_ENABLE_FILMIC_TONEMAPPING || QSSG_ENABLE_LINEAR_TONEMAPPING || QSSG_FORCE_IBL_EXPOSURE return vec3(vec3(1.0) - exp(-color * exposure)); -#endif +#else return color; +#endif } #endif // TONEMAPPPING_GLSLIB diff --git a/tests/baseline/data/view3d/SceneEffecsExposure.qml b/tests/baseline/data/view3d/SceneEffecsExposure.qml new file mode 100644 index 00000000..4b56c975 --- /dev/null +++ b/tests/baseline/data/view3d/SceneEffecsExposure.qml @@ -0,0 +1,107 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import QtQuick +import QtQuick.Layouts +import QtQuick3D +import QtQuick3D.Helpers + +Item { + id: rootItem + width: 460 + height: 460 + + Node { + id: scene + PerspectiveCamera { + id: camera + z: 100 + } + + DirectionalLight { + + } + + Model { + source: "#Sphere" + materials: [ PrincipledMaterial { + id: sphereMaterial + baseColor: "green" + metalness: 0.5 + } ] + } + } + + GridLayout { + columns: 2 + anchors.fill: parent + + View3D { + implicitHeight: rootItem.height / 2 + implicitWidth: rootItem.width / 2 + environment: ExtendedSceneEnvironment { + backgroundMode: SceneEnvironment.SkyBox + lightProbe: Texture { + source: "../shared/maps/TestEnvironment-512.hdr" + mappingMode: Texture.LightProbe + } + + probeExposure: 0 + exposure: 1.0 + } + + importScene: scene + } + + View3D { + implicitHeight: rootItem.height / 2 + implicitWidth: rootItem.width / 2 + environment: ExtendedSceneEnvironment { + backgroundMode: SceneEnvironment.SkyBox + lightProbe: Texture { + source: "../shared/maps/TestEnvironment-512.hdr" + mappingMode: Texture.LightProbe + } + + probeExposure: 10.0 + exposure: 1.0 + } + + importScene: scene + } + + View3D { + implicitHeight: rootItem.height / 2 + implicitWidth: rootItem.width / 2 + environment: ExtendedSceneEnvironment { + backgroundMode: SceneEnvironment.SkyBox + lightProbe: Texture { + source: "../shared/maps/TestEnvironment-512.hdr" + mappingMode: Texture.LightProbe + } + + probeExposure: 1.0 + exposure: 1.0 + } + + importScene: scene + } + + View3D { + implicitHeight: rootItem.height / 2 + implicitWidth: rootItem.width / 2 + environment: ExtendedSceneEnvironment { + backgroundMode: SceneEnvironment.SkyBox + lightProbe: Texture { + source: "../shared/maps/TestEnvironment-512.hdr" + mappingMode: Texture.LightProbe + } + + probeExposure: 1.0 + exposure: 10.0 + } + + importScene: scene + } + } +} |