mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 09:33:36 +02:00
Bilateral blur taps are evaluated in shader
This commit is contained in:
parent
0c586edeeb
commit
60f5913002
4 changed files with 13 additions and 82 deletions
|
@ -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<float> evalSampling(int samplingRadius, float deviation) {
|
||||
std::vector<float> 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<DeferredLightingEffect>()->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;
|
||||
|
|
|
@ -175,7 +175,6 @@ private:
|
|||
|
||||
using FrameParametersBuffer = gpu::StructBuffer< AmbientOcclusionFrameParams>;
|
||||
|
||||
void updateGaussianDistribution();
|
||||
void updateBlurParameters();
|
||||
void updateFramebufferSizes();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue