diff --git a/code/World/Editor/IrradianceGridAsset.cpp b/code/World/Editor/IrradianceGridAsset.cpp
index 94b0d7aa26..75b98bf2fa 100644
--- a/code/World/Editor/IrradianceGridAsset.cpp
+++ b/code/World/Editor/IrradianceGridAsset.cpp
@@ -1,6 +1,6 @@
/*
* TRAKTOR
- * Copyright (c) 2022 Anders Pistol.
+ * Copyright (c) 2022-2024 Anders Pistol.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -14,7 +14,7 @@
namespace traktor::world
{
-T_IMPLEMENT_RTTI_EDIT_CLASS(L"traktor.world.IrradianceGridAsset", 2, IrradianceGridAsset, editor::Asset)
+T_IMPLEMENT_RTTI_EDIT_CLASS(L"traktor.world.IrradianceGridAsset", 3, IrradianceGridAsset, editor::Asset)
void IrradianceGridAsset::serialize(ISerializer& s)
{
@@ -23,6 +23,9 @@ void IrradianceGridAsset::serialize(ISerializer& s)
if (s.getVersion< IrradianceGridAsset >() >= 1)
s >> Member< float >(L"intensity", m_intensity, AttributeUnit(UnitType::Percent));
+ if (s.getVersion< IrradianceGridAsset >() >= 3)
+ s >> Member< float >(L"saturation", m_saturation, AttributeUnit(UnitType::Percent));
+
if (s.getVersion< IrradianceGridAsset >() >= 2)
s >> Member< bool >(L"cancelSun", m_cancelSun);
}
diff --git a/code/World/Editor/IrradianceGridAsset.h b/code/World/Editor/IrradianceGridAsset.h
index d9bac1d6f0..30d36722d7 100644
--- a/code/World/Editor/IrradianceGridAsset.h
+++ b/code/World/Editor/IrradianceGridAsset.h
@@ -1,6 +1,6 @@
/*
* TRAKTOR
- * Copyright (c) 2022 Anders Pistol.
+ * Copyright (c) 2022-2024 Anders Pistol.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -33,10 +33,13 @@ class T_DLLCLASS IrradianceGridAsset : public editor::Asset
float getIntensity() const { return m_intensity; }
+ float getSaturation() const { return m_saturation; }
+
bool shouldCancelSun() const { return m_cancelSun; }
private:
float m_intensity = 1.0f;
+ float m_saturation = 1.0f;
bool m_cancelSun = true;
};
diff --git a/code/World/Editor/IrradianceGridPipeline.cpp b/code/World/Editor/IrradianceGridPipeline.cpp
index 580e7fbf17..12b7b70d93 100644
--- a/code/World/Editor/IrradianceGridPipeline.cpp
+++ b/code/World/Editor/IrradianceGridPipeline.cpp
@@ -1,6 +1,6 @@
/*
* TRAKTOR
- * Copyright (c) 2022-2023 Anders Pistol.
+ * Copyright (c) 2022-2024 Anders Pistol.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -193,9 +193,12 @@ bool IrradianceGridPipeline::buildOutput(
{
// No asset specified; use dynamic sky.
const Scalar intensity(asset->getIntensity());
+ const Scalar saturation(asset->getSaturation());
WrappedSHFunction shFunction([&] (const Vector4& unit) -> Vector4 {
Color4f cl(0.0f, 0.0f, 0.0f, 0.0f);
+
+ // Sample over hemisphere.
for (int32_t i = 0; i < 1000; ++i)
{
const Vector2 uv = Quasirandom::hammersley(i, 1000);
@@ -213,6 +216,11 @@ bool IrradianceGridPipeline::buildOutput(
col += clamp((0.1_simd - direction.y()) * 10.0_simd, 0.0_simd, 1.0_simd) * Vector4(0.0f, 0.1f, 0.2f, 0.0f);
cl += Color4f(col * w);
}
+
+ // Apply saturation.
+ const Scalar bw = dot3(cl, Vector4(1.0f, 1.0f, 1.0f)) / 3.0_simd;
+ cl = Color4f(lerp(Vector4(bw, bw, bw, 0.0f), cl, saturation));
+
return (cl * intensity * 2.0_simd) / 1000.0_simd;
});
diff --git a/data/Source/System/Shaders/Modules/PBR.xdi b/data/Source/System/Shaders/Modules/PBR.xdi
new file mode 100644
index 0000000000..6e588e0b07
--- /dev/null
+++ b/data/Source/System/Shaders/Modules/PBR.xdi
@@ -0,0 +1,97 @@
+
+
diff --git a/data/Source/System/Shaders/Modules/PBR.xdm b/data/Source/System/Shaders/Modules/PBR.xdm
new file mode 100644
index 0000000000..709a524801
--- /dev/null
+++ b/data/Source/System/Shaders/Modules/PBR.xdm
@@ -0,0 +1,6 @@
+
+
diff --git a/data/Source/System/Weather/Sky/Sky.xdi b/data/Source/System/Weather/Sky/Sky.xdi
index 084c4ede3d..e9c903450b 100644
--- a/data/Source/System/Weather/Sky/Sky.xdi
+++ b/data/Source/System/Weather/Sky/Sky.xdi
@@ -1,6 +1,7 @@
-