From bcde742bbc7e77cb03b0e9c13534a67bfd108f96 Mon Sep 17 00:00:00 2001 From: Pixelflinger Date: Thu, 30 Jan 2020 11:36:02 -0800 Subject: [PATCH] Revert "wip: rework filtering" This reverts commit 79a83e8c467ba85fbfc8308d79cd35bf7eca1d1a. --- filament/src/PostProcessManager.cpp | 23 ++++++++----------- filament/src/PostProcessManager.h | 2 +- filament/src/Renderer.cpp | 35 ++++++++++++++++++++++------- filament/src/View.cpp | 2 +- filament/src/fg/FrameGraph.cpp | 2 +- shaders/src/light_indirect.fs | 7 +++--- 6 files changed, 42 insertions(+), 29 deletions(-) diff --git a/filament/src/PostProcessManager.cpp b/filament/src/PostProcessManager.cpp index 52b111b308..c00ae8c08b 100644 --- a/filament/src/PostProcessManager.cpp +++ b/filament/src/PostProcessManager.cpp @@ -694,20 +694,17 @@ FrameGraphId PostProcessManager::bilateralBlurPass(FrameGraph } FrameGraphId PostProcessManager::gaussianBlurPass(FrameGraph& fg, - FrameGraphId input, uint8_t srcLevel, uint8_t dstLevel) noexcept { + FrameGraphId input, uint8_t srcLevel, uint8_t dstLevel, float alpha) noexcept { Handle fullScreenRenderPrimitive = mEngine.getFullScreenRenderPrimitive(); - auto computeGaussianCoefficients = [](float2* kernel, size_t size) -> size_t { - // The kernel-size was determined empirically so that we don't get too many aritfacts - // due to the down-sampling. - const size_t n = 17; - - // The relation between n and q the variance should 6q - 1 = n, however here we - // use 4q - 1 = n, which gives a stronger blur, without bringing too many artifacts. - const float q = (n + 1) / 4; - const float alpha = 1.0f / (2.0f * q * q); - + auto computeGaussianCoefficients = [](float2* kernel, size_t size, float alpha) -> size_t { + // Figure out how many samples we need. A gaussian filter keeps its gaussianness + // if it has at least 6q-1 coefficient (q = standard deviation) + // standard deviation + float q = 1 / std::sqrt(2.0f * alpha); + // number of samples needed + size_t n = (size_t)std::max(1.0f, std::ceil(6.0f * q - 1.0f)); // number of positive-side samples needed, using linear sampling size_t m = (n - 1) / 4 + 1; // clamp to what we have @@ -757,8 +754,6 @@ FrameGraphId PostProcessManager::gaussianBlurPass(FrameGraph& desc.width = FTexture::valueForLevel(dstLevel, desc.width); // height of the source level (b/c it's not blurred in this pass) desc.height = FTexture::valueForLevel(srcLevel, desc.height); - // only one level - desc.levels = 1; data.temp = builder.createTexture("Horizontal temporary buffer", desc); data.temp = builder.write(builder.sample(data.temp)); @@ -784,7 +779,7 @@ FrameGraphId PostProcessManager::gaussianBlurPass(FrameGraph& float2 kernel[128]; size_t m = computeGaussianCoefficients(kernel, - std::min(sizeof(kernel) / sizeof(*kernel), kernelStorageSize)); + std::min(sizeof(kernel) / sizeof(*kernel), kernelStorageSize), alpha); // horizontal pass auto hwTempRT = resources.getRenderTarget(data.tempRT); diff --git a/filament/src/PostProcessManager.h b/filament/src/PostProcessManager.h index 28369b3c8a..a7946e8777 100644 --- a/filament/src/PostProcessManager.h +++ b/filament/src/PostProcessManager.h @@ -75,7 +75,7 @@ public: FrameGraphId gaussianBlurPass(FrameGraph& fg, FrameGraphId input, uint8_t srcLevel, - uint8_t dstLevel) noexcept; + uint8_t dstLevel, float alpha) noexcept; backend::Handle getNoSSAOTexture() const { return mNoSSAOTexture; diff --git a/filament/src/Renderer.cpp b/filament/src/Renderer.cpp index a072dae997..4b544be4f7 100644 --- a/filament/src/Renderer.cpp +++ b/filament/src/Renderer.cpp @@ -455,24 +455,43 @@ FrameGraphId FRenderer::refractionPass(FrameGraph& fg, // Number of roughness levels we want. Perceptual roughness will be mapped between // 0 and 0.5 (see lodToPerceptualRoughness() below). - const size_t kNumRoughnessLods = 10; + const size_t kNumRoughnessLods = 5; + + // maps a LOD to the perceptual roughness. this must match the inverse mapping + // in light_indirect.fs + auto lodToPerceptualRoughness = [](float lod) -> float { + return 0.5f * std::pow(2.0f, lod - (kNumRoughnessLods - 1)); }; // Copy the color buffer into a texture, we use resolve() because in case of a multi-sample // buffer, it'll also resolve it. input = ppm.resolve(fg, "Refraction Buffer", kNumRoughnessLods, TextureFormat::R11F_G11F_B10F, input); -// // scale factor for the gaussian so it matches our resolution / FOV + // scale factor for the gaussian so it matches our resolution / FOV const float verticalFieldOfView = view.getCameraUser().getFieldOfView(Camera::Fov::VERTICAL); const float s = pow2(verticalFieldOfView / desc.height); - float alpha0 = 0.2469f / s; + // this compute the alpha parameter of a gaussian that is applied on a base gaussian + // and for which the result of the convolution is given. + auto deconvolveGaussian = [](float baseAlpha, float convolvedAlpha) -> float { + return (baseAlpha * convolvedAlpha) / (baseAlpha - convolvedAlpha); + }; + + float prevAlpha = 65536.0; // just need a large number for (size_t i = 1; i < kNumRoughnessLods; i++) { - float alpha = alpha0 / float(1 << i * 2); - float roughness = 1.0f / std::sqrt(alpha); - float perceptualRoughness = std::sqrt(roughness); - slog.d << "lod=" << i << ", alpha=" << alpha << ", perceptualRoughness=" << perceptualRoughness << io::endl; - input = ppm.gaussianBlurPass(fg, input, i - 1, i); + // compute our gaussian parameter, alpha, for a given pereceptual roughness + // The gaussian kernel is e^(-alpha * x^2) + // and alpha = 1/roughness^2, with x between -pi/2 and pi/2 + // with, roughness = perceptual_roughnes^2 + const float perceptualRoughness = lodToPerceptualRoughness(i); + const float roughness = pow2(perceptualRoughness); + const float alpha = s * (1.0f / pow2(roughness)); + const float r = float(1 << (i - 1) * 2); + const float alphaForLod = r * deconvolveGaussian(prevAlpha, alpha); + input = ppm.gaussianBlurPass(fg, input, i - 1, i, alphaForLod); + prevAlpha = alpha; + //slog.d << "roughness=" << perceptualRoughness + // << ", alpha=" << alpha << ", " << alphaForLod << io::endl; } struct PrepareSSRData { diff --git a/filament/src/View.cpp b/filament/src/View.cpp index 148c870409..63f1a184a6 100644 --- a/filament/src/View.cpp +++ b/filament/src/View.cpp @@ -650,7 +650,7 @@ void FView::prepareSSAO(Handle ssao) const noexcept { void FView::prepareSSR(Handle ssr) const noexcept { mPerViewSb.setSampler(PerViewSib::SSR, ssr, { .filterMag = SamplerMagFilter::LINEAR, - .filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST + .filterMin = SamplerMinFilter::LINEAR_MIPMAP_LINEAR }); } diff --git a/filament/src/fg/FrameGraph.cpp b/filament/src/fg/FrameGraph.cpp index f17d391777..711d919ab4 100644 --- a/filament/src/fg/FrameGraph.cpp +++ b/filament/src/fg/FrameGraph.cpp @@ -173,7 +173,7 @@ FrameGraphPassResources::getRenderTarget(FrameGraphRenderTargetHandle handle, ui FrameGraph::FrameGraph(fg::ResourceAllocatorInterface& resourceAllocator) : mResourceAllocator(resourceAllocator), - mArena("FrameGraph Arena", 65536), // TODO: the Area will eventually come from outside + mArena("FrameGraph Arena", 32768), // TODO: the Area will eventually come from outside mPassNodes(mArena), mResourceNodes(mArena), mRenderTargets(mArena), diff --git a/shaders/src/light_indirect.fs b/shaders/src/light_indirect.fs index 00272e35cb..13d97595a6 100644 --- a/shaders/src/light_indirect.fs +++ b/shaders/src/light_indirect.fs @@ -445,12 +445,11 @@ void applyRefraction(const PixelParams pixel, p.xy = uvToRenderTargetUV(p.xy * (0.5 / p.w) + 0.5); // perceptualRoughness to LOD - const float kNumRoughnessLods = 10.0; + const float kNumRoughnessLods = 5.0; // Empirical factor to compensate for the gaussian approximation of Dggx, chosen so // cubemap and screen-space modes match at perceptualRoughness 0.125 -// float tweakedPerceptualRoughness = perceptualRoughness * 1.74; -// float lod = log2(tweakedPerceptualRoughness * 2.0) + (kNumRoughnessLods - 1.0); - float lod = perceptualRoughness * (kNumRoughnessLods - 1.0); + float tweakedPerceptualRoughness = perceptualRoughness * 1.74; + float lod = log2(tweakedPerceptualRoughness * 2.0) + (kNumRoughnessLods - 1.0); vec3 Ft = textureLod(light_ssr, p.xy, lod).rgb; #endif