Fixed for any resolution level in stereo

This commit is contained in:
Olivier Prat 2018-09-20 11:15:25 +02:00
parent b1db7ab403
commit d5d0f056a9
5 changed files with 45 additions and 28 deletions

View file

@ -87,10 +87,6 @@ void AmbientOcclusionFramebuffer::allocate() {
_occlusionBlurredTexture = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR, gpu::Sampler::WRAP_CLAMP)); _occlusionBlurredTexture = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR, gpu::Sampler::WRAP_CLAMP));
_occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusionBlurred")); _occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusionBlurred"));
_occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture); _occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture);
_normalTexture = gpu::Texture::createRenderBuffer(gpu::Element::COLOR_R11G11B10, width, height, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT, gpu::Sampler::WRAP_CLAMP));
_normalFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("ssaoNormals"));
_normalFramebuffer->setRenderBuffer(0, _normalTexture);
} }
gpu::FramebufferPointer AmbientOcclusionFramebuffer::getOcclusionFramebuffer() { gpu::FramebufferPointer AmbientOcclusionFramebuffer::getOcclusionFramebuffer() {
@ -121,16 +117,26 @@ gpu::TexturePointer AmbientOcclusionFramebuffer::getOcclusionBlurredTexture() {
return _occlusionBlurredTexture; return _occlusionBlurredTexture;
} }
gpu::FramebufferPointer AmbientOcclusionFramebuffer::getNormalFramebuffer() { void AmbientOcclusionFramebuffer::allocate(int resolutionLevel) {
if (!_normalFramebuffer) { auto width = _frameSize.x >> resolutionLevel;
allocate(); auto height = _frameSize.y >> resolutionLevel;
_normalTexture = gpu::Texture::createRenderBuffer(gpu::Element::COLOR_R11G11B10, width, height, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT, gpu::Sampler::WRAP_CLAMP));
_normalFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("ssaoNormals"));
_normalFramebuffer->setRenderBuffer(0, _normalTexture);
_resolutionLevel = resolutionLevel;
}
gpu::FramebufferPointer AmbientOcclusionFramebuffer::getNormalFramebuffer(int resolutionLevel) {
if (!_normalFramebuffer || resolutionLevel != _resolutionLevel) {
allocate(resolutionLevel);
} }
return _normalFramebuffer; return _normalFramebuffer;
} }
gpu::TexturePointer AmbientOcclusionFramebuffer::getNormalTexture() { gpu::TexturePointer AmbientOcclusionFramebuffer::getNormalTexture(int resolutionLevel) {
if (!_normalTexture) { if (!_normalTexture || resolutionLevel != _resolutionLevel) {
allocate(); allocate(resolutionLevel);
} }
return _normalTexture; return _normalTexture;
} }
@ -208,11 +214,11 @@ AmbientOcclusionEffectConfig::AmbientOcclusionEffectConfig() :
blurDeviation{ 2.5f }, blurDeviation{ 2.5f },
numSpiralTurns{ 7.0f }, numSpiralTurns{ 7.0f },
#if SSAO_USE_HORIZON_BASED #if SSAO_USE_HORIZON_BASED
numSamples{ 2 }, numSamples{ 3 },
#else #else
numSamples{ 16 }, numSamples{ 16 },
#endif #endif
resolutionLevel{ 0 }, resolutionLevel{ 2 },
blurRadius{ 4 }, blurRadius{ 4 },
ditheringEnabled{ true }, ditheringEnabled{ true },
borderingEnabled{ true }, borderingEnabled{ true },
@ -470,10 +476,11 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
_framebuffer = std::make_shared<AmbientOcclusionFramebuffer>(); _framebuffer = std::make_shared<AmbientOcclusionFramebuffer>();
} }
const auto resolutionScale = powf(0.5f, _aoParametersBuffer->getResolutionLevel()); const int resolutionLevel = _aoParametersBuffer->getResolutionLevel();
if (_aoParametersBuffer->getResolutionLevel() > 0) { const auto resolutionScale = powf(0.5f, resolutionLevel);
occlusionViewport = occlusionViewport >> _aoParametersBuffer->getResolutionLevel(); if (resolutionLevel > 0) {
firstBlurViewport.w = firstBlurViewport.w >> _aoParametersBuffer->getResolutionLevel(); occlusionViewport = occlusionViewport >> resolutionLevel;
firstBlurViewport.w = firstBlurViewport.w >> resolutionLevel;
occlusionDepthTexture = linearDepthFramebuffer->getHalfLinearDepthTexture(); occlusionDepthTexture = linearDepthFramebuffer->getHalfLinearDepthTexture();
} }
@ -498,8 +505,8 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
#if SSAO_USE_QUAD_SPLIT #if SSAO_USE_QUAD_SPLIT
auto gatherPipeline = getGatherPipeline(); auto gatherPipeline = getGatherPipeline();
auto buildNormalsPipeline = getBuildNormalsPipeline(); auto buildNormalsPipeline = getBuildNormalsPipeline();
auto occlusionNormalFramebuffer = _framebuffer->getNormalFramebuffer(); auto occlusionNormalFramebuffer = _framebuffer->getNormalFramebuffer(resolutionLevel);
auto occlusionNormalTexture = _framebuffer->getNormalTexture(); auto occlusionNormalTexture = _framebuffer->getNormalTexture(resolutionLevel);
#endif #endif
auto fullNormalTexture = linearDepthFramebuffer->getNormalTexture(); auto fullNormalTexture = linearDepthFramebuffer->getNormalTexture();
@ -536,12 +543,13 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
#if SSAO_USE_QUAD_SPLIT #if SSAO_USE_QUAD_SPLIT
// Build derivative normals pass // Build derivative normals pass
batch.pushProfileRange("Build Normals"); batch.pushProfileRange("Build Normals");
batch.setViewportTransform(sourceViewport); batch.setViewportTransform(occlusionViewport);
batch.setPipeline(buildNormalsPipeline); batch.setPipeline(buildNormalsPipeline);
batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, linearDepthTexture);
batch.setResourceTexture(render_utils::slot::texture::SsaoNormal, nullptr);
batch.setUniformBuffer(render_utils::slot::buffer::DeferredFrameTransform, frameTransform->getFrameTransformBuffer()); batch.setUniformBuffer(render_utils::slot::buffer::DeferredFrameTransform, frameTransform->getFrameTransformBuffer());
batch.setUniformBuffer(render_utils::slot::buffer::SsaoParams, _aoParametersBuffer); batch.setUniformBuffer(render_utils::slot::buffer::SsaoParams, _aoParametersBuffer);
batch.setFramebuffer(occlusionNormalFramebuffer); batch.setFramebuffer(occlusionNormalFramebuffer);
batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, linearDepthTexture);
batch.draw(gpu::TRIANGLE_STRIP, 4); batch.draw(gpu::TRIANGLE_STRIP, 4);
batch.popProfileRange(); batch.popProfileRange();
#endif #endif

