mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 18:21:16 +02:00
Small bilateral blur optim
This commit is contained in:
parent
6420d96149
commit
1ed0bd68b9
4 changed files with 40 additions and 23 deletions
|
@ -220,7 +220,7 @@ AmbientOcclusionEffectConfig::AmbientOcclusionEffectConfig() :
|
||||||
borderingEnabled{ true },
|
borderingEnabled{ true },
|
||||||
fetchMipsEnabled{ true },
|
fetchMipsEnabled{ true },
|
||||||
horizonBased{ true },
|
horizonBased{ true },
|
||||||
jitterEnabled{ true }{
|
jitterEnabled{ false }{
|
||||||
}
|
}
|
||||||
|
|
||||||
AmbientOcclusionEffect::AOParameters::AOParameters() {
|
AmbientOcclusionEffect::AOParameters::AOParameters() {
|
||||||
|
|
|
@ -32,14 +32,20 @@ vec4 packOcclusionOutput(float occlusion, float depth, vec3 eyeNormal) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void unpackOcclusionOutput(vec4 raw, out float occlusion, out float depth, out vec3 eyeNormal) {
|
struct UnpackedOcclusion {
|
||||||
occlusion = raw.x;
|
vec3 normal;
|
||||||
|
float depth;
|
||||||
|
float occlusion;
|
||||||
|
};
|
||||||
|
|
||||||
|
void unpackOcclusionOutput(vec4 raw, out UnpackedOcclusion result) {
|
||||||
|
result.occlusion = raw.x;
|
||||||
#if SSAO_BILATERAL_BLUR_USE_NORMAL
|
#if SSAO_BILATERAL_BLUR_USE_NORMAL
|
||||||
depth = raw.y;
|
result.depth = raw.y;
|
||||||
eyeNormal = normalize(vec3(raw.zw, 1.0));
|
result.normal = normalize(vec3(raw.zw, 1.0));
|
||||||
#else
|
#else
|
||||||
depth = (raw.y + raw.z / 256.0);
|
result.depth = (raw.y + raw.z / 256.0);
|
||||||
eyeNormal = vec3(0,0,1);
|
result.normal = vec3(0,0,1);
|
||||||
#endif
|
#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_COS_ANGLE 1
|
||||||
|
#define HBAO_USE_OVERHANG_HACK 0
|
||||||
|
|
||||||
float computeWeightForHorizon(float horizonLimit, float distanceSquared) {
|
float computeWeightForHorizon(float horizonLimit, float distanceSquared) {
|
||||||
return max(0.0, 1.0 - distanceSquared / getRadius2());
|
return max(0.0, 1.0 - distanceSquared / getRadius2());
|
||||||
|
@ -433,11 +440,14 @@ float computeWeightedHorizon(float horizonLimit, float distanceSquared) {
|
||||||
if (tapHorizonLimit > horizonLimit) {
|
if (tapHorizonLimit > horizonLimit) {
|
||||||
occlusion += weight * (tapHorizonLimit - horizonLimit);
|
occlusion += weight * (tapHorizonLimit - horizonLimit);
|
||||||
horizonLimit = tapHorizonLimit;
|
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
|
// This is a hack to try to handle the case where the occlusion angle is
|
||||||
// greater than 90°
|
// greater than 90°
|
||||||
occlusion = mix(occlusion, (occlusion+1.0) * 0.5, weight);
|
occlusion = mix(occlusion, (occlusion+1.0) * 0.5, weight);
|
||||||
}*/
|
}
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
if (tapHorizonLimit < horizonLimit) {
|
if (tapHorizonLimit < horizonLimit) {
|
||||||
tapHorizonLimit = computeWeightedHorizon(tapHorizonLimit, distanceSquared);
|
tapHorizonLimit = computeWeightedHorizon(tapHorizonLimit, distanceSquared);
|
||||||
|
@ -509,13 +519,16 @@ float evalVisibilityHBAO(ivec4 side, vec2 fragUVPos, vec2 invSideImageSize, vec2
|
||||||
pixelSearchVec = abs(pixelSearchVec);
|
pixelSearchVec = abs(pixelSearchVec);
|
||||||
int stepCount = int(ceil(max(pixelSearchVec.x, pixelSearchVec.y)));
|
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);
|
fragFrameES.tangent = normalize(fragFrameES.tangent * deltaTap.x + fragFrameES.binormal * deltaTap.y);
|
||||||
|
#endif
|
||||||
// Forward search for h1
|
// Forward search for h1
|
||||||
obscuranceH1 = computeOcclusion(side, fragUVPos, fragPositionES, fragFrameES, searchDir, diskPixelRadius, stepCount);
|
obscuranceH1 = computeOcclusion(side, fragUVPos, fragPositionES, fragFrameES, searchDir, diskPixelRadius, stepCount);
|
||||||
|
|
||||||
// Backward search for h2
|
// Backward search for h2
|
||||||
|
#if HBAO_USE_OVERHANG_HACK || !HBAO_USE_COS_ANGLE
|
||||||
fragFrameES.tangent = -fragFrameES.tangent;
|
fragFrameES.tangent = -fragFrameES.tangent;
|
||||||
|
#endif
|
||||||
obscuranceH2 = computeOcclusion(side, fragUVPos, fragPositionES, fragFrameES, -searchDir, diskPixelRadius, stepCount);
|
obscuranceH2 = computeOcclusion(side, fragUVPos, fragPositionES, fragFrameES, -searchDir, diskPixelRadius, stepCount);
|
||||||
|
|
||||||
return obscuranceH1 + obscuranceH2;
|
return obscuranceH1 + obscuranceH2;
|
||||||
|
|
|
@ -55,29 +55,26 @@ float evalBlurCoefficient(vec3 blurScales, float radialDistance, float zDistance
|
||||||
const float BLUR_EDGE_NORMAL_LIMIT = 0.25;
|
const float BLUR_EDGE_NORMAL_LIMIT = 0.25;
|
||||||
|
|
||||||
vec2 evalTapWeightedValue(vec3 blurScales, ivec4 side, int r, vec2 occlusionTexCoord, float fragDepth, vec3 fragNormal) {
|
vec2 evalTapWeightedValue(vec3 blurScales, ivec4 side, int r, vec2 occlusionTexCoord, float fragDepth, vec3 fragNormal) {
|
||||||
vec2 tapOcclusionTexCoord = getBlurOcclusionAxis() * r + occlusionTexCoord;
|
|
||||||
vec2 occlusionTexCoordLimits = getBlurOcclusionUVLimit();
|
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);
|
return vec2(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 tapOcclusionPacked = fetchOcclusionPacked(side, tapOcclusionTexCoord);
|
vec4 tapOcclusionPacked = fetchOcclusionPacked(side, occlusionTexCoord);
|
||||||
float tapOcclusion;
|
UnpackedOcclusion tap;
|
||||||
float tapDepth;
|
unpackOcclusionOutput(tapOcclusionPacked, tap);
|
||||||
vec3 tapNormal;
|
|
||||||
unpackOcclusionOutput(tapOcclusionPacked, tapOcclusion, tapDepth, tapNormal);
|
|
||||||
|
|
||||||
// range domain (the "bilateral" weight). As depth difference increases, decrease weight.
|
// 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
|
#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
|
#else
|
||||||
float normalDistance = 0.0;
|
float normalDistance = 0.0;
|
||||||
#endif
|
#endif
|
||||||
float weight = evalBlurCoefficient(blurScales, abs(r), zDistance, normalDistance);
|
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) {
|
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
|
// Accumulate weighted contributions along the bluring axis in the [-radius, radius] range
|
||||||
int blurRadius = getBlurRadius();
|
int blurRadius = getBlurRadius();
|
||||||
vec3 blurScales = getBlurScales();
|
vec3 blurScales = getBlurScales();
|
||||||
|
int r;
|
||||||
|
|
||||||
// From now on, occlusionTexCoord is the UV pos in the side
|
// From now on, occlusionTexCoord is the UV pos in the side
|
||||||
float sideTexCoord = occlusionTexCoord.x * 2.0 - getStereoSide(side) * getBlurOcclusionUVLimit().x;
|
float sideTexCoord = occlusionTexCoord.x * 2.0 - getStereoSide(side) * getBlurOcclusionUVLimit().x;
|
||||||
occlusionTexCoord.x = mix(occlusionTexCoord.x, sideTexCoord, isStereo());
|
occlusionTexCoord.x = mix(occlusionTexCoord.x, sideTexCoord, isStereo());
|
||||||
|
|
||||||
|
occlusionTexCoord -= getBlurOcclusionAxis() * blurRadius;
|
||||||
|
|
||||||
// negative side first
|
// negative side first
|
||||||
for (int r = -blurRadius; r <= -1; ++r) {
|
for (r = -blurRadius; r <= -1; r++) {
|
||||||
weightedSums += evalTapWeightedValue(blurScales, side, r, occlusionTexCoord, fragDepthKey, fragNormal);
|
weightedSums += evalTapWeightedValue(blurScales, side, r, occlusionTexCoord, fragDepthKey, fragNormal);
|
||||||
|
occlusionTexCoord += getBlurOcclusionAxis();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Central pixel contribution
|
// Central pixel contribution
|
||||||
float mainWeight = 1.0;
|
float mainWeight = 1.0;
|
||||||
float pixelOcclusion = unpackOcclusion(fetchOcclusionPacked(side, occlusionTexCoord));
|
float pixelOcclusion = unpackOcclusion(fetchOcclusionPacked(side, occlusionTexCoord));
|
||||||
weightedSums += vec2(pixelOcclusion * mainWeight, mainWeight);
|
weightedSums += vec2(pixelOcclusion * mainWeight, mainWeight);
|
||||||
|
occlusionTexCoord += getBlurOcclusionAxis();
|
||||||
|
|
||||||
// then positive side
|
// then positive side
|
||||||
for (int r = 1; r <= blurRadius; ++r) {
|
for (r = 1; r <= blurRadius; ++r) {
|
||||||
weightedSums += evalTapWeightedValue(blurScales, side, r, occlusionTexCoord, fragDepthKey, fragNormal);
|
weightedSums += evalTapWeightedValue(blurScales, side, r, occlusionTexCoord, fragDepthKey, fragNormal);
|
||||||
|
occlusionTexCoord += getBlurOcclusionAxis();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final normalization
|
// Final normalization
|
||||||
|
|
|
@ -60,8 +60,9 @@ void main(void) {
|
||||||
fragFrameES.tangent = vec3(0.0);
|
fragFrameES.tangent = vec3(0.0);
|
||||||
fragFrameES.binormal = vec3(0.0);
|
fragFrameES.binormal = vec3(0.0);
|
||||||
fragFrameES.normal = fragNormalES;
|
fragFrameES.normal = fragNormalES;
|
||||||
|
#if HBAO_USE_OVERHANG_HACK || !HBAO_USE_COS_ANGLE
|
||||||
buildTangentBinormal(side, fragUVPos, fragPositionES, fragNormalES, deltaDepthUV, fragFrameES.tangent, fragFrameES.binormal);
|
buildTangentBinormal(side, fragUVPos, fragPositionES, fragNormalES, deltaDepthUV, fragFrameES.tangent, fragFrameES.binormal);
|
||||||
|
#endif
|
||||||
// Let's make noise
|
// Let's make noise
|
||||||
float randomPatternRotationAngle = getAngleDithering(fragPixelPos);
|
float randomPatternRotationAngle = getAngleDithering(fragPixelPos);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue