From 60f59130023e6ce10e6ea457ed5dfb7bbf14d892 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Tue, 25 Sep 2018 11:06:05 +0200 Subject: [PATCH] Bilateral blur taps are evaluated in shader --- .../src/AmbientOcclusionEffect.cpp | 69 ------------------- .../render-utils/src/AmbientOcclusionEffect.h | 1 - libraries/render-utils/src/ssao.slh | 23 ++++--- libraries/render-utils/src/ssao_shared.h | 2 - 4 files changed, 13 insertions(+), 82 deletions(-) diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.cpp b/libraries/render-utils/src/AmbientOcclusionEffect.cpp index 776996536b..5a1a168894 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.cpp +++ b/libraries/render-utils/src/AmbientOcclusionEffect.cpp @@ -199,61 +199,6 @@ gpu::TexturePointer AmbientOcclusionFramebuffer::getNormalTexture() { return _normalTexture; } -class GaussianDistribution { -public: - - static double integral(float x, float deviation) { - return 0.5 * erf((double)x / ((double)deviation * sqrt(2.0))); - } - - static double rangeIntegral(float x0, float x1, float deviation) { - return integral(x1, deviation) - integral(x0, deviation); - } - - static std::vector evalSampling(int samplingRadius, float deviation) { - std::vector coefs(samplingRadius + 1, 0.0f); - - // corner case when radius is 0 or under - if (samplingRadius <= 0) { - coefs[0] = 1.0f; - return coefs; - } - - // Evaluate all the samples range integral of width 1 from center until the penultimate one - float halfWidth = 0.5f; - double sum = 0.0; - for (int i = 0; i < samplingRadius; i++) { - float x = (float) i; - double sample = rangeIntegral(x - halfWidth, x + halfWidth, deviation); - coefs[i] = sample; - sum += sample; - } - - // last sample goes to infinity - float lastSampleX0 = (float) samplingRadius - halfWidth; - float largeEnough = lastSampleX0 + 1000.0f * deviation; - double sample = rangeIntegral(lastSampleX0, largeEnough, deviation); - coefs[samplingRadius] = sample; - sum += sample; - - return coefs; - } - - static void evalSampling(float* coefs, unsigned int coefsLength, int samplingRadius, float deviation) { - auto coefsVector = evalSampling(samplingRadius, deviation); - if (coefsLength> coefsVector.size() + 1) { - unsigned int coefsNum = 0; - for (auto s : coefsVector) { - coefs[coefsNum] = s; - coefsNum++; - } - for (;coefsNum < coefsLength; coefsNum++) { - coefs[coefsNum] = 0.0f; - } - } - } -}; - AmbientOcclusionEffectConfig::AmbientOcclusionEffectConfig() : render::GPUJobConfig::Persistent(QStringList() << "Render" << "Engine" << "Ambient Occlusion", false), #if SSAO_USE_HORIZON_BASED @@ -298,7 +243,6 @@ AmbientOcclusionEffect::AmbientOcclusionEffect() { void AmbientOcclusionEffect::configure(const Config& config) { DependencyManager::get()->setAmbientOcclusionEnabled(config.enabled); - bool shouldUpdateGaussian = false; bool shouldUpdateBlurs = false; const double RADIUS_POWER = 6.0; @@ -332,7 +276,6 @@ void AmbientOcclusionEffect::configure(const Config& config) { if (config.blurDeviation != _aoParametersBuffer->getBlurDeviation()) { auto& current = _aoParametersBuffer.edit()._blurInfo; current.z = config.blurDeviation; - shouldUpdateGaussian = true; } if (config.numSpiralTurns != _aoParametersBuffer->getNumSpiralTurns()) { @@ -386,7 +329,6 @@ void AmbientOcclusionEffect::configure(const Config& config) { if (config.blurRadius != _aoParametersBuffer.get().getBlurRadius()) { auto& current = _aoParametersBuffer.edit()._blurInfo; current.y = (float)config.blurRadius; - shouldUpdateGaussian = true; } if (config.ditheringEnabled != _aoParametersBuffer->isDitheringEnabled()) { @@ -399,10 +341,6 @@ void AmbientOcclusionEffect::configure(const Config& config) { current.w = (float)config.borderingEnabled; } - if (shouldUpdateGaussian) { - updateGaussianDistribution(); - } - if (shouldUpdateBlurs) { updateBlurParameters(); } @@ -525,13 +463,6 @@ const gpu::PipelinePointer& AmbientOcclusionEffect::getBuildNormalsPipeline() { return _buildNormalsPipeline; } -void AmbientOcclusionEffect::updateGaussianDistribution() { - auto filterTaps = _aoParametersBuffer.edit()._blurFilterTaps; - auto blurRadius = _aoParametersBuffer.get().getBlurRadius(); - - GaussianDistribution::evalSampling(filterTaps, SSAO_BLUR_GAUSSIAN_COEFS_COUNT, blurRadius, _aoParametersBuffer->getBlurDeviation()); -} - int AmbientOcclusionEffect::getDepthResolutionLevel() const { // Having some problems making a nice AO with Half resolution depth, so stick to full res. return 0; diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.h b/libraries/render-utils/src/AmbientOcclusionEffect.h index a86cce4d23..3ad5ee2138 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.h +++ b/libraries/render-utils/src/AmbientOcclusionEffect.h @@ -175,7 +175,6 @@ private: using FrameParametersBuffer = gpu::StructBuffer< AmbientOcclusionFrameParams>; - void updateGaussianDistribution(); void updateBlurParameters(); void updateFramebufferSizes(); diff --git a/libraries/render-utils/src/ssao.slh b/libraries/render-utils/src/ssao.slh index 5e250fe04b..468e3fc7d1 100644 --- a/libraries/render-utils/src/ssao.slh +++ b/libraries/render-utils/src/ssao.slh @@ -123,10 +123,6 @@ int getBlurRadius() { return int(params._blurInfo.y); } -float getBlurCoef(int c) { - return params._blurFilterTaps[c]; -} - <@endfunc@> <@func declareSamplingDisk()@> @@ -454,7 +450,12 @@ float fetchOcclusion(vec2 coords) { const float BLUR_EDGE_DISTANCE_SCALE = 1000.0; -vec2 evalTapWeightedValue(ivec3 side, int r, ivec2 destPixelCoord, vec2 scaledTexCoord, vec2 fullTexCoord, float fragDepth) { +float evalBlurCoefficient(vec2 blurScales, float radialDistance, float zDistance) { + vec2 distances = vec2(radialDistance, zDistance); + return exp2(dot(blurScales, distances*distances)); +} + +vec2 evalTapWeightedValue(vec2 blurScales, ivec3 side, int r, ivec2 destPixelCoord, vec2 scaledTexCoord, vec2 fullTexCoord, float fragDepth) { ivec2 tapOffset = <$axis$> * r; ivec2 tapPixelCoord = destPixelCoord + ivec2(tapOffset); @@ -467,11 +468,10 @@ vec2 evalTapWeightedValue(ivec3 side, int r, ivec2 destPixelCoord, vec2 scaledTe tapTexCoord = fullTexCoord + tapOffset * getDepthBlurScale(); float tapDepth = getZEyeAtUV(tapTexCoord, 0); - float weight = getBlurCoef(abs(r)); // range domain (the "bilateral" weight). As depth difference increases, decrease weight. float zDistance = tapDepth - fragDepth; - weight *= exp(-getBlurEdgeSharpness() * (zDistance * zDistance * BLUR_EDGE_DISTANCE_SCALE)); + float weight = evalBlurCoefficient(blurScales, abs(r), zDistance); return vec2(tapOcclusion * weight, weight); } @@ -485,20 +485,23 @@ vec3 getBlurredOcclusion(ivec2 destPixelCoord, vec2 scaledTexCoord, vec2 fullTex // Accumulate weighted contributions along the bluring axis in the [-radius, radius] range int blurRadius = getBlurRadius(); + float blurRadialSigma = float(blurRadius) * 0.5; + float blurRadialScale = 1.0 / (2.0*blurRadialSigma*blurRadialSigma); + vec2 blurScales = -vec2(blurRadialScale, BLUR_EDGE_DISTANCE_SCALE) * getBlurEdgeSharpness(); // negative side first for (int r = -blurRadius; r <= -1; ++r) { - weightedSums += evalTapWeightedValue(side.xyz, r, destPixelCoord, scaledTexCoord, fullTexCoord, fragDepth); + weightedSums += evalTapWeightedValue(blurScales, side.xyz, r, destPixelCoord, scaledTexCoord, fullTexCoord, fragDepth); } // Central pixel contribution - float mainWeight = getBlurCoef(0); + float mainWeight = 1.0; float pixelOcclusion = fetchOcclusion(scaledTexCoord); weightedSums += vec2(pixelOcclusion * mainWeight, mainWeight); // then positive side for (int r = 1; r <= blurRadius; ++r) { - weightedSums += evalTapWeightedValue(side.xyz, r, destPixelCoord, scaledTexCoord, fullTexCoord, fragDepth); + weightedSums += evalTapWeightedValue(blurScales, side.xyz, r, destPixelCoord, scaledTexCoord, fullTexCoord, fragDepth); } // Final normalization diff --git a/libraries/render-utils/src/ssao_shared.h b/libraries/render-utils/src/ssao_shared.h index 7410baf715..11c7f894d5 100644 --- a/libraries/render-utils/src/ssao_shared.h +++ b/libraries/render-utils/src/ssao_shared.h @@ -16,7 +16,6 @@ #define SSAO_USE_HORIZON_BASED 1 #define SSAO_USE_QUAD_SPLIT 1 -#define SSAO_BLUR_GAUSSIAN_COEFS_COUNT 16 #if SSAO_USE_QUAD_SPLIT #define SSAO_SPLIT_COUNT 4 @@ -39,7 +38,6 @@ struct AmbientOcclusionParams { SSAO_VEC4 _ditheringInfo; SSAO_VEC4 _sampleInfo; SSAO_VEC4 _blurInfo; - float _blurFilterTaps[SSAO_BLUR_GAUSSIAN_COEFS_COUNT]; SSAO_VEC4 _sideSizes[2]; };