mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Fixed for any resolution level in stereo
This commit is contained in:
parent
b1db7ab403
commit
d5d0f056a9
5 changed files with 45 additions and 28 deletions
|
@ -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
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue