diff --git a/Flax.flaxproj b/Flax.flaxproj
index 207a27b66..fadf436c3 100644
--- a/Flax.flaxproj
+++ b/Flax.flaxproj
@@ -4,7 +4,7 @@
"Major": 1,
"Minor": 13,
"Revision": 0,
- "Build": 7001
+ "Build": 7002
},
"Company": "Flax",
"Copyright": "Copyright (c) 2012-2026 Wojciech Figat. All rights reserved.",
diff --git a/Flax.sln.DotSettings b/Flax.sln.DotSettings
index 5a027a4d2..777ddbf8d 100644
--- a/Flax.sln.DotSettings
+++ b/Flax.sln.DotSettings
@@ -257,6 +257,7 @@
True
True
True
+ True
DisabledByUser
True
Blue
diff --git a/Source/Engine/Core/Config/GameSettings.cpp b/Source/Engine/Core/Config/GameSettings.cpp
index c75d2e8cb..b89e85012 100644
--- a/Source/Engine/Core/Config/GameSettings.cpp
+++ b/Source/Engine/Core/Config/GameSettings.cpp
@@ -44,12 +44,32 @@ public:
IMPLEMENT_ENGINE_SETTINGS_GETTER(BuildSettings, GameCooking);
#include "Engine/Content/Deprecated.h"
+
+PRAGMA_DISABLE_DEPRECATION_WARNINGS;
+
+bool GraphicsSettings::GetUeeHDRProbes() const
+{
+ return UseHDRProbes;
+}
+
void GraphicsSettings::SetUeeHDRProbes(bool value)
{
MARK_CONTENT_DEPRECATED();
- UseHDRProbes = value;
+ DefaultProbeCubemapFormat = value ? ProbeCubemapFormats::R11G11B10 : ProbeCubemapFormats::R8G8B8A8;
}
+bool GraphicsSettings::GetUseHDRProbes() const
+{
+ return UseHDRProbes;
+}
+
+void GraphicsSettings::SetUseHDRProbes(bool value)
+{
+ DefaultProbeCubemapFormat = value ? ProbeCubemapFormats::R11G11B10 : ProbeCubemapFormats::R8G8B8A8;
+}
+
+PRAGMA_ENABLE_DEPRECATION_WARNINGS;
+
void GraphicsSettings::OnDeserializing(const CallbackContext& context)
{
#if 0 // TODO: move to Linear color space as default once it's ready for production
diff --git a/Source/Engine/Core/Config/GraphicsSettings.h b/Source/Engine/Core/Config/GraphicsSettings.h
index ddf75b99e..e18814149 100644
--- a/Source/Engine/Core/Config/GraphicsSettings.h
+++ b/Source/Engine/Core/Config/GraphicsSettings.h
@@ -31,6 +31,22 @@ public:
R16G16B16A16,
};
+ ///
+ /// The environment probes cubemap texture storage formats.
+ ///
+ API_ENUM(Attributes = "EnumDisplay(EnumDisplayAttribute.FormatMode.None)")
+ enum class ProbeCubemapFormats
+ {
+ // LDR uncompressed format (32-bit per pixel).
+ R8G8B8A8,
+ // HDR uncompressed format (32-bit per pixel, no alpha).
+ R11G11B10,
+ // HDR compressed format (8-bit per pixel, no alpha). Converted into ASTC/Basis for mobile/web. Realtime probes will fallback to R11G11B10.
+ BC6,
+ // HDR compressed format (8-bit per pixel). Converted into ASTC/Basis for mobile/web. Realtime probes will fallback to R11G11B10.
+ BC7,
+ };
+
public:
///
/// Enables rendering synchronization with the refresh rate of the display device to avoid "tearing" artifacts.
@@ -87,9 +103,16 @@ public:
ProbeCubemapResolution DefaultProbeResolution = ProbeCubemapResolution::_128;
///
- /// If checked, Environment Probes will use HDR texture format. Improves quality in very bright scenes at cost of higher memory usage.
+ /// Environment Probes texture storage format. Controls the quality fo reflections and memory usage of probes data.
///
API_FIELD(Attributes="EditorOrder(1502), EditorDisplay(\"Quality\")")
+ ProbeCubemapFormats DefaultProbeCubemapFormat = ProbeCubemapFormats::BC6;
+
+ ///
+ /// If checked, Environment Probes will use HDR texture format. Improves quality in very bright scenes at cost of higher memory usage.
+ /// [Deprecated in v1.13]
+ ///
+ DEPRECATED("Use DefaultProbeCubemapFormat instead.")
bool UseHDRProbes = false;
///
@@ -175,8 +198,10 @@ private:
/// Renamed UeeHDRProbes into UseHDRProbes
/// [Deprecated on 12.10.2022, expires on 12.10.2024]
///
- API_PROPERTY(Attributes="Serialize, Obsolete, NoUndo") DEPRECATED("Use UseHDRProbes instead.") bool GetUeeHDRProbes() const { return UseHDRProbes; }
- API_PROPERTY(Attributes="Serialize, Obsolete, NoUndo") DEPRECATED("Use UseHDRProbes instead.") void SetUeeHDRProbes(bool value);
+ API_PROPERTY(Attributes="Serialize, Obsolete, NoUndo") DEPRECATED("Use DefaultProbeCubemapFormat instead.") bool GetUeeHDRProbes() const;
+ API_PROPERTY(Attributes="Serialize, Obsolete, NoUndo") DEPRECATED("Use DefaultProbeCubemapFormat instead.") void SetUeeHDRProbes(bool value);
+ API_PROPERTY(Attributes="Serialize, Obsolete, NoUndo") DEPRECATED("Use DefaultProbeCubemapFormat instead.") bool GetUseHDRProbes() const;
+ API_PROPERTY(Attributes="Serialize, Obsolete, NoUndo") DEPRECATED("Use DefaultProbeCubemapFormat instead.") void SetUseHDRProbes(bool value);
API_FUNCTION(Attributes="OnDeserializing", Hidden) void OnDeserializing(const CallbackContext& context);
public:
diff --git a/Source/Engine/Platform/SettingsBase.cs b/Source/Engine/Platform/SettingsBase.cs
index 18de538eb..d1a82d660 100644
--- a/Source/Engine/Platform/SettingsBase.cs
+++ b/Source/Engine/Platform/SettingsBase.cs
@@ -25,6 +25,17 @@ namespace FlaxEditor.Content.Settings
set => UseHDRProbes = value;
}
+ ///
+ /// Use DefaultProbeCubemapFormat instead
+ /// [Deprecated in v1.13]
+ ///
+ [Serialize, Obsolete, NoUndo]
+ private bool UseHDRProbes
+ {
+ get => UseHDRProbes;
+ set => DefaultProbeCubemapFormat = value ? ProbeCubemapFormats.R11G11B10 : ProbeCubemapFormats.R8G8B8A8;
+ }
+
///
/// Initializes a new instance of the .
///
diff --git a/Source/Engine/Renderer/ProbesRenderer.cpp b/Source/Engine/Renderer/ProbesRenderer.cpp
index 5ed2af5d9..aa5a7f559 100644
--- a/Source/Engine/Renderer/ProbesRenderer.cpp
+++ b/Source/Engine/Renderer/ProbesRenderer.cpp
@@ -25,6 +25,7 @@
#include "Engine/Graphics/Textures/TextureData.h"
#include "Engine/Graphics/RenderTask.h"
#include "Engine/Scripting/ScriptingObjectReference.h"
+#include "Engine/Tools/TextureTool/TextureTool.h"
#include "Engine/Threading/ThreadPoolTask.h"
// Amount of frames to wait for data from probe update job
@@ -46,6 +47,7 @@ struct ProbeEntry
bool UseTextureData() const;
int32 GetResolution() const;
PixelFormat GetFormat() const;
+ PixelFormat GetStorageFormat() const;
};
// Custom task called after downloading probe texture data to save it.
@@ -70,16 +72,29 @@ public:
bool Run() override
{
+ // Compress texture data if needed
+ TextureData* data = &_data;
+#if COMPILE_WITH_TEXTURE_TOOL
+ TextureData tmpData;
+ PixelFormat storageFormat = _entry.GetStorageFormat();
+ if (storageFormat != _data.Format)
+ {
+ if (TextureTool::Convert(tmpData, _data, storageFormat))
+ return true;
+ data = &tmpData;
+ }
+#endif
+
Actor* actor = _entry.Actor.Get();
if (_entry.Type == ProbeEntry::Types::EnvProbe)
{
if (actor)
- ((EnvironmentProbe*)actor)->SetProbeData(_data);
+ ((EnvironmentProbe*)actor)->SetProbeData(*data);
}
else if (_entry.Type == ProbeEntry::Types::SkyLight)
{
if (actor)
- ((SkyLight*)actor)->SetProbeData(_data);
+ ((SkyLight*)actor)->SetProbeData(*data);
}
else
{
@@ -202,7 +217,35 @@ int32 ProbeEntry::GetResolution() const
PixelFormat ProbeEntry::GetFormat() const
{
- return GraphicsSettings::Get()->UseHDRProbes ? PixelFormat::R11G11B10_Float : PixelFormat::R8G8B8A8_UNorm;
+ // Return render format (storage can be compressed during importing, realtime probes use uncompressed)
+ switch (GraphicsSettings::Get()->DefaultProbeCubemapFormat)
+ {
+ case GraphicsSettings::ProbeCubemapFormats::R8G8B8A8:
+ return PixelFormat::R8G8B8A8_UNorm;
+ case GraphicsSettings::ProbeCubemapFormats::R11G11B10:
+ case GraphicsSettings::ProbeCubemapFormats::BC6:
+ case GraphicsSettings::ProbeCubemapFormats::BC7:
+ return PixelFormat::R11G11B10_Float;
+ default:
+ return PixelFormat::Unknown;
+ }
+}
+
+PixelFormat ProbeEntry::GetStorageFormat() const
+{
+ switch (GraphicsSettings::Get()->DefaultProbeCubemapFormat)
+ {
+ case GraphicsSettings::ProbeCubemapFormats::R8G8B8A8:
+ return PixelFormat::R8G8B8A8_UNorm;
+ case GraphicsSettings::ProbeCubemapFormats::R11G11B10:
+ return PixelFormat::R11G11B10_Float;
+ case GraphicsSettings::ProbeCubemapFormats::BC6:
+ return PixelFormat::BC6H_Uf16;
+ case GraphicsSettings::ProbeCubemapFormats::BC7:
+ return PixelFormat::BC7_UNorm;
+ default:
+ return PixelFormat::Unknown;
+ }
}
bool ProbesRendererService::LazyInit()
diff --git a/Source/Engine/Renderer/Renderer.Build.cs b/Source/Engine/Renderer/Renderer.Build.cs
index 2f5a5008a..c8952c2c5 100644
--- a/Source/Engine/Renderer/Renderer.Build.cs
+++ b/Source/Engine/Renderer/Renderer.Build.cs
@@ -15,5 +15,9 @@ public class Renderer : EngineModule
options.PrivateDependencies.Add("Graphics");
options.PrivateDependencies.Add("Content");
+ if (options.Target.IsEditor)
+ {
+ options.PrivateDependencies.Add("TextureTool");
+ }
}
}