View file

@ -31,8 +31,8 @@ public:
gpu::FramebufferPointer getOcclusionBlurredFramebuffer(); gpu::FramebufferPointer getOcclusionBlurredFramebuffer();
gpu::TexturePointer getOcclusionBlurredTexture(); gpu::TexturePointer getOcclusionBlurredTexture();
gpu::FramebufferPointer getNormalFramebuffer(); gpu::FramebufferPointer getNormalFramebuffer(int resolutionLevel);
gpu::TexturePointer getNormalTexture(); gpu::TexturePointer getNormalTexture(int resolutionLevel);
// Update the source framebuffer size which will drive the allocation of all the other resources. // Update the source framebuffer size which will drive the allocation of all the other resources.
bool updateLinearDepth(const gpu::TexturePointer& linearDepthBuffer); bool updateLinearDepth(const gpu::TexturePointer& linearDepthBuffer);
@ -40,8 +40,10 @@ public:
const glm::ivec2& getSourceFrameSize() const { return _frameSize; } const glm::ivec2& getSourceFrameSize() const { return _frameSize; }
protected: protected:
void clear(); void clear();
void allocate(); void allocate();
void allocate(int resolutionLevel);
gpu::TexturePointer _linearDepthTexture; gpu::TexturePointer _linearDepthTexture;
@ -56,6 +58,7 @@ protected:
glm::ivec2 _frameSize; glm::ivec2 _frameSize;
int _resolutionLevel{ 0 };
}; };
using AmbientOcclusionFramebufferPointer = std::shared_ptr<AmbientOcclusionFramebuffer>; using AmbientOcclusionFramebufferPointer = std::shared_ptr<AmbientOcclusionFramebuffer>;

View file

