diff --git a/Content/Shaders/ProbesFilter.flax b/Content/Shaders/ProbesFilter.flax index 0f853c5b4..679eac27b 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:f0249696b525cd59825ab3c0ce38bd612f93cf4be1f88fb49bfcecaac6e9ab34 -size 2022 +oid sha256:bbe90799accc93fabdc900df37bf762132037eeaff17f5731f379b6b3d017d2b +size 2033 diff --git a/Source/Engine/Renderer/ProbesRenderer.cpp b/Source/Engine/Renderer/ProbesRenderer.cpp index ae94385e2..9eb5f3937 100644 --- a/Source/Engine/Renderer/ProbesRenderer.cpp +++ b/Source/Engine/Renderer/ProbesRenderer.cpp @@ -125,11 +125,21 @@ public: } bool LazyInit(); + bool InitShader(); void Update() override; void Dispose() override; - void Bake(const ProbeEntry& e); + +private: void OnRender(RenderTask* task, GPUContext* context); +#if COMPILE_WITH_DEV_ENV + bool _initShader = false; + void OnShaderReloading(Asset* obj) + { + _initShader = true; + SAFE_DELETE_GPU_RESOURCE(_psFilterFace); + } +#endif }; ProbesRendererService ProbesRendererServiceInstance; @@ -206,19 +216,13 @@ bool ProbesRendererService::LazyInit() _initFailed = _shader == nullptr; if (_initFailed) return false; +#if COMPILE_WITH_DEV_ENV + _shader->OnReloading.Bind(this); +#endif } if (!_shader->IsLoaded()) return true; - const auto shader = _shader->GetShader(); - CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); - - // Create pipeline stages - _psFilterFace = GPUDevice::Instance->CreatePipelineState(); - auto psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle; - { - psDesc.PS = shader->GetPS("PS_FilterFace"); - _initFailed |= _psFilterFace->Init(psDesc); - } + _initFailed |= InitShader(); // Init rendering pipeline _output = GPUDevice::Instance->CreateTexture(TEXT("ProbesRenderer.Output")); @@ -262,6 +266,16 @@ bool ProbesRendererService::LazyInit() return false; } +bool ProbesRendererService::InitShader() +{ + const auto shader = _shader->GetShader(); + CHECK_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data); + _psFilterFace = GPUDevice::Instance->CreatePipelineState(); + auto psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle; + psDesc.PS = shader->GetPS("PS_FilterFace"); + return _psFilterFace->Init(psDesc); +} + void ProbesRendererService::Update() { PROFILE_MEM(Graphics); @@ -412,6 +426,18 @@ void ProbesRendererService::OnRender(RenderTask* task, GPUContext* context) auto shader = _shader->GetShader(); PROFILE_GPU("Render Probe"); +#if COMPILE_WITH_DEV_ENV + // handle shader hot-reload + if (_initShader) + { + if (_shader->WaitForLoaded()) + return; + _initShader = false; + if (InitShader()) + return; + } +#endif + // Init const int32 probeResolution = _current.GetResolution(); const PixelFormat probeFormat = _current.GetFormat(); diff --git a/Source/Shaders/ProbesFilter.shader b/Source/Shaders/ProbesFilter.shader index 437d484f5..c64a281f2 100644 --- a/Source/Shaders/ProbesFilter.shader +++ b/Source/Shaders/ProbesFilter.shader @@ -50,18 +50,16 @@ float4 PS_FilterFace(Quad_VS2PS input) : SV_Target float2 uv = input.TexCoord * 2 - 1; float3 cubeCoordinates = UvToCubeMapUv(uv); -#define NUM_FILTER_SAMPLES 512 - float3 N = normalize(cubeCoordinates); float roughness = ProbeRoughnessFromMip(SourceMipIndex); + const uint samplesCount = roughness > 0.1 ? 64 : 32; float4 filteredColor = 0; float weight = 0; - LOOP - for (int i = 0; i < NUM_FILTER_SAMPLES; i++) + for (int i = 0; i < samplesCount; i++) { - float2 E = Hammersley(i, NUM_FILTER_SAMPLES, 0); + float2 E = Hammersley(i, samplesCount, 0); float3 H = TangentToWorld(ImportanceSampleGGX(E, roughness).xyz, N); float3 L = 2 * dot(N, H) * H - N; float NoL = saturate(dot(N, L));