mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 19:41:20 +02:00
Fixed bugs in stereo
This commit is contained in:
parent
086ba998c8
commit
9f9fe909b0
4 changed files with 56 additions and 42 deletions
|
@ -92,12 +92,13 @@ void AmbientOcclusionFramebuffer::allocate() {
|
||||||
{
|
{
|
||||||
auto width = _frameSize.x;
|
auto width = _frameSize.x;
|
||||||
auto height = _frameSize.y;
|
auto height = _frameSize.y;
|
||||||
|
auto sampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR, gpu::Sampler::WRAP_CLAMP);
|
||||||
|
|
||||||
_occlusionTexture = gpu::Texture::createRenderBuffer(occlusionformat, width, height, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR, gpu::Sampler::WRAP_CLAMP));
|
_occlusionTexture = gpu::Texture::createRenderBuffer(occlusionformat, width, height, gpu::Texture::SINGLE_MIP, sampler);
|
||||||
_occlusionFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusion"));
|
_occlusionFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusion"));
|
||||||
_occlusionFramebuffer->setRenderBuffer(0, _occlusionTexture);
|
_occlusionFramebuffer->setRenderBuffer(0, _occlusionTexture);
|
||||||
|
|
||||||
_occlusionBlurredTexture = gpu::Texture::createRenderBuffer(occlusionformat, width, height, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR, gpu::Sampler::WRAP_CLAMP));
|
_occlusionBlurredTexture = gpu::Texture::createRenderBuffer(occlusionformat, width, height, gpu::Texture::SINGLE_MIP, sampler);
|
||||||
_occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusionBlurred"));
|
_occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusionBlurred"));
|
||||||
_occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture);
|
_occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture);
|
||||||
}
|
}
|
||||||
|
@ -108,7 +109,7 @@ void AmbientOcclusionFramebuffer::allocate() {
|
||||||
if (_isStereo) {
|
if (_isStereo) {
|
||||||
sideSize.x >>= 1;
|
sideSize.x >>= 1;
|
||||||
}
|
}
|
||||||
sideSize = divideRoundUp(sideSize, 1 << _resolutionLevel);
|
sideSize >>= _resolutionLevel;
|
||||||
if (_isStereo) {
|
if (_isStereo) {
|
||||||
sideSize.x <<= 1;
|
sideSize.x <<= 1;
|
||||||
}
|
}
|
||||||
|
@ -127,7 +128,7 @@ void AmbientOcclusionFramebuffer::allocate() {
|
||||||
if (_isStereo) {
|
if (_isStereo) {
|
||||||
splitSize.x >>= 1;
|
splitSize.x >>= 1;
|
||||||
}
|
}
|
||||||
splitSize = divideRoundUp(splitSize, SSAO_SPLIT_COUNT << _resolutionLevel);
|
splitSize = divideRoundUp(_frameSize >> _resolutionLevel, SSAO_SPLIT_COUNT);
|
||||||
if (_isStereo) {
|
if (_isStereo) {
|
||||||
splitSize.x <<= 1;
|
splitSize.x <<= 1;
|
||||||
}
|
}
|
||||||
|
@ -355,14 +356,13 @@ void AmbientOcclusionEffect::configure(const Config& config) {
|
||||||
|
|
||||||
void AmbientOcclusionEffect::updateBlurParameters() {
|
void AmbientOcclusionEffect::updateBlurParameters() {
|
||||||
const auto resolutionLevel = _aoParametersBuffer->getResolutionLevel();
|
const auto resolutionLevel = _aoParametersBuffer->getResolutionLevel();
|
||||||
const auto resolutionScale = 1 << resolutionLevel;
|
|
||||||
auto& vblur = _vblurParametersBuffer.edit();
|
auto& vblur = _vblurParametersBuffer.edit();
|
||||||
auto& hblur = _hblurParametersBuffer.edit();
|
auto& hblur = _hblurParametersBuffer.edit();
|
||||||
auto frameSize = _framebuffer->getSourceFrameSize();
|
auto frameSize = _framebuffer->getSourceFrameSize();
|
||||||
if (_framebuffer->isStereo()) {
|
if (_framebuffer->isStereo()) {
|
||||||
frameSize.x >>= 1;
|
frameSize.x >>= 1;
|
||||||
}
|
}
|
||||||
const auto occlusionSize = divideRoundUp(frameSize, resolutionScale);
|
const auto occlusionSize = frameSize >> resolutionLevel;
|
||||||
|
|
||||||
// Occlusion UV limit
|
// Occlusion UV limit
|
||||||
hblur._blurAxis.z = occlusionSize.x / float(frameSize.x);
|
hblur._blurAxis.z = occlusionSize.x / float(frameSize.x);
|
||||||
|
@ -381,18 +381,17 @@ void AmbientOcclusionEffect::updateBlurParameters() {
|
||||||
|
|
||||||
void AmbientOcclusionEffect::updateFramebufferSizes() {
|
void AmbientOcclusionEffect::updateFramebufferSizes() {
|
||||||
auto& params = _aoParametersBuffer.edit();
|
auto& params = _aoParametersBuffer.edit();
|
||||||
const int widthScale = _framebuffer->isStereo() & 1;
|
const int stereoDivide = _framebuffer->isStereo() & 1;
|
||||||
auto sourceFrameSideSize = _framebuffer->getSourceFrameSize();
|
auto sourceFrameSideSize = _framebuffer->getSourceFrameSize();
|
||||||
sourceFrameSideSize.x >>= widthScale;
|
sourceFrameSideSize.x >>= stereoDivide;
|
||||||
|
|
||||||
const int resolutionLevel = _aoParametersBuffer.get().getResolutionLevel();
|
const int resolutionLevel = _aoParametersBuffer.get().getResolutionLevel();
|
||||||
// Depth is at maximum half depth
|
|
||||||
const int depthResolutionLevel = getDepthResolutionLevel();
|
const int depthResolutionLevel = getDepthResolutionLevel();
|
||||||
const auto occlusionDepthFrameSize = divideRoundUp(sourceFrameSideSize, 1 << depthResolutionLevel);
|
const auto occlusionDepthFrameSize = sourceFrameSideSize >> depthResolutionLevel;
|
||||||
const auto occlusionFrameSize = divideRoundUp(sourceFrameSideSize, 1 << resolutionLevel);
|
const auto occlusionFrameSize = sourceFrameSideSize >> resolutionLevel;
|
||||||
auto normalTextureSize = _framebuffer->getNormalTexture()->getDimensions();
|
auto normalTextureSize = _framebuffer->getNormalTexture()->getDimensions();
|
||||||
|
|
||||||
normalTextureSize.x >>= widthScale;
|
normalTextureSize.x >>= stereoDivide;
|
||||||
|
|
||||||
params._sideSizes[0].x = normalTextureSize.x;
|
params._sideSizes[0].x = normalTextureSize.x;
|
||||||
params._sideSizes[0].y = normalTextureSize.y;
|
params._sideSizes[0].y = normalTextureSize.y;
|
||||||
|
@ -485,12 +484,10 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
||||||
const auto depthResolutionScale = powf(0.5f, depthResolutionLevel);
|
const auto depthResolutionScale = powf(0.5f, depthResolutionLevel);
|
||||||
const auto isHorizonBased = _aoParametersBuffer->isHorizonBased();
|
const auto isHorizonBased = _aoParametersBuffer->isHorizonBased();
|
||||||
|
|
||||||
auto linearDepthTexture = linearDepthFramebuffer->getLinearDepthTexture();
|
auto fullResDepthTexture = linearDepthFramebuffer->getLinearDepthTexture();
|
||||||
auto occlusionDepthTexture = linearDepthTexture;
|
auto occlusionDepthTexture = fullResDepthTexture;
|
||||||
auto sourceViewport = args->_viewport;
|
auto sourceViewport = args->_viewport;
|
||||||
// divideRoundUp is used two compute the quarter or half resolution render sizes.
|
auto occlusionViewport = sourceViewport >> resolutionLevel;
|
||||||
// We choose to take the rounded up resolution.
|
|
||||||
auto occlusionViewport = divideRoundUp(sourceViewport, 1 << resolutionLevel);
|
|
||||||
auto firstBlurViewport = sourceViewport;
|
auto firstBlurViewport = sourceViewport;
|
||||||
firstBlurViewport.w = occlusionViewport.w;
|
firstBlurViewport.w = occlusionViewport.w;
|
||||||
|
|
||||||
|
@ -506,7 +503,7 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
||||||
occlusionDepthTexture = linearDepthFramebuffer->getHalfLinearDepthTexture();
|
occlusionDepthTexture = linearDepthFramebuffer->getHalfLinearDepthTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_framebuffer->update(linearDepthTexture, resolutionLevel, depthResolutionLevel, args->isStereo())) {
|
if (_framebuffer->update(fullResDepthTexture, resolutionLevel, depthResolutionLevel, args->isStereo())) {
|
||||||
updateBlurParameters();
|
updateBlurParameters();
|
||||||
updateFramebufferSizes();
|
updateFramebufferSizes();
|
||||||
}
|
}
|
||||||
|
@ -538,7 +535,7 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
||||||
auto& sample = _aoFrameParametersBuffer[splitId].edit();
|
auto& sample = _aoFrameParametersBuffer[splitId].edit();
|
||||||
sample._angleInfo.x = _randomSamples[splitId + SSAO_RANDOM_SAMPLE_COUNT * _frameId];
|
sample._angleInfo.x = _randomSamples[splitId + SSAO_RANDOM_SAMPLE_COUNT * _frameId];
|
||||||
}
|
}
|
||||||
// _frameId = (_frameId + 1) % SSAO_RANDOM_SAMPLE_COUNT;
|
_frameId = (_frameId + 1) % SSAO_RANDOM_SAMPLE_COUNT;
|
||||||
|
|
||||||
gpu::doInBatch("AmbientOcclusionEffect::run", args->_context, [=](gpu::Batch& batch) {
|
gpu::doInBatch("AmbientOcclusionEffect::run", args->_context, [=](gpu::Batch& batch) {
|
||||||
PROFILE_RANGE_BATCH(batch, "SSAO");
|
PROFILE_RANGE_BATCH(batch, "SSAO");
|
||||||
|
@ -567,7 +564,7 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
||||||
batch.setModelTransform(Transform());
|
batch.setModelTransform(Transform());
|
||||||
batch.setViewportTransform(normalViewport);
|
batch.setViewportTransform(normalViewport);
|
||||||
batch.setPipeline(buildNormalsPipeline);
|
batch.setPipeline(buildNormalsPipeline);
|
||||||
batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, linearDepthTexture);
|
batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, fullResDepthTexture);
|
||||||
batch.setResourceTexture(render_utils::slot::texture::SsaoNormal, nullptr);
|
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);
|
||||||
|
@ -651,8 +648,8 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
||||||
batch.setModelTransform(model);
|
batch.setModelTransform(model);
|
||||||
}
|
}
|
||||||
batch.setPipeline(bilateralBlurPipeline);
|
batch.setPipeline(bilateralBlurPipeline);
|
||||||
// Use full resolution depth and normal for bilateral upscaling and blur
|
// Use full resolution depth for bilateral upscaling and blur
|
||||||
batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, linearDepthTexture);
|
batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, fullResDepthTexture);
|
||||||
#if SSAO_USE_QUAD_SPLIT
|
#if SSAO_USE_QUAD_SPLIT
|
||||||
batch.setResourceTexture(render_utils::slot::texture::SsaoNormal, occlusionNormalTexture);
|
batch.setResourceTexture(render_utils::slot::texture::SsaoNormal, occlusionNormalTexture);
|
||||||
#else
|
#else
|
||||||
|
@ -742,18 +739,18 @@ void DebugAmbientOcclusion::run(const render::RenderContextPointer& renderContex
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto linearDepthTexture = linearDepthFramebuffer->getLinearDepthTexture();
|
auto fullResDepthTexture = linearDepthFramebuffer->getLinearDepthTexture();
|
||||||
auto sourceViewport = args->_viewport;
|
auto sourceViewport = args->_viewport;
|
||||||
auto occlusionViewport = sourceViewport;
|
auto occlusionViewport = sourceViewport;
|
||||||
|
|
||||||
auto resolutionLevel = ambientOcclusionUniforms->getResolutionLevel();
|
auto resolutionLevel = ambientOcclusionUniforms->getResolutionLevel();
|
||||||
|
|
||||||
if (resolutionLevel > 0) {
|
if (resolutionLevel > 0) {
|
||||||
linearDepthTexture = linearDepthFramebuffer->getHalfLinearDepthTexture();
|
fullResDepthTexture = linearDepthFramebuffer->getHalfLinearDepthTexture();
|
||||||
occlusionViewport = occlusionViewport >> ambientOcclusionUniforms->getResolutionLevel();
|
occlusionViewport = occlusionViewport >> ambientOcclusionUniforms->getResolutionLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto framebufferSize = glm::ivec2(linearDepthTexture->getDimensions());
|
auto framebufferSize = glm::ivec2(fullResDepthTexture->getDimensions());
|
||||||
|
|
||||||
float sMin = occlusionViewport.x / (float)framebufferSize.x;
|
float sMin = occlusionViewport.x / (float)framebufferSize.x;
|
||||||
float sWidth = occlusionViewport.z / (float)framebufferSize.x;
|
float sWidth = occlusionViewport.z / (float)framebufferSize.x;
|
||||||
|
@ -779,7 +776,7 @@ void DebugAmbientOcclusion::run(const render::RenderContextPointer& renderContex
|
||||||
batch.setUniformBuffer(render_utils::slot::buffer::SsaoDebugParams, _parametersBuffer);
|
batch.setUniformBuffer(render_utils::slot::buffer::SsaoDebugParams, _parametersBuffer);
|
||||||
|
|
||||||
batch.setPipeline(debugPipeline);
|
batch.setPipeline(debugPipeline);
|
||||||
batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, linearDepthTexture);
|
batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, fullResDepthTexture);
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ void LinearDepthFramebuffer::update(const gpu::TexturePointer& depthBuffer, cons
|
||||||
if (isStereo) {
|
if (isStereo) {
|
||||||
_halfFrameSize.x >>= 1;
|
_halfFrameSize.x >>= 1;
|
||||||
}
|
}
|
||||||
_halfFrameSize = divideRoundUp(_halfFrameSize, 2);
|
_halfFrameSize >>= 1;
|
||||||
if (isStereo) {
|
if (isStereo) {
|
||||||
_halfFrameSize.x <<= 1;
|
_halfFrameSize.x <<= 1;
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ void LinearDepthPass::run(const render::RenderContextPointer& renderContext, con
|
||||||
auto downsamplePipeline = getDownsamplePipeline(renderContext);
|
auto downsamplePipeline = getDownsamplePipeline(renderContext);
|
||||||
|
|
||||||
auto depthViewport = args->_viewport;
|
auto depthViewport = args->_viewport;
|
||||||
auto halfViewport = divideRoundUp(depthViewport, 2);
|
auto halfViewport = depthViewport >> 1;
|
||||||
float clearLinearDepth = args->getViewFrustum().getFarClip() * 2.0f;
|
float clearLinearDepth = args->getViewFrustum().getFarClip() * 2.0f;
|
||||||
|
|
||||||
gpu::doInBatch("LinearDepthPass::run", args->_context, [=](gpu::Batch& batch) {
|
gpu::doInBatch("LinearDepthPass::run", args->_context, [=](gpu::Batch& batch) {
|
||||||
|
|
|
@ -260,11 +260,20 @@ float getZEyeAtUV(vec2 texCoord, int level) {
|
||||||
return -textureLod(depthPyramidTex, texCoord, level).x;
|
return -textureLod(depthPyramidTex, texCoord, level).x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float getZEyeAtUV(vec2 texCoord, int level, ivec2 texelOffset) {
|
||||||
|
return -textureLodOffset(depthPyramidTex, texCoord, level, texelOffset).x;
|
||||||
|
}
|
||||||
|
|
||||||
float getZEyeAtUV(ivec4 side, vec2 texCoord, int level) {
|
float getZEyeAtUV(ivec4 side, vec2 texCoord, int level) {
|
||||||
texCoord.x = mix(texCoord.x, (texCoord.x + getStereoSide(side)) * 0.5, isStereo());
|
texCoord.x = mix(texCoord.x, (texCoord.x + getStereoSide(side)) * 0.5, isStereo());
|
||||||
return getZEyeAtUV(texCoord, level);
|
return getZEyeAtUV(texCoord, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float getZEyeAtUV(ivec4 side, vec2 texCoord, int level, ivec2 texelOffset) {
|
||||||
|
texCoord.x = mix(texCoord.x, (texCoord.x + getStereoSide(side)) * 0.5, isStereo());
|
||||||
|
return getZEyeAtUV(texCoord, level, texelOffset);
|
||||||
|
}
|
||||||
|
|
||||||
vec3 getNormalEyeAtUV(vec2 texCoord, int level) {
|
vec3 getNormalEyeAtUV(vec2 texCoord, int level) {
|
||||||
return normalize(textureLod(normalTex, texCoord, level).xyz*2.0 - vec3(1.0));
|
return normalize(textureLod(normalTex, texCoord, level).xyz*2.0 - vec3(1.0));
|
||||||
}
|
}
|
||||||
|
@ -301,20 +310,25 @@ vec3 buildPosition(ivec4 side, vec2 fragUVPos) {
|
||||||
return evalEyePositionFromZeye(side.x, Zeye, fragUVPos);
|
return evalEyePositionFromZeye(side.x, Zeye, fragUVPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 buildPosition(ivec4 side, vec2 fragUVPos, ivec2 texelOffset, vec2 deltaUV) {
|
||||||
|
float Zeye = getZEyeAtUV(side, fragUVPos, 0, texelOffset);
|
||||||
|
return evalEyePositionFromZeye(side.x, Zeye, fragUVPos + texelOffset*deltaUV);
|
||||||
|
}
|
||||||
|
|
||||||
vec3 getMinDelta(vec3 centralPoint, vec3 offsetPointPos, vec3 offsetPointNeg) {
|
vec3 getMinDelta(vec3 centralPoint, vec3 offsetPointPos, vec3 offsetPointNeg) {
|
||||||
vec3 delta0 = offsetPointPos - centralPoint;
|
vec3 delta0 = offsetPointPos - centralPoint;
|
||||||
vec3 delta1 = centralPoint - offsetPointNeg;
|
vec3 delta1 = centralPoint - offsetPointNeg;
|
||||||
float sqrLength0 = dot(delta0, delta0);
|
float sqrLength0 = dot(delta0, delta0);
|
||||||
float sqrLength1 = dot(delta1, delta1);
|
float sqrLength1 = dot(delta1, delta1);
|
||||||
float epsilon = 1e-6;
|
|
||||||
return sqrLength0 < sqrLength1 && sqrLength0>epsilon ? delta0 : delta1;
|
return sqrLength0 < sqrLength1 ? delta0 : delta1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 buildNormal(ivec4 side, vec2 fragUVPos, vec3 fragPosition, vec2 deltaDepthUV) {
|
vec3 buildNormal(ivec4 side, vec2 fragUVPos, vec3 fragPosition, vec2 deltaDepthUV) {
|
||||||
vec3 fragPositionDxPos = buildPosition(side, fragUVPos + vec2(deltaDepthUV.x, 0));
|
vec3 fragPositionDxPos = buildPosition(side, fragUVPos, ivec2(1,0), deltaDepthUV);
|
||||||
vec3 fragPositionDxNeg = buildPosition(side, fragUVPos - vec2(deltaDepthUV.x, 0));
|
vec3 fragPositionDxNeg = buildPosition(side, fragUVPos, ivec2(-1,0), deltaDepthUV);
|
||||||
vec3 fragPositionDyPos = buildPosition(side, fragUVPos + vec2(0, deltaDepthUV.y));
|
vec3 fragPositionDyPos = buildPosition(side, fragUVPos, ivec2(0,1), deltaDepthUV);
|
||||||
vec3 fragPositionDyNeg = buildPosition(side, fragUVPos - vec2(0, deltaDepthUV.y));
|
vec3 fragPositionDyNeg = buildPosition(side, fragUVPos, ivec2(0,-1), deltaDepthUV);
|
||||||
|
|
||||||
vec3 fragPositionDx = getMinDelta(fragPosition, fragPositionDxPos, fragPositionDxNeg);
|
vec3 fragPositionDx = getMinDelta(fragPosition, fragPositionDxPos, fragPositionDxNeg);
|
||||||
vec3 fragPositionDy = getMinDelta(fragPosition, fragPositionDyPos, fragPositionDyNeg);
|
vec3 fragPositionDy = getMinDelta(fragPosition, fragPositionDyPos, fragPositionDyNeg);
|
||||||
|
|
|
@ -43,7 +43,7 @@ int getBlurRadius() {
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 fetchOcclusionPacked(ivec4 side, vec2 texCoord) {
|
vec4 fetchOcclusionPacked(ivec4 side, vec2 texCoord) {
|
||||||
texCoord.x = mix(texCoord.x, (texCoord.x + getStereoSide(side)) * 0.5, isStereo());
|
texCoord.x = mix(texCoord.x, (texCoord.x + getStereoSide(side) * getBlurOcclusionUVLimit().x) * 0.5, isStereo());
|
||||||
return textureLod(occlusionMap, texCoord, 0);
|
return textureLod(occlusionMap, texCoord, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,12 +54,11 @@ 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, vec2 depthTexCoord, float fragDepth, vec3 fragNormal) {
|
vec2 evalTapWeightedValue(vec3 blurScales, ivec4 side, int r, vec2 occlusionTexCoord, float fragDepth, vec3 fragNormal) {
|
||||||
vec2 tapOcclusionTexCoord = getBlurOcclusionAxis() * r + occlusionTexCoord;
|
vec2 tapOcclusionTexCoord = getBlurOcclusionAxis() * r + occlusionTexCoord;
|
||||||
vec2 occlusionTexCoordLimits = getBlurOcclusionUVLimit();
|
vec2 occlusionTexCoordLimits = getBlurOcclusionUVLimit();
|
||||||
|
|
||||||
if (tapOcclusionTexCoord.x < side.x || tapOcclusionTexCoord.x >= (side.x + occlusionTexCoordLimits.x)
|
if (any(lessThan(tapOcclusionTexCoord, vec2(0.0))) || any(greaterThanEqual(tapOcclusionTexCoord, occlusionTexCoordLimits)) ) {
|
||||||
|| tapOcclusionTexCoord.y < 0 || tapOcclusionTexCoord.y >= occlusionTexCoordLimits.y) {
|
|
||||||
return vec2(0.0);
|
return vec2(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,10 +84,10 @@ vec4 getBlurredOcclusion(ivec2 destPixelCoord, vec2 occlusionTexCoord, vec2 dept
|
||||||
// Stereo side info
|
// Stereo side info
|
||||||
ivec4 side = getStereoSideInfo(destPixelCoord.x, 0);
|
ivec4 side = getStereoSideInfo(destPixelCoord.x, 0);
|
||||||
|
|
||||||
float fragDepth = getZEyeAtUV(side, depthTexCoord, 0);
|
float fragDepth = getZEyeAtUV(depthTexCoord, 0);
|
||||||
float fragDepthKey = CSZToDepthKey(fragDepth);
|
float fragDepthKey = CSZToDepthKey(fragDepth);
|
||||||
#if SSAO_BILATERAL_BLUR_USE_NORMAL
|
#if SSAO_BILATERAL_BLUR_USE_NORMAL
|
||||||
vec3 fragNormal = getNormalEyeAtUV(side, depthTexCoord, 0);
|
vec3 fragNormal = getNormalEyeAtUV(depthTexCoord, 0);
|
||||||
#else
|
#else
|
||||||
vec3 fragNormal = vec3(0, 0, 1);
|
vec3 fragNormal = vec3(0, 0, 1);
|
||||||
#endif
|
#endif
|
||||||
|
@ -98,9 +97,13 @@ vec4 getBlurredOcclusion(ivec2 destPixelCoord, vec2 occlusionTexCoord, vec2 dept
|
||||||
int blurRadius = getBlurRadius();
|
int blurRadius = getBlurRadius();
|
||||||
vec3 blurScales = getBlurScales();
|
vec3 blurScales = getBlurScales();
|
||||||
|
|
||||||
|
// From now on, occlusionTexCoord is the UV pos in the side
|
||||||
|
float sideTexCoord = occlusionTexCoord.x * 2.0 - getStereoSide(side) * getBlurOcclusionUVLimit().x;
|
||||||
|
occlusionTexCoord.x = mix(occlusionTexCoord.x, sideTexCoord, isStereo());
|
||||||
|
|
||||||
// negative side first
|
// negative side first
|
||||||
for (int r = -blurRadius; r <= -1; ++r) {
|
for (int r = -blurRadius; r <= -1; ++r) {
|
||||||
weightedSums += evalTapWeightedValue(blurScales, side, r, occlusionTexCoord, depthTexCoord, fragDepthKey, fragNormal);
|
weightedSums += evalTapWeightedValue(blurScales, side, r, occlusionTexCoord, fragDepthKey, fragNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Central pixel contribution
|
// Central pixel contribution
|
||||||
|
@ -110,7 +113,7 @@ vec4 getBlurredOcclusion(ivec2 destPixelCoord, vec2 occlusionTexCoord, vec2 dept
|
||||||
|
|
||||||
// then positive side
|
// then positive side
|
||||||
for (int r = 1; r <= blurRadius; ++r) {
|
for (int r = 1; r <= blurRadius; ++r) {
|
||||||
weightedSums += evalTapWeightedValue(blurScales, side, r, occlusionTexCoord, depthTexCoord, fragDepthKey, fragNormal);
|
weightedSums += evalTapWeightedValue(blurScales, side, r, occlusionTexCoord, fragDepthKey, fragNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final normalization
|
// Final normalization
|
||||||
|
|
Loading…
Reference in a new issue