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 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<ProbesRendererService, &ProbesRendererService::OnShaderReloading>(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();
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user