diff --git a/Content/Shaders/BakeLightmap.flax b/Content/Shaders/BakeLightmap.flax
index e36cf49eb..ef3e02163 100644
--- a/Content/Shaders/BakeLightmap.flax
+++ b/Content/Shaders/BakeLightmap.flax
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:4df3ff78a4381534223145fefa33b7ccb9a07a8b4a996e2b7b8ffd0ededbda54
+oid sha256:18eb0ec2642a8f87ee3d4dbe7af8771b0f79f983637aee1a9e5baebce435976b
size 16284
diff --git a/Content/Shaders/Editor/LightmapUVsDensity.flax b/Content/Shaders/Editor/LightmapUVsDensity.flax
index 735187ca5..c817058f7 100644
--- a/Content/Shaders/Editor/LightmapUVsDensity.flax
+++ b/Content/Shaders/Editor/LightmapUVsDensity.flax
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:57334505aab1d6e07e8f0301e86e9e5a4aca9155f814a72ea77fd50e17ebaa23
+oid sha256:f23c12db6332866a9ac91d576575448af02e1a4e0fff20529f32911970de72e5
size 4509
diff --git a/Content/Shaders/ProbesFilter.flax b/Content/Shaders/ProbesFilter.flax
index e52d9a6e2..832091cc6 100644
--- a/Content/Shaders/ProbesFilter.flax
+++ b/Content/Shaders/ProbesFilter.flax
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:9af216fba5493159e62493e3fe82c82298f42d1551380cd5b2961e3554c39640
+oid sha256:ea8309d9ec0e373fb0e6f7bd90649a45f009ea7880ccd328cd5e0ff9f5166b4a
size 4980
diff --git a/Source/Engine/Core/Config/GraphicsSettings.cpp b/Source/Engine/Core/Config/GraphicsSettings.cpp
index 6ae8d5a4a..d10df48d2 100644
--- a/Source/Engine/Core/Config/GraphicsSettings.cpp
+++ b/Source/Engine/Core/Config/GraphicsSettings.cpp
@@ -13,7 +13,6 @@ void GraphicsSettings::Apply()
Graphics::ShadowsQuality = ShadowsQuality;
Graphics::ShadowMapsQuality = ShadowMapsQuality;
Graphics::AllowCSMBlending = AllowCSMBlending;
- Graphics::DefaultProbeResolution = (int32)DefaultProbeResolution;
Graphics::GlobalSDFQuality = GlobalSDFQuality;
Graphics::GIQuality = GIQuality;
Graphics::PostProcessSettings = PostProcessSettings;
diff --git a/Source/Engine/Core/Config/GraphicsSettings.h b/Source/Engine/Core/Config/GraphicsSettings.h
index e6ab31c3c..eab796109 100644
--- a/Source/Engine/Core/Config/GraphicsSettings.h
+++ b/Source/Engine/Core/Config/GraphicsSettings.h
@@ -64,20 +64,10 @@ public:
bool AllowCSMBlending = false;
///
- /// Default probes cubemap resolution.
+ /// Default probes cubemap resolution (use for Environment Probes, can be overriden per-actor).
///
- API_ENUM() enum class DefaultProbeResolutions
- {
- _64 = 64,
- _128 = 128,
- _256 = 256,
- _512 = 512,
- _1024 = 1024,
- _2048 = 2048,
- _4096 = 4096,
- };
- API_FIELD(Attributes = "EditorOrder(1500), DefaultValue(DefaultProbeResolutions._512), EditorDisplay(\"Quality\", \"Default Probe Resolution\")")
- DefaultProbeResolutions DefaultProbeResolution = DefaultProbeResolutions::_512;
+ API_FIELD(Attributes = "EditorOrder(1500), EditorDisplay(\"Quality\")")
+ ProbeCubemapResolution DefaultProbeResolution = ProbeCubemapResolution::_128;
///
/// If checked, enables Global SDF rendering. This can be used in materials, shaders, and particles.
diff --git a/Source/Engine/Graphics/Enums.h b/Source/Engine/Graphics/Enums.h
index dd0154ce3..9a71255d4 100644
--- a/Source/Engine/Graphics/Enums.h
+++ b/Source/Engine/Graphics/Enums.h
@@ -1082,3 +1082,26 @@ enum class ShaderFlags : uint32
};
DECLARE_ENUM_OPERATORS(ShaderFlags);
+
+///
+/// The environment probes cubemap texture resolutions.
+///
+API_ENUM() enum class ProbeCubemapResolution
+{
+ // Graphics Settings default option.
+ UseGraphicsSettings = 0,
+ // Cubemap with 32x32.
+ _32 = 32,
+ // Cubemap with 64x64.
+ _64 = 64,
+ // Cubemap with 128x128.
+ _128 = 128,
+ // Cubemap with 256x256.
+ _256 = 256,
+ // Cubemap with 512x512.
+ _512 = 512,
+ // Cubemap with 1024x1024.
+ _1024 = 1024,
+ // Cubemap with 2048x2048.
+ _2048 = 2048,
+};
diff --git a/Source/Engine/Graphics/Graphics.cpp b/Source/Engine/Graphics/Graphics.cpp
index 2d0698877..aaa5dc2d8 100644
--- a/Source/Engine/Graphics/Graphics.cpp
+++ b/Source/Engine/Graphics/Graphics.cpp
@@ -14,7 +14,6 @@ Quality Graphics::VolumetricFogQuality = Quality::High;
Quality Graphics::ShadowsQuality = Quality::Medium;
Quality Graphics::ShadowMapsQuality = Quality::Medium;
bool Graphics::AllowCSMBlending = false;
-int32 Graphics::DefaultProbeResolution = 512;
Quality Graphics::GlobalSDFQuality = Quality::High;
Quality Graphics::GIQuality = Quality::High;
PostProcessSettings Graphics::PostProcessSettings;
diff --git a/Source/Engine/Graphics/Graphics.h b/Source/Engine/Graphics/Graphics.h
index 65c80c25b..c5933cfc1 100644
--- a/Source/Engine/Graphics/Graphics.h
+++ b/Source/Engine/Graphics/Graphics.h
@@ -53,11 +53,6 @@ public:
///
API_FIELD() static bool AllowCSMBlending;
- ///
- /// Default probes cubemap resolution.
- ///
- API_FIELD() static int32 DefaultProbeResolution;
-
///
/// The Global SDF quality. Controls the volume texture resolution and amount of cascades to use.
///
diff --git a/Source/Engine/Graphics/Textures/GPUTexture.cpp b/Source/Engine/Graphics/Textures/GPUTexture.cpp
index 4cbe4ae60..b7aa53dba 100644
--- a/Source/Engine/Graphics/Textures/GPUTexture.cpp
+++ b/Source/Engine/Graphics/Textures/GPUTexture.cpp
@@ -551,6 +551,8 @@ bool GPUTexture::Resize(int32 width, int32 height, int32 depth)
desc.Width = width;
desc.Height = height;
desc.Depth = depth;
+ if (desc.MipLevels > 1)
+ desc.MipLevels = CalculateMipMapCount(0, Math::Max(width, height));
// Recreate
return Init(desc);
diff --git a/Source/Engine/Level/Actors/EnvironmentProbe.cpp b/Source/Engine/Level/Actors/EnvironmentProbe.cpp
index 231439a5a..746d87679 100644
--- a/Source/Engine/Level/Actors/EnvironmentProbe.cpp
+++ b/Source/Engine/Level/Actors/EnvironmentProbe.cpp
@@ -45,6 +45,26 @@ float EnvironmentProbe::GetScaledRadius() const
return _radius * _transform.Scale.MaxValue();
}
+bool EnvironmentProbe::HasProbe() const
+{
+ return _probe != nullptr;
+}
+
+bool EnvironmentProbe::HasProbeLoaded() const
+{
+ return _probe != nullptr && _probe->IsLoaded();
+}
+
+CubeTexture* EnvironmentProbe::GetProbe() const
+{
+ return _probe;
+}
+
+bool EnvironmentProbe::IsUsingCustomProbe() const
+{
+ return _isUsingCustomProbe;
+}
+
void EnvironmentProbe::SetupProbeData(const RenderContext& renderContext, ProbeData* data) const
{
const float radius = GetScaledRadius();
@@ -81,17 +101,9 @@ void EnvironmentProbe::Bake(float timeout)
void EnvironmentProbe::SetProbeData(TextureData& data)
{
- int32 probeResolution = (int32)CubemapResolution;
- // if Use Graphics Settings
- if (probeResolution == 0) probeResolution = Graphics::DefaultProbeResolution;
-
- // Validate input data
- ASSERT(data.GetArraySize() == 6 && data.Height == probeResolution && data.Width == probeResolution);
-
- // Check if was using custom probe
+ // Remove custom probe (if used)
if (_isUsingCustomProbe)
{
- // Set
_isUsingCustomProbe = false;
_probe = nullptr;
}
diff --git a/Source/Engine/Level/Actors/EnvironmentProbe.h b/Source/Engine/Level/Actors/EnvironmentProbe.h
index 65b4d3b59..cf3bc2874 100644
--- a/Source/Engine/Level/Actors/EnvironmentProbe.h
+++ b/Source/Engine/Level/Actors/EnvironmentProbe.h
@@ -5,6 +5,7 @@
#include "../Actor.h"
#include "Engine/Content/Assets/CubeTexture.h"
#include "Engine/Content/AssetReference.h"
+#include "Engine/Graphics/Enums.h"
///
/// Environment Probe can capture space around the objects to provide reflections.
@@ -22,36 +23,25 @@ public:
///
/// The reflections texture resolution.
///
- API_ENUM() enum class CubemapResolutions
- {
- UseGraphicsSettings = 0,
- _64 = 64,
- _128 = 128,
- _256 = 256,
- _512 = 512,
- _1024 = 1024,
- _2048 = 2048,
- _4096 = 4096,
- };
- API_FIELD(Attributes = "EditorOrder(0), DefaultValue(CubemapResolutions.UseGraphicsSettings), EditorDisplay(\"Probe\")")
- CubemapResolutions CubemapResolution = CubemapResolutions::UseGraphicsSettings;
+ API_FIELD(Attributes = "EditorOrder(0), EditorDisplay(\"Probe\")")
+ ProbeCubemapResolution CubemapResolution = ProbeCubemapResolution::UseGraphicsSettings;
///
/// The reflections brightness.
///
- API_FIELD(Attributes="EditorOrder(10), DefaultValue(1.0f), Limit(0, 1000, 0.01f), EditorDisplay(\"Probe\")")
+ API_FIELD(Attributes="EditorOrder(10), Limit(0, 1000, 0.01f), EditorDisplay(\"Probe\")")
float Brightness = 1.0f;
///
/// Value indicating if probe should be updated automatically on change.
///
- API_FIELD(Attributes="EditorOrder(30), DefaultValue(false), EditorDisplay(\"Probe\")")
+ API_FIELD(Attributes="EditorOrder(30), EditorDisplay(\"Probe\")")
bool AutoUpdate = false;
///
/// The probe capture camera near plane distance.
///
- API_FIELD(Attributes="EditorOrder(30), DefaultValue(10.0f), Limit(0, float.MaxValue, 0.01f), EditorDisplay(\"Probe\")")
+ API_FIELD(Attributes="EditorOrder(30), Limit(0, float.MaxValue, 0.01f), EditorDisplay(\"Probe\")")
float CaptureNearPlane = 10.0f;
public:
@@ -74,39 +64,27 @@ public:
///
/// Returns true if env probe has cube texture assigned.
///
- API_PROPERTY() bool HasProbe() const
- {
- return _probe != nullptr;
- }
+ API_PROPERTY() bool HasProbe() const;
///
/// Returns true if env probe has cube texture assigned.
///
- API_PROPERTY() bool HasProbeLoaded() const
- {
- return _probe != nullptr && _probe->IsLoaded();
- }
+ API_PROPERTY() bool HasProbeLoaded() const;
///
/// Gets the probe texture used during rendering (baked or custom one).
///
- API_PROPERTY() CubeTexture* GetProbe() const
- {
- return _probe;
- }
+ API_PROPERTY() CubeTexture* GetProbe() const;
///
/// True if probe is using custom cube texture (not baked).
///
- API_PROPERTY() bool IsUsingCustomProbe() const
- {
- return _isUsingCustomProbe;
- }
+ API_PROPERTY() bool IsUsingCustomProbe() const;
///
/// Setup probe data structure
///
- /// Rendering context
+ /// Rendering context
/// Packed probe data to set
void SetupProbeData(const RenderContext& renderContext, struct ProbeData* data) const;
diff --git a/Source/Engine/Renderer/ProbesRenderer.cpp b/Source/Engine/Renderer/ProbesRenderer.cpp
index 41bf78c51..3c12f5986 100644
--- a/Source/Engine/Renderer/ProbesRenderer.cpp
+++ b/Source/Engine/Renderer/ProbesRenderer.cpp
@@ -5,6 +5,7 @@
#include "ProbesRenderer.h"
#include "Renderer.h"
#include "ReflectionsPass.h"
+#include "Engine/Core/Config/GraphicsSettings.h"
#include "Engine/Threading/ThreadPoolTask.h"
#include "Engine/Content/Content.h"
#include "Engine/Engine/EngineService.h"
@@ -32,13 +33,11 @@
class DownloadProbeTask : public ThreadPoolTask
{
private:
-
GPUTexture* _texture;
TextureData _data;
ProbesRenderer::Entry _entry;
public:
-
///
/// Initializes a new instance of the class.
///
@@ -51,7 +50,6 @@ public:
}
public:
-
///
/// Gets the texture data container.
///
@@ -61,7 +59,6 @@ public:
}
protected:
-
// [ThreadPoolTask]
bool Run() override
{
@@ -134,7 +131,6 @@ using namespace ProbesRendererImpl;
class ProbesRendererService : public EngineService
{
public:
-
ProbesRendererService()
: EngineService(TEXT("Probes Renderer"), 70)
{
@@ -204,6 +200,20 @@ void ProbesRenderer::Bake(SkyLight* probe, float timeout)
OnRegisterBake(e);
}
+int32 ProbesRenderer::Entry::GetResolution() const
+{
+ auto resolution = ProbeCubemapResolution::UseGraphicsSettings;
+ if (Type == EntryType::EnvProbe && Actor)
+ resolution = ((EnvironmentProbe*)Actor.Get())->CubemapResolution;
+ else if (Type == EntryType::SkyLight)
+ resolution = ProbeCubemapResolution::_128;
+ if (resolution == ProbeCubemapResolution::UseGraphicsSettings)
+ resolution = GraphicsSettings::Get()->DefaultProbeResolution;
+ if (resolution == ProbeCubemapResolution::UseGraphicsSettings)
+ resolution = ProbeCubemapResolution::_128;
+ return (int32)resolution;
+}
+
int32 ProbesRenderer::GetBakeQueueSize()
{
return _probesToBake.Count();
@@ -280,15 +290,8 @@ bool ProbesRenderer::Init()
// Init rendering pipeline
_output = GPUDevice::Instance->CreateTexture(TEXT("Output"));
- int32 probeResolution = ENV_PROBES_RESOLUTION;
- if (_current.Type == EntryType::EnvProbe)
- {
- auto envProbe = (EnvironmentProbe*)_current.Actor.Get();
- probeResolution = (int32)envProbe->CubemapResolution;
- // if Use Graphics Settings
- if (probeResolution == 0) probeResolution = Graphics::DefaultProbeResolution;
- }
- if (_output->Init(GPUTextureDescription::New2D(probeResolution, probeResolution, ENV_PROBES_FORMAT)))
+ const int32 probeResolution = _current.GetResolution();
+ if (_output->Init(GPUTextureDescription::New2D(probeResolution, probeResolution, PixelFormat::R8G8B8A8_UNorm)))
return true;
_task = New();
auto task = _task;
@@ -315,10 +318,10 @@ bool ProbesRenderer::Init()
// Init render targets
_probe = GPUDevice::Instance->CreateTexture(TEXT("ProbesUpdate.Probe"));
- if (_probe->Init(GPUTextureDescription::NewCube(probeResolution, ENV_PROBES_FORMAT, GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget | GPUTextureFlags::PerMipViews, 0)))
+ if (_probe->Init(GPUTextureDescription::NewCube(probeResolution, _output->Format(), GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget | GPUTextureFlags::PerMipViews, 0)))
return true;
_tmpFace = GPUDevice::Instance->CreateTexture(TEXT("ProbesUpdate.TmpFae"));
- if (_tmpFace->Init(GPUTextureDescription::New2D(probeResolution, probeResolution, 0, ENV_PROBES_FORMAT, GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget | GPUTextureFlags::PerMipViews)))
+ if (_tmpFace->Init(GPUTextureDescription::New2D(probeResolution, probeResolution, 0, _output->Format(), GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget | GPUTextureFlags::PerMipViews)))
return true;
// Mark as ready
@@ -421,7 +424,7 @@ void ProbesRendererService::Update()
// Store time of the last probe update
_lastProbeUpdate = timeNow;
}
- // Check if need to release data
+ // Check if need to release data
else if (_isReady && timeSinceUpdate > ProbesRenderer::ProbesReleaseDataTime)
{
// Release service
@@ -474,14 +477,11 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
// Init
float customCullingNear = -1;
- int32 probeResolution = ENV_PROBES_RESOLUTION;
+ const int32 probeResolution = _current.GetResolution();
if (_current.Type == EntryType::EnvProbe)
{
auto envProbe = (EnvironmentProbe*)_current.Actor.Get();
- probeResolution = (int32)envProbe->CubemapResolution;
- // if Use Graphics Settings
- if (probeResolution == 0) probeResolution = Graphics::DefaultProbeResolution;
- LOG(Info, "Updating Env probe '{0}'...", envProbe->ToString());
+ LOG(Info, "Updating Env probe '{0}' (resolution: {1})...", envProbe->ToString(), probeResolution);
Vector3 position = envProbe->GetPosition();
float radius = envProbe->GetScaledRadius();
float nearPlane = Math::Max(0.1f, envProbe->CaptureNearPlane);
@@ -499,7 +499,7 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
else if (_current.Type == EntryType::SkyLight)
{
auto skyLight = (SkyLight*)_current.Actor.Get();
- LOG(Info, "Updating sky light '{0}'...", skyLight->ToString());
+ LOG(Info, "Updating sky light '{0}' (resolution: {1})...", skyLight->ToString(), probeResolution);
Vector3 position = skyLight->GetPosition();
float nearPlane = 10.0f;
float farPlane = Math::Max(nearPlane + 1000.0f, skyLight->SkyDistanceThreshold * 2.0f);
@@ -512,6 +512,14 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
_task->View.SetUpCube(nearPlane, farPlane, position - _task->View.Origin);
}
+ // Resize buffers
+ bool resizeFailed = _output->Resize(probeResolution, probeResolution);
+ resizeFailed |= _task->Resize(probeResolution, probeResolution);
+ resizeFailed |= _probe->Resize(probeResolution, probeResolution);
+ resizeFailed |= _tmpFace->Resize(probeResolution, probeResolution);
+ if (resizeFailed)
+ LOG(Error, "Failed to resize probe");
+
// Disable actor during baking (it cannot influence own results)
const bool isActorActive = _current.Actor->GetIsActive();
_current.Actor->SetIsActive(false);
@@ -538,7 +546,7 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
{
PROFILE_GPU("Copy Face");
context->SetRenderTarget(_probe->View(faceIndex));
- context->SetViewportAndScissors(probeResolution, probeResolution);
+ context->SetViewportAndScissors((float)probeResolution, (float)probeResolution);
auto probeFrame = _output->View();
if (setLowerHemisphereToBlack && faceIndex != 2)
{
diff --git a/Source/Engine/Renderer/ProbesRenderer.h b/Source/Engine/Renderer/ProbesRenderer.h
index 2df2e0f69..e9fa24b97 100644
--- a/Source/Engine/Renderer/ProbesRenderer.h
+++ b/Source/Engine/Renderer/ProbesRenderer.h
@@ -45,6 +45,8 @@ public:
Actor = other.Actor;
Timeout = other.Timeout;
}
+
+ int32 GetResolution() const;
};
public:
diff --git a/Source/Engine/Renderer/ReflectionsPass.cpp b/Source/Engine/Renderer/ReflectionsPass.cpp
index ed7f25eed..6ab22cf49 100644
--- a/Source/Engine/Renderer/ReflectionsPass.cpp
+++ b/Source/Engine/Renderer/ReflectionsPass.cpp
@@ -390,7 +390,7 @@ void ReflectionsPass::Render(RenderContext& renderContext, GPUTextureView* light
context->BindSR(2, renderContext.Buffers->GBuffer2);
context->BindSR(3, renderContext.Buffers->DepthBuffer);
- auto tempDesc = GPUTextureDescription::New2D(renderContext.Buffers->GetWidth(), renderContext.Buffers->GetHeight(), REFLECTIONS_PASS_OUTPUT_FORMAT);
+ auto tempDesc = GPUTextureDescription::New2D(renderContext.Buffers->GetWidth(), renderContext.Buffers->GetHeight(), PixelFormat::R11G11B10_Float);
auto reflectionsBuffer = RenderTargetPool::Get(tempDesc);
context->Clear(*reflectionsBuffer, Color::Black);
diff --git a/Source/Engine/Renderer/ReflectionsPass.h b/Source/Engine/Renderer/ReflectionsPass.h
index 37893e605..cab4618d5 100644
--- a/Source/Engine/Renderer/ReflectionsPass.h
+++ b/Source/Engine/Renderer/ReflectionsPass.h
@@ -7,12 +7,6 @@
#include "Engine/Content/Assets/Model.h"
#include "Engine/Content/Assets/Shader.h"
-// Reflections buffer format used for rendering env probes and screen space reflections
-#define REFLECTIONS_PASS_OUTPUT_FORMAT PixelFormat::R11G11B10_Float
-#define ENV_PROBES_RESOLUTION 128
-//#define ENV_PROBES_FORMAT PixelFormat::R11G11B10_Float
-#define ENV_PROBES_FORMAT PixelFormat::R8G8B8A8_UNorm
-
#define GENERATE_GF_CACHE 0
#define PRE_INTEGRATED_GF_ASSET_NAME TEXT("Engine/Textures/PreIntegratedGF")