From 22b1507597e1aafea88ece8beb5d2d18c6e6f1eb Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Mon, 25 Sep 2017 16:41:20 +0200 Subject: [PATCH] Fixed blur to work correctly on four sides of screen --- .../src/RenderableModelEntityItem.cpp | 4 +- libraries/render-utils/src/BloomEffect.cpp | 10 +++-- libraries/render/src/render/BlurTask.cpp | 16 ++------ libraries/render/src/render/BlurTask.h | 4 +- libraries/render/src/render/BlurTask.slh | 40 +++++++++++++------ .../render/src/render/BlurTask_shared.slh | 2 +- 6 files changed, 44 insertions(+), 32 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 799a84aaee..b88ef5f8fb 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -319,7 +319,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { // should never fall in here when collision model not fully loaded // hence we assert that all geometries exist and are loaded - assert(_model && _model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded()); + assert(model && model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded()); const FBXGeometry& collisionGeometry = _compoundShapeResource->getFBXGeometry(); ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection(); @@ -408,7 +408,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { shapeInfo.setParams(type, dimensions, getCompoundShapeURL()); } else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) { // should never fall in here when model not fully loaded - assert(_model && _model->isLoaded()); + assert(model && model->isLoaded()); updateModelBounds(); model->updateGeometry(); diff --git a/libraries/render-utils/src/BloomEffect.cpp b/libraries/render-utils/src/BloomEffect.cpp index a0a36a2194..eb02c4fa57 100644 --- a/libraries/render-utils/src/BloomEffect.cpp +++ b/libraries/render-utils/src/BloomEffect.cpp @@ -17,9 +17,10 @@ void BloomConfig::setMix(float value) { } void BloomConfig::setSize(float value) { - auto blurConfig = getConfig("Blur"); - assert(blurConfig); - blurConfig->setProperty("filterScale", value*10.0f); + auto& blurJob = static_cast(_task)->_jobs.front(); + auto& gaussianBlur = blurJob.edit(); + auto gaussianBlurParams = gaussianBlur.getParameters(); + gaussianBlurParams->setGaussianFilterTaps((BLUR_MAX_NUM_TAPS - 1) / 2, value*7.0f); } Bloom::Bloom() { @@ -27,7 +28,8 @@ Bloom::Bloom() { } void Bloom::configure(const Config& config) { - + auto blurConfig = config.getConfig(); + blurConfig->setProperty("filterScale", 2.5f); } void Bloom::build(JobModel& task, const render::Varying& inputs, render::Varying& outputs) { diff --git a/libraries/render/src/render/BlurTask.cpp b/libraries/render/src/render/BlurTask.cpp index 2d51fd1271..2e3cf8138f 100644 --- a/libraries/render/src/render/BlurTask.cpp +++ b/libraries/render/src/render/BlurTask.cpp @@ -77,7 +77,7 @@ void BlurParams::setFilterTap(int index, float offset, float value) { filterTaps[index].y = value; } -void BlurParams::setGaussianFilterTaps(int numHalfTaps, float sigma, bool normalize) { +void BlurParams::setGaussianFilterTaps(int numHalfTaps, float sigma) { auto& params = _parametersBuffer.edit(); const int numTaps = 2 * numHalfTaps + 1; assert(numTaps <= BLUR_MAX_NUM_TAPS); @@ -102,16 +102,8 @@ void BlurParams::setGaussianFilterTaps(int numHalfTaps, float sigma, bool normal totalWeight += 2 * weight; } - float normalizer; - if (normalize) { - normalizer = float(1.0 / totalWeight); - } else { - normalizer = float(1.0 / (sqrt(2 * M_PI)*sigma)); - } - - for (i = 0; i < numTaps; i++) { - params.filterTaps[i].y *= normalizer; - } + // Tap weights will be normalized in shader because side cases on edges of screen + // won't have the same number of taps as in the center. } void BlurParams::setDepthPerspective(float oneOverTan2FOV) { @@ -158,7 +150,7 @@ bool BlurInOutResource::updateResources(const gpu::FramebufferPointer& sourceFra // _blurredFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat()); //} auto blurringSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT); - auto blurringTarget = gpu::Texture::create2D(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), gpu::Texture::SINGLE_MIP, blurringSampler); + auto blurringTarget = gpu::Texture::createRenderBuffer(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), gpu::Texture::SINGLE_MIP, blurringSampler); _blurredFramebuffer->setRenderBuffer(0, blurringTarget); } diff --git a/libraries/render/src/render/BlurTask.h b/libraries/render/src/render/BlurTask.h index 011da6ab68..4df5a09576 100644 --- a/libraries/render/src/render/BlurTask.h +++ b/libraries/render/src/render/BlurTask.h @@ -30,7 +30,7 @@ public: void setFilterNumTaps(int count); // Tap 0 is considered the center of the kernel void setFilterTap(int index, float offset, float value); - void setGaussianFilterTaps(int numHalfTaps, float sigma = 1.47f, bool normalize = true); + void setGaussianFilterTaps(int numHalfTaps, float sigma = 1.47f); void setDepthPerspective(float oneOverTan2FOV); void setDepthThreshold(float threshold); @@ -116,6 +116,8 @@ public: void configure(const Config& config); void run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& sourceFramebuffer, gpu::FramebufferPointer& blurredFramebuffer); + BlurParamsPointer getParameters() const { return _parameters; } + protected: BlurParamsPointer _parameters; diff --git a/libraries/render/src/render/BlurTask.slh b/libraries/render/src/render/BlurTask.slh index b871b59bed..5a41a0b1c6 100644 --- a/libraries/render/src/render/BlurTask.slh +++ b/libraries/render/src/render/BlurTask.slh @@ -83,17 +83,25 @@ vec4 pixelShaderGaussian(vec2 texcoord, vec2 direction, vec2 pixelStep) { vec2 finalStep = getFilterScale() * direction * pixelStep; vec4 srcBlurred = vec4(0.0); + float totalWeight = 0.f; int numTaps = getFilterNumTaps(); for(int i = 0; i < numTaps; i++) { vec2 tapInfo = getFilterTap(i); - // Fetch color and depth for current sample. + // Fetch color for current sample. vec2 sampleCoord = texcoord + (getFilterTapOffset(tapInfo) * finalStep); - vec4 srcSample = texture(sourceMap, sampleCoord); - // Accumulate. - srcBlurred += getFilterTapWeight(tapInfo) * srcSample; + if (all(greaterThanEqual(sampleCoord, vec2(0,0))) && all(lessThanEqual(sampleCoord, vec2(1.0,1.0)))) { + vec4 srcSample = texture(sourceMap, sampleCoord); + float weight = getFilterTapWeight(tapInfo); + // Accumulate. + srcBlurred += srcSample * weight; + totalWeight += weight; + } } + if (totalWeight>0.0) { + srcBlurred /= totalWeight; + } return srcBlurred; } @@ -128,24 +136,32 @@ vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep // Accumulate the center sample vec2 tapInfo = getFilterTap(0); - vec4 srcBlurred = getFilterTapWeight(tapInfo) * sampleCenter; + float totalWeight = getFilterTapWeight(tapInfo); + vec4 srcBlurred = sampleCenter * totalWeight; for(int i = 1; i < numTaps; i++) { tapInfo = getFilterTap(i); // Fetch color and depth for current sample. vec2 sampleCoord = texcoord + (getFilterTapOffset(tapInfo) * finalStep); - float srcDepth = texture(depthMap, sampleCoord).x; - vec4 srcSample = texture(sourceMap, sampleCoord); + if (all(greaterThanEqual(sampleCoord, vec2(0,0))) && all(lessThanEqual(sampleCoord, vec2(1.0,1.0)))) { + float srcDepth = texture(depthMap, sampleCoord).x; + vec4 srcSample = texture(sourceMap, sampleCoord); + float weight = getFilterTapWeight(tapInfo); - // If the difference in depth is huge, we lerp color back. - float s = clamp(depthThreshold * distanceToProjectionWindow * filterScale * abs(srcDepth - sampleDepth), 0.0, 1.0); - srcSample = mix(srcSample, sampleCenter, s); + // If the difference in depth is huge, we lerp color back. + float s = clamp(depthThreshold * distanceToProjectionWindow * filterScale * abs(srcDepth - sampleDepth), 0.0, 1.0); + srcSample = mix(srcSample, sampleCenter, s); - // Accumulate. - srcBlurred += getFilterTapWeight(tapInfo) * srcSample; + // Accumulate. + srcBlurred += srcSample * weight; + totalWeight += weight; + } } + if (totalWeight>0.0) { + srcBlurred /= totalWeight; + } return srcBlurred; } diff --git a/libraries/render/src/render/BlurTask_shared.slh b/libraries/render/src/render/BlurTask_shared.slh index 94417fa939..84c633d74c 100644 --- a/libraries/render/src/render/BlurTask_shared.slh +++ b/libraries/render/src/render/BlurTask_shared.slh @@ -7,4 +7,4 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#define BLUR_MAX_NUM_TAPS 21 +#define BLUR_MAX_NUM_TAPS 25