From a8579cadcc2a95d4a43533def97ad49f0a13dace Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Thu, 14 Jul 2022 15:37:54 +0200 Subject: [PATCH] Move `DefaultProbeResolution` from Graphics to `GraphicsSettings` only (not runtime option) #728 --- Content/Shaders/BakeLightmap.flax | 2 +- .../Shaders/Editor/LightmapUVsDensity.flax | 2 +- Content/Shaders/ProbesFilter.flax | 2 +- .../Engine/Core/Config/GraphicsSettings.cpp | 1 - Source/Engine/Core/Config/GraphicsSettings.h | 16 +----- Source/Engine/Graphics/Enums.h | 23 ++++++++ Source/Engine/Graphics/Graphics.cpp | 1 - Source/Engine/Graphics/Graphics.h | 5 -- .../Engine/Graphics/Textures/GPUTexture.cpp | 2 + .../Engine/Level/Actors/EnvironmentProbe.cpp | 30 +++++++--- Source/Engine/Level/Actors/EnvironmentProbe.h | 44 ++++----------- Source/Engine/Renderer/ProbesRenderer.cpp | 56 +++++++++++-------- Source/Engine/Renderer/ProbesRenderer.h | 2 + Source/Engine/Renderer/ReflectionsPass.cpp | 2 +- Source/Engine/Renderer/ReflectionsPass.h | 6 -- 15 files changed, 98 insertions(+), 96 deletions(-) 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")