aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Strømme <christian.stromme@qt.io>2024-04-10 15:15:49 +0200
committerTim Jenssen <tim.jenssen@qt.io>2024-04-24 15:24:35 +0000
commitcd7e89070579dd220fbc64c48f138585e55b6b8d (patch)
treeff72f11bb6ef9d4319eb1574088ce15c29af0338
parentc8bcda86bde2c9bcad8718244f5894bc6712ff98 (diff)
Enable usage of the IBL probe exposure with the ExtendedSceneEnvironment6.7-experimental
Since the ExtendedSceneEnvironment is not using the built-in tonemapping of the engine but instead uses its own custom tonemapping code, the internal tonemapping, and therefore the exposure, was disabled. With this change the exposure and tonemapping is decoupled when used with custom tonemapping code (internal only), which allows the ExtendedSceneEnvironment to force the exposure values to be added to the output. Fixes: QTBUG-123846 Change-Id: I00cbdd85f4e3d3d58afff7899a5ca2ce61365a55 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
-rw-r--r--examples/quick3d/sceneeffects/SettingsPage.qml13
-rw-r--r--src/quick3d/qquick3dscenerenderer_p.h8
-rw-r--r--src/runtimerender/CMakeLists.txt35
-rw-r--r--src/runtimerender/graphobjects/qssgrenderlayer_p.h5
-rw-r--r--src/runtimerender/qssgrendershadercache.cpp4
-rw-r--r--src/runtimerender/qssgrendershadercache_p.h3
-rw-r--r--src/runtimerender/rendererimpl/qssglayerrenderdata.cpp3
-rw-r--r--src/runtimerender/rendererimpl/qssglayerrenderdata_p.h2
-rw-r--r--src/runtimerender/rendererimpl/qssgrendererimplshaders_rhi.cpp7
-rw-r--r--src/runtimerender/rendererimpl/qssgrenderpass.cpp3
-rw-r--r--src/runtimerender/res/effectlib/tonemapping.glsllib8
-rw-r--r--tests/baseline/data/view3d/SceneEffecsExposure.qml107
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
+ }
+ }
+}