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

View file

@ -31,8 +31,8 @@ public:
gpu::FramebufferPointer getOcclusionBlurredFramebuffer();
gpu::TexturePointer getOcclusionBlurredTexture();
gpu::FramebufferPointer getNormalFramebuffer();
gpu::TexturePointer getNormalTexture();
gpu::FramebufferPointer getNormalFramebuffer(int resolutionLevel);
gpu::TexturePointer getNormalTexture(int resolutionLevel);
// Update the source framebuffer size which will drive the allocation of all the other resources.
bool updateLinearDepth(const gpu::TexturePointer& linearDepthBuffer);
@ -40,8 +40,10 @@ public:
const glm::ivec2& getSourceFrameSize() const { return _frameSize; }
protected:
void clear();
void allocate();
void allocate(int resolutionLevel);
gpu::TexturePointer _linearDepthTexture;
@ -56,6 +58,7 @@ protected:
glm::ivec2 _frameSize;
int _resolutionLevel{ 0 };
};
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_NORMAL) uniform sampler2D normalTex;
ivec2 getDepthTextureSize(int level) {
return textureSize(depthPyramidTex, level);
}
float getZEyeAtPixel(ivec2 pixel, int level) {
return -texelFetch(depthPyramidTex, pixel, level).x;
}

View file

@ -18,17 +18,19 @@
layout(location=0) out vec4 outFragColor;
void main(void) {
vec2 sideImageSize = getStereoSideSize(0);
vec2 sideImageSize = getStereoSideSize(getResolutionLevel());
ivec2 renderSize = ivec2(sideImageSize) << ivec2(int(isStereo()) & 1, 0);
// Pixel being shaded
vec2 fragCoord = gl_FragCoord.xy;
ivec2 fragPixelPos = ivec2(fragCoord.xy);
// 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
ivec4 side = getStereoSideInfo(fragPixelPos.x, 0);
ivec4 side = getStereoSideInfo(fragPixelPos.x, getResolutionLevel());
// From now on, fragPixelPos is the pixel pos in the side
fragPixelPos.x -= side.y;
@ -39,7 +41,5 @@ void main(void) {
vec3 fragNormalES = evalEyeNormal(fragPositionES);
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);
}

View file

@ -25,6 +25,7 @@ layout(location=0) out vec4 outFragColor;
void main(void) {
vec2 sideImageSize = getStereoSideSize(getResolutionLevel());
ivec2 renderSize = ivec2(sideImageSize) << ivec2(int(isStereo()) & 1, 0);
// Pixel being shaded
vec2 fragCoord = gl_FragCoord.xy;
@ -35,7 +36,8 @@ void main(void) {
#endif
// 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
vec3 fragNormalES = getNormalEyeAtPixel(fragPixelPos, 0);
#endif