Optimize environment probes filtering shader
This commit is contained in:
BIN
Content/Shaders/ProbesFilter.flax
(Stored with Git LFS)
BIN
Content/Shaders/ProbesFilter.flax
(Stored with Git LFS)
Binary file not shown.
@@ -125,11 +125,21 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool LazyInit();
|
bool LazyInit();
|
||||||
|
bool InitShader();
|
||||||
void Update() override;
|
void Update() override;
|
||||||
void Dispose() override;
|
void Dispose() override;
|
||||||
|
|
||||||
void Bake(const ProbeEntry& e);
|
void Bake(const ProbeEntry& e);
|
||||||
|
|
||||||
|
private:
|
||||||
void OnRender(RenderTask* task, GPUContext* context);
|
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;
|
ProbesRendererService ProbesRendererServiceInstance;
|
||||||
@@ -206,19 +216,13 @@ bool ProbesRendererService::LazyInit()
|
|||||||
_initFailed = _shader == nullptr;
|
_initFailed = _shader == nullptr;
|
||||||
if (_initFailed)
|
if (_initFailed)
|
||||||
return false;
|
return false;
|
||||||
|
#if COMPILE_WITH_DEV_ENV
|
||||||
|
_shader->OnReloading.Bind<ProbesRendererService, &ProbesRendererService::OnShaderReloading>(this);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (!_shader->IsLoaded())
|
if (!_shader->IsLoaded())
|
||||||
return true;
|
return true;
|
||||||
const auto shader = _shader->GetShader();
|
_initFailed |= InitShader();
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init rendering pipeline
|
// Init rendering pipeline
|
||||||
_output = GPUDevice::Instance->CreateTexture(TEXT("ProbesRenderer.Output"));
|
_output = GPUDevice::Instance->CreateTexture(TEXT("ProbesRenderer.Output"));
|
||||||
@@ -262,6 +266,16 @@ bool ProbesRendererService::LazyInit()
|
|||||||
return false;
|
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()
|
void ProbesRendererService::Update()
|
||||||
{
|
{
|
||||||
PROFILE_MEM(Graphics);
|
PROFILE_MEM(Graphics);
|
||||||
@@ -412,6 +426,18 @@ void ProbesRendererService::OnRender(RenderTask* task, GPUContext* context)
|
|||||||
auto shader = _shader->GetShader();
|
auto shader = _shader->GetShader();
|
||||||
PROFILE_GPU("Render Probe");
|
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
|
// Init
|
||||||
const int32 probeResolution = _current.GetResolution();
|
const int32 probeResolution = _current.GetResolution();
|
||||||
const PixelFormat probeFormat = _current.GetFormat();
|
const PixelFormat probeFormat = _current.GetFormat();
|
||||||
|
|||||||
@@ -50,18 +50,16 @@ float4 PS_FilterFace(Quad_VS2PS input) : SV_Target
|
|||||||
float2 uv = input.TexCoord * 2 - 1;
|
float2 uv = input.TexCoord * 2 - 1;
|
||||||
float3 cubeCoordinates = UvToCubeMapUv(uv);
|
float3 cubeCoordinates = UvToCubeMapUv(uv);
|
||||||
|
|
||||||
#define NUM_FILTER_SAMPLES 512
|
|
||||||
|
|
||||||
float3 N = normalize(cubeCoordinates);
|
float3 N = normalize(cubeCoordinates);
|
||||||
float roughness = ProbeRoughnessFromMip(SourceMipIndex);
|
float roughness = ProbeRoughnessFromMip(SourceMipIndex);
|
||||||
|
|
||||||
|
const uint samplesCount = roughness > 0.1 ? 64 : 32;
|
||||||
float4 filteredColor = 0;
|
float4 filteredColor = 0;
|
||||||
float weight = 0;
|
float weight = 0;
|
||||||
|
|
||||||
LOOP
|
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 H = TangentToWorld(ImportanceSampleGGX(E, roughness).xyz, N);
|
||||||
float3 L = 2 * dot(N, H) * H - N;
|
float3 L = 2 * dot(N, H) * H - N;
|
||||||
float NoL = saturate(dot(N, L));
|
float NoL = saturate(dot(N, L));
|
||||||
|
|||||||
Reference in New Issue
Block a user