From acc6d0b79eb6b4d26d4b8c5a44e6bd874e25cb83 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Tue, 18 Sep 2018 10:22:35 +0200 Subject: [PATCH] Fixed wrong AO with far objects! --- .../render-utils/src/SurfaceGeometryPass.cpp | 4 +-- libraries/render-utils/src/ssao.slh | 12 ++++---- .../render-utils/src/ssao_makeOcclusion.slf | 28 +++++++++---------- libraries/render-utils/src/ssao_mip_depth.slf | 9 ++---- 4 files changed, 25 insertions(+), 28 deletions(-) diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index f22b8351d4..d2bff5b322 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -66,7 +66,7 @@ void LinearDepthFramebuffer::allocate() { // For Linear Depth: const uint16_t LINEAR_DEPTH_MAX_MIP_LEVEL = 5; _linearDepthTexture = gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RED), width, height, LINEAR_DEPTH_MAX_MIP_LEVEL, - gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT, gpu::Sampler::WRAP_CLAMP)); + gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_POINT, gpu::Sampler::WRAP_CLAMP)); _linearDepthFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("linearDepth")); _linearDepthFramebuffer->setRenderBuffer(0, _linearDepthTexture); _linearDepthFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, _primaryDepthTexture->getTexelFormat()); @@ -74,7 +74,7 @@ void LinearDepthFramebuffer::allocate() { // For Downsampling: const uint16_t HALF_LINEAR_DEPTH_MAX_MIP_LEVEL = LINEAR_DEPTH_MAX_MIP_LEVEL; _halfLinearDepthTexture = gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RED), _halfFrameSize.x, _halfFrameSize.y, HALF_LINEAR_DEPTH_MAX_MIP_LEVEL, - gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT, gpu::Sampler::WRAP_CLAMP)); + gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_POINT, gpu::Sampler::WRAP_CLAMP)); _halfNormalTexture = gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, _halfFrameSize.x, _halfFrameSize.y, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)); diff --git a/libraries/render-utils/src/ssao.slh b/libraries/render-utils/src/ssao.slh index ab728553f1..051f685e2d 100644 --- a/libraries/render-utils/src/ssao.slh +++ b/libraries/render-utils/src/ssao.slh @@ -226,7 +226,7 @@ float getZEyeAtUV(vec2 texCoord, int level) { return -texture(pyramidMap, texCoord, level).x; } -const int LOG_MAX_OFFSET = 1; +const int LOG_MAX_OFFSET = 2; const int MAX_MIP_LEVEL = 5; int evalMipFromRadius(float radius) { // mipLevel = floor(log(ssR / MAX_OFFSET)); @@ -289,10 +289,12 @@ float evalVisibilitySSAO(in vec3 centerPosition, in vec3 centerNormal, in vec3 t } float computeHorizonFromTap(vec3 tapPositionES, vec3 fragPositionES, vec3 fragNormalES) { + const float epsilon = 0.01; + vec3 deltaVec = tapPositionES - fragPositionES; - float distanceSquared = dot(deltaVec, deltaVec); - float cosHorizonAngle = dot(normalize(deltaVec), fragNormalES); - float radiusFalloff = max(0.0, 1.0 - (distanceSquared / getRadius2())); + float distance = length(deltaVec); + float cosHorizonAngle = dot(deltaVec, fragNormalES) / (distance + epsilon); + float radiusFalloff = max(0.0, 1.0 - (distance*distance / getRadius2())); cosHorizonAngle = max(0.0, (cosHorizonAngle - getFalloffAngle()) / (1.0 - getFalloffAngle())); cosHorizonAngle *= radiusFalloff; @@ -313,7 +315,7 @@ float computeHorizonFromTap(vec3 tapPositionES, vec3 fragPositionES, vec3 fragNo <@endfunc@> -#define SSAO_LINEAR_SEARCH_HORIZON 1 +#define SSAO_LINEAR_SEARCH_HORIZON 0 float computeHorizon(ivec4 side, vec2 shadedPixelPos, vec2 sideImageSize, vec2 deltaTap, vec3 fragPositionES, vec3 fragNormalES, vec2 searchVec, float searchRadius) { diff --git a/libraries/render-utils/src/ssao_makeOcclusion.slf b/libraries/render-utils/src/ssao_makeOcclusion.slf index a28b06cea1..94e87c75e0 100644 --- a/libraries/render-utils/src/ssao_makeOcclusion.slf +++ b/libraries/render-utils/src/ssao_makeOcclusion.slf @@ -29,20 +29,20 @@ void main(void) { // Pixel being shaded vec2 fragCoord = gl_FragCoord.xy; - ivec2 shadedPixelPos = ivec2(fragCoord.xy); + ivec2 fragPixelPos = ivec2(fragCoord.xy); // Stereo side info - ivec4 side = getStereoSideInfo(shadedPixelPos.x, getResolutionLevel()); + ivec4 side = getStereoSideInfo(fragPixelPos.x, getResolutionLevel()); - // From now on, shadedPixelPos is the pixel pos in the side - shadedPixelPos.x -= side.y; - vec2 shadedUVPos = (vec2(shadedPixelPos) + vec2(0.5)) / sideImageSize; + // From now on, fragPixelPos is the pixel pos in the side + fragPixelPos.x -= side.y; + vec2 fragUVPos = (vec2(fragPixelPos) + vec2(0.5)) / sideImageSize; // Fetch the z under the pixel (stereo or not) - float Zeye = getZEyeAtUV(shadedUVPos, 0); + float Zeye = getZEyeAtUV(fragUVPos, 0); // The position and normal of the pixel fragment in Eye space - vec3 fragPositionES = evalEyePositionFromZeye(side.x, Zeye, shadedUVPos); + vec3 fragPositionES = evalEyePositionFromZeye(side.x, Zeye, fragUVPos); vec3 fragNormalES = evalEyeNormal(fragPositionES); // Choose the screen-space sample radius @@ -52,7 +52,7 @@ void main(void) { #endif // Let's make noise - float randomPatternRotationAngle = getAngleDithering(shadedPixelPos); + float randomPatternRotationAngle = getAngleDithering(fragPixelPos); // Accumulate the obscurance for each samples float obscuranceSum = 0.0; @@ -60,12 +60,10 @@ void main(void) { for (int i = 0; i < numSamples; ++i) { #if SSAO_USE_HORIZON_BASED vec3 deltaTap = getUnitTapLocation(i, 1.0, randomPatternRotationAngle, PI); - // TEMPO OP - deltaTap.xy = vec2(1,0); - obscuranceSum += evalVisibilityHBAO(side, vec2(shadedPixelPos), sideImageSize, deltaTap.xy, diskPixelRadius, fragPositionES, fragNormalES); + obscuranceSum += evalVisibilityHBAO(side, vec2(fragPixelPos), sideImageSize, deltaTap.xy, diskPixelRadius, fragPositionES, fragNormalES); #else - vec3 tap = getTapLocationClampedSSAO(i, randomPatternRotationAngle, diskPixelRadius, shadedPixelPos, sideImageSize); - vec2 tapPixelPos = vec2(shadedPixelPos) + tap.xy; + vec3 tap = getTapLocationClampedSSAO(i, randomPatternRotationAngle, diskPixelRadius, fragPixelPos, sideImageSize); + vec2 tapPixelPos = vec2(fragPixelPos) + tap.xy; vec3 tapUVZ = fetchTap(side, tapPixelPos, tap.z, sideImageSize); vec3 tapPositionES = evalEyePositionFromZeye(side.x, tapUVZ.z, tapUVZ.xy); obscuranceSum += float(tap.z > 0.0) * evalVisibilitySSAO(fragPositionES, fragNormalES, tapPositionES); @@ -78,10 +76,10 @@ void main(void) { // Bilateral box-filter over a quad for free, respecting depth edges // (the difference that this makes is subtle) /* if (abs(dFdx(fragPositionES.z)) < 0.02) { - occlusion -= dFdx(occlusion) * ((shadedPixelPos.x & 1) - 0.5); + occlusion -= dFdx(occlusion) * ((fragPixelPos.x & 1) - 0.5); } if (abs(dFdy(fragPositionES.z)) < 0.02) { - occlusion -= dFdy(occlusion) * ((shadedPixelPos.y & 1) - 0.5); + occlusion -= dFdy(occlusion) * ((fragPixelPos.y & 1) - 0.5); }*/ //outFragColor = vec4(packOcclusionDepth(occlusion, CSZToDepthKey(fragPositionES.z)), 1.0); diff --git a/libraries/render-utils/src/ssao_mip_depth.slf b/libraries/render-utils/src/ssao_mip_depth.slf index 6a72af704c..49f3d5254f 100644 --- a/libraries/render-utils/src/ssao_mip_depth.slf +++ b/libraries/render-utils/src/ssao_mip_depth.slf @@ -22,7 +22,7 @@ void main(void) { vec4 depths = textureGather(depthTexture, varTexCoord0); // Order the depths from minimum to maximum -/* depths.xy = depths.x > depths.y ? depths.yx : depths.xy; + depths.xy = depths.x > depths.y ? depths.yx : depths.xy; depths.xz = depths.x > depths.z ? depths.zx : depths.xz; depths.xw = depths.x > depths.w ? depths.wx : depths.xw; @@ -31,11 +31,8 @@ void main(void) { depths.zw = depths.z > depths.w ? depths.wz : depths.zw; - float outZ = (depths.y + depths.z) / 2.0;*/ - - float outZ = min(depths.x, depths.y); - outZ = min(outZ, depths.z); - outZ = min(outZ, depths.w); + // Take the median depth + float outZ = (depths.y + depths.z) / 2.0; outFragColor = vec4(vec3(outZ), 1.0); }