Small bilateral blur optim

This commit is contained in:
Olivier Prat 2018-10-02 12:25:00 +02:00
parent 6420d96149
commit 1ed0bd68b9
4 changed files with 40 additions and 23 deletions

View file

@ -220,7 +220,7 @@ AmbientOcclusionEffectConfig::AmbientOcclusionEffectConfig() :
borderingEnabled{ true },
fetchMipsEnabled{ true },
horizonBased{ true },
jitterEnabled{ true }{
jitterEnabled{ false }{
}
AmbientOcclusionEffect::AOParameters::AOParameters() {

View file

@ -32,14 +32,20 @@ vec4 packOcclusionOutput(float occlusion, float depth, vec3 eyeNormal) {
#endif
}
void unpackOcclusionOutput(vec4 raw, out float occlusion, out float depth, out vec3 eyeNormal) {
occlusion = raw.x;
struct UnpackedOcclusion {
vec3 normal;
float depth;
float occlusion;
};
void unpackOcclusionOutput(vec4 raw, out UnpackedOcclusion result) {
result.occlusion = raw.x;
#if SSAO_BILATERAL_BLUR_USE_NORMAL
depth = raw.y;
eyeNormal = normalize(vec3(raw.zw, 1.0));
result.depth = raw.y;
result.normal = normalize(vec3(raw.zw, 1.0));
#else
depth = (raw.y + raw.z / 256.0);
eyeNormal = vec3(0,0,1);
result.depth = (raw.y + raw.z / 256.0);
result.normal = vec3(0,0,1);
#endif
}
@ -391,6 +397,7 @@ float evalVisibilitySSAO(in vec3 centerPosition, in vec3 centerNormal, in vec3 t
}
#define HBAO_USE_COS_ANGLE 1
#define HBAO_USE_OVERHANG_HACK 0
float computeWeightForHorizon(float horizonLimit, float distanceSquared) {
return max(0.0, 1.0 - distanceSquared / getRadius2());
@ -433,11 +440,14 @@ float computeWeightedHorizon(float horizonLimit, float distanceSquared) {
if (tapHorizonLimit > horizonLimit) {
occlusion += weight * (tapHorizonLimit - horizonLimit);
horizonLimit = tapHorizonLimit;
} /*else if (dot(deltaVec, fragFrameES.tangent) < 0.0) {
}
#if HBAO_USE_OVERHANG_HACK
else if (dot(deltaVec, fragFrameES.tangent) < 0.0) {
// This is a hack to try to handle the case where the occlusion angle is
// greater than 90°
occlusion = mix(occlusion, (occlusion+1.0) * 0.5, weight);
}*/
}
#endif
#else
if (tapHorizonLimit < horizonLimit) {
tapHorizonLimit = computeWeightedHorizon(tapHorizonLimit, distanceSquared);
@ -509,13 +519,16 @@ float evalVisibilityHBAO(ivec4 side, vec2 fragUVPos, vec2 invSideImageSize, vec2
pixelSearchVec = abs(pixelSearchVec);
int stepCount = int(ceil(max(pixelSearchVec.x, pixelSearchVec.y)));
#if HBAO_USE_OVERHANG_HACK || !HBAO_USE_COS_ANGLE
fragFrameES.tangent = normalize(fragFrameES.tangent * deltaTap.x + fragFrameES.binormal * deltaTap.y);
#endif
// Forward search for h1
obscuranceH1 = computeOcclusion(side, fragUVPos, fragPositionES, fragFrameES, searchDir, diskPixelRadius, stepCount);
// Backward search for h2
#if HBAO_USE_OVERHANG_HACK || !HBAO_USE_COS_ANGLE
fragFrameES.tangent = -fragFrameES.tangent;
#endif
obscuranceH2 = computeOcclusion(side, fragUVPos, fragPositionES, fragFrameES, -searchDir, diskPixelRadius, stepCount);
return obscuranceH1 + obscuranceH2;

View file

@ -55,29 +55,26 @@ float evalBlurCoefficient(vec3 blurScales, float radialDistance, float zDistance
const float BLUR_EDGE_NORMAL_LIMIT = 0.25;
vec2 evalTapWeightedValue(vec3 blurScales, ivec4 side, int r, vec2 occlusionTexCoord, float fragDepth, vec3 fragNormal) {
vec2 tapOcclusionTexCoord = getBlurOcclusionAxis() * r + occlusionTexCoord;
vec2 occlusionTexCoordLimits = getBlurOcclusionUVLimit();
if (any(lessThan(tapOcclusionTexCoord, vec2(0.0))) || any(greaterThanEqual(tapOcclusionTexCoord, occlusionTexCoordLimits)) ) {
if (any(lessThan(occlusionTexCoord, vec2(0.0))) || any(greaterThanEqual(occlusionTexCoord, occlusionTexCoordLimits)) ) {
return vec2(0.0);
}
vec4 tapOcclusionPacked = fetchOcclusionPacked(side, tapOcclusionTexCoord);
float tapOcclusion;
float tapDepth;
vec3 tapNormal;
unpackOcclusionOutput(tapOcclusionPacked, tapOcclusion, tapDepth, tapNormal);
vec4 tapOcclusionPacked = fetchOcclusionPacked(side, occlusionTexCoord);
UnpackedOcclusion tap;
unpackOcclusionOutput(tapOcclusionPacked, tap);
// range domain (the "bilateral" weight). As depth difference increases, decrease weight.
float zDistance = tapDepth - fragDepth;
float zDistance = tap.depth - fragDepth;
#if SSAO_BILATERAL_BLUR_USE_NORMAL
float normalDistance = BLUR_EDGE_NORMAL_LIMIT - min(BLUR_EDGE_NORMAL_LIMIT, dot(tapNormal, fragNormal));
float normalDistance = BLUR_EDGE_NORMAL_LIMIT - min(BLUR_EDGE_NORMAL_LIMIT, dot(tap.normal, fragNormal));
#else
float normalDistance = 0.0;
#endif
float weight = evalBlurCoefficient(blurScales, abs(r), zDistance, normalDistance);
return vec2(tapOcclusion * weight, weight);
return vec2(tap.occlusion * weight, weight);
}
vec4 getBlurredOcclusion(ivec2 destPixelCoord, vec2 occlusionTexCoord, vec2 depthTexCoord) {
@ -96,24 +93,30 @@ vec4 getBlurredOcclusion(ivec2 destPixelCoord, vec2 occlusionTexCoord, vec2 dept
// Accumulate weighted contributions along the bluring axis in the [-radius, radius] range
int blurRadius = getBlurRadius();
vec3 blurScales = getBlurScales();
int r;
// From now on, occlusionTexCoord is the UV pos in the side
float sideTexCoord = occlusionTexCoord.x * 2.0 - getStereoSide(side) * getBlurOcclusionUVLimit().x;
occlusionTexCoord.x = mix(occlusionTexCoord.x, sideTexCoord, isStereo());
occlusionTexCoord -= getBlurOcclusionAxis() * blurRadius;
// negative side first
for (int r = -blurRadius; r <= -1; ++r) {
for (r = -blurRadius; r <= -1; r++) {
weightedSums += evalTapWeightedValue(blurScales, side, r, occlusionTexCoord, fragDepthKey, fragNormal);
occlusionTexCoord += getBlurOcclusionAxis();
}
// Central pixel contribution
float mainWeight = 1.0;
float pixelOcclusion = unpackOcclusion(fetchOcclusionPacked(side, occlusionTexCoord));
weightedSums += vec2(pixelOcclusion * mainWeight, mainWeight);
occlusionTexCoord += getBlurOcclusionAxis();
// then positive side
for (int r = 1; r <= blurRadius; ++r) {
for (r = 1; r <= blurRadius; ++r) {
weightedSums += evalTapWeightedValue(blurScales, side, r, occlusionTexCoord, fragDepthKey, fragNormal);
occlusionTexCoord += getBlurOcclusionAxis();
}
// Final normalization

View file

@ -60,8 +60,9 @@ void main(void) {
fragFrameES.tangent = vec3(0.0);
fragFrameES.binormal = vec3(0.0);
fragFrameES.normal = fragNormalES;
#if HBAO_USE_OVERHANG_HACK || !HBAO_USE_COS_ANGLE
buildTangentBinormal(side, fragUVPos, fragPositionES, fragNormalES, deltaDepthUV, fragFrameES.tangent, fragFrameES.binormal);
#endif
// Let's make noise
float randomPatternRotationAngle = getAngleDithering(fragPixelPos);