@ -202,6 +202,10 @@ vec3 getTapLocationClampedSSAO(int sampleNumber, float spinAngle, float outerRad
layout(binding=RENDER_UTILS_TEXTURE_SSAO_DEPTH) uniform sampler2D depthPyramidTex; layout(binding=RENDER_UTILS_TEXTURE_SSAO_DEPTH) uniform sampler2D depthPyramidTex;
layout(binding=RENDER_UTILS_TEXTURE_SSAO_NORMAL) uniform sampler2D normalTex; layout(binding=RENDER_UTILS_TEXTURE_SSAO_NORMAL) uniform sampler2D normalTex;
ivec2 getDepthTextureSize(int level) {
return textureSize(depthPyramidTex, level);
}
float getZEyeAtPixel(ivec2 pixel, int level) { float getZEyeAtPixel(ivec2 pixel, int level) {
return -texelFetch(depthPyramidTex, pixel, level).x; return -texelFetch(depthPyramidTex, pixel, level).x;
} }

View file

@ -18,17 +18,19 @@
layout(location=0) out vec4 outFragColor; layout(location=0) out vec4 outFragColor;
void main(void) { void main(void) {
vec2 sideImageSize = getStereoSideSize(0); vec2 sideImageSize = getStereoSideSize(getResolutionLevel());
ivec2 renderSize = ivec2(sideImageSize) << ivec2(int(isStereo()) & 1, 0);
// Pixel being shaded // Pixel being shaded
vec2 fragCoord = gl_FragCoord.xy; vec2 fragCoord = gl_FragCoord.xy;
ivec2 fragPixelPos = ivec2(fragCoord.xy); ivec2 fragPixelPos = ivec2(fragCoord.xy);
// Fetch the z under the pixel (stereo or not) // Fetch the z under the pixel (stereo or not)
float Zeye = getZEyeAtPixel(fragPixelPos, 0); ivec2 depthTexFragPixelPos = fragPixelPos * getDepthTextureSize(0) / renderSize ;
float Zeye = getZEyeAtPixel(depthTexFragPixelPos, 0);
// Stereo side info // Stereo side info
ivec4 side = getStereoSideInfo(fragPixelPos.x, 0); ivec4 side = getStereoSideInfo(fragPixelPos.x, getResolutionLevel());
// From now on, fragPixelPos is the pixel pos in the side // From now on, fragPixelPos is the pixel pos in the side
fragPixelPos.x -= side.y; fragPixelPos.x -= side.y;
@ -39,7 +41,5 @@ void main(void) {
vec3 fragNormalES = evalEyeNormal(fragPositionES); vec3 fragNormalES = evalEyeNormal(fragPositionES);
vec3 absFragNormalES = abs(fragNormalES); vec3 absFragNormalES = abs(fragNormalES);
// Maximize encoding precision
fragNormalES /= max(max(absFragNormalES.x, absFragNormalES.y), absFragNormalES.z);
outFragColor = vec4(vec3(fragNormalES)*0.5 + vec3(0.5), 1.0); outFragColor = vec4(vec3(fragNormalES)*0.5 + vec3(0.5), 1.0);
} }

View file

@ -25,6 +25,7 @@ layout(location=0) out vec4 outFragColor;
void main(void) { void main(void) {
vec2 sideImageSize = getStereoSideSize(getResolutionLevel()); vec2 sideImageSize = getStereoSideSize(getResolutionLevel());
ivec2 renderSize = ivec2(sideImageSize) << ivec2(int(isStereo()) & 1, 0);
// Pixel being shaded // Pixel being shaded
vec2 fragCoord = gl_FragCoord.xy; vec2 fragCoord = gl_FragCoord.xy;
@ -35,7 +36,8 @@ void main(void) {
#endif #endif
// Fetch the z under the pixel (stereo or not) // Fetch the z under the pixel (stereo or not)
float Zeye = getZEyeAtPixel(fragPixelPos, 0); ivec2 depthTexFragPixelPos = fragPixelPos * getDepthTextureSize(0) / renderSize ;
float Zeye = getZEyeAtPixel(depthTexFragPixelPos, 0);
#if SSAO_USE_QUAD_SPLIT #if SSAO_USE_QUAD_SPLIT
vec3 fragNormalES = getNormalEyeAtPixel(fragPixelPos, 0); vec3 fragNormalES = getNormalEyeAtPixel(fragPixelPos, 0);
#endif #endif