mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 09:44:21 +02:00
Added user definable taps in blur task
This commit is contained in:
parent
bcec3680b6
commit
443d6dfacb
4 changed files with 107 additions and 53 deletions
|
@ -29,11 +29,10 @@ enum BlurShaderMapSlots {
|
|||
BlurTask_DepthSlot,
|
||||
};
|
||||
|
||||
const float BLUR_NUM_SAMPLES = 7.0f;
|
||||
|
||||
BlurParams::BlurParams() {
|
||||
Params params;
|
||||
_parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Params), (const gpu::Byte*) ¶ms));
|
||||
setGaussianFilterTaps(3);
|
||||
}
|
||||
|
||||
void BlurParams::setWidthHeight(int width, int height, bool isStereo) {
|
||||
|
@ -60,7 +59,58 @@ void BlurParams::setFilterRadiusScale(float scale) {
|
|||
auto filterInfo = _parametersBuffer.get<Params>().filterInfo;
|
||||
if (scale != filterInfo.x) {
|
||||
_parametersBuffer.edit<Params>().filterInfo.x = scale;
|
||||
_parametersBuffer.edit<Params>().filterInfo.y = scale / BLUR_NUM_SAMPLES;
|
||||
}
|
||||
}
|
||||
|
||||
void BlurParams::setFilterNumTaps(int count) {
|
||||
assert(count <= BLUR_MAX_NUM_TAPS);
|
||||
auto filterInfo = _parametersBuffer.get<Params>().filterInfo;
|
||||
if (count != (int)filterInfo.y) {
|
||||
_parametersBuffer.edit<Params>().filterInfo.y = count;
|
||||
}
|
||||
}
|
||||
|
||||
void BlurParams::setFilterTap(int index, float offset, float value) {
|
||||
auto filterTaps = _parametersBuffer.edit<Params>().filterTaps;
|
||||
assert(index < BLUR_MAX_NUM_TAPS);
|
||||
filterTaps[index].x = offset;
|
||||
filterTaps[index].y = value;
|
||||
}
|
||||
|
||||
void BlurParams::setGaussianFilterTaps(int numHalfTaps, float sigma, bool normalize) {
|
||||
auto& params = _parametersBuffer.edit<Params>();
|
||||
const int numTaps = 2 * numHalfTaps + 1;
|
||||
assert(numTaps <= BLUR_MAX_NUM_TAPS);
|
||||
assert(sigma > 0.0f);
|
||||
const float inverseTwoSigmaSquared = float(0.5 / (sigma*sigma));
|
||||
float totalWeight = 1.0f;
|
||||
float weight;
|
||||
float offset;
|
||||
int i;
|
||||
|
||||
params.filterInfo.y = numTaps;
|
||||
params.filterTaps[0].x = 0.0f;
|
||||
params.filterTaps[0].y = 1.0f;
|
||||
|
||||
for (i = 0; i < numHalfTaps; i++) {
|
||||
offset = i + 1;
|
||||
weight = (float)exp(-offset*offset * inverseTwoSigmaSquared);
|
||||
params.filterTaps[i + 1].x = offset;
|
||||
params.filterTaps[i + 1].y = weight;
|
||||
params.filterTaps[i + 1 + numHalfTaps].x = -offset;
|
||||
params.filterTaps[i + 1 + numHalfTaps].y = weight;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
#include "Engine.h"
|
||||
|
||||
#include "BlurTask_shared.slh"
|
||||
|
||||
namespace render {
|
||||
|
||||
|
||||
|
@ -25,6 +27,10 @@ public:
|
|||
void setTexcoordTransform(const glm::vec4 texcoordTransformViewport);
|
||||
|
||||
void setFilterRadiusScale(float scale);
|
||||
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 setDepthPerspective(float oneOverTan2FOV);
|
||||
void setDepthThreshold(float threshold);
|
||||
|
@ -40,7 +46,7 @@ public:
|
|||
// Viewport to Texcoord info, if the region of the blur (viewport) is smaller than the full frame
|
||||
glm::vec4 texcoordTransform{ 0.0f, 0.0f, 1.0f, 1.0f };
|
||||
|
||||
// Filter info (radius scale
|
||||
// Filter info (radius scale, number of taps, mix)
|
||||
glm::vec4 filterInfo{ 1.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
// Depth info (radius scale
|
||||
|
@ -52,6 +58,9 @@ public:
|
|||
// LinearDepth info is { f }
|
||||
glm::vec4 linearDepthInfo{ 0.0f };
|
||||
|
||||
// Taps (offset, weight)
|
||||
glm::vec2 filterTaps[BLUR_MAX_NUM_TAPS];
|
||||
|
||||
Params() {}
|
||||
};
|
||||
gpu::BufferView _parametersBuffer;
|
||||
|
|
|
@ -9,17 +9,7 @@
|
|||
|
||||
<@func declareBlurUniforms()@>
|
||||
|
||||
#define NUM_TAPS 7
|
||||
#define NUM_TAPS_OFFSET 3.0f
|
||||
|
||||
float uniformFilterWidth = 0.05f;
|
||||
|
||||
const float gaussianDistributionCurve[NUM_TAPS] = float[](
|
||||
0.383f, 0.006f, 0.061f, 0.242f, 0.242f, 0.061f, 0.006f
|
||||
);
|
||||
const float gaussianDistributionOffset[NUM_TAPS] = float[](
|
||||
0.0f, -3.0f, -2.0f, -1.0f, 1.0f, 2.0f, 3.0f
|
||||
);
|
||||
<@include BlurTask_shared.slh@>
|
||||
|
||||
struct BlurParameters {
|
||||
vec4 resolutionInfo;
|
||||
|
@ -28,6 +18,7 @@ struct BlurParameters {
|
|||
vec4 depthInfo;
|
||||
vec4 stereoInfo;
|
||||
vec4 linearDepthInfo;
|
||||
vec2 taps[BLUR_MAX_NUM_TAPS];
|
||||
};
|
||||
|
||||
uniform blurParamsBuffer {
|
||||
|
@ -46,6 +37,25 @@ float getFilterScale() {
|
|||
return parameters.filterInfo.x;
|
||||
}
|
||||
|
||||
int getFilterNumTaps() {
|
||||
return int(parameters.filterInfo.y);
|
||||
}
|
||||
|
||||
float getFilterMix() {
|
||||
return parameters.filterInfo.z;
|
||||
}
|
||||
|
||||
vec2 getFilterTap(int index) {
|
||||
return parameters.taps[index];
|
||||
}
|
||||
|
||||
float getFilterTapOffset(vec2 tap) {
|
||||
return tap.x;
|
||||
}
|
||||
|
||||
float getFilterTapWeight(vec2 tap) {
|
||||
return tap.y;
|
||||
}
|
||||
|
||||
float getDepthThreshold() {
|
||||
return parameters.depthInfo.x;
|
||||
|
@ -70,17 +80,18 @@ uniform sampler2D sourceMap;
|
|||
|
||||
vec4 pixelShaderGaussian(vec2 texcoord, vec2 direction, vec2 pixelStep) {
|
||||
texcoord = evalTexcoordTransformed(texcoord);
|
||||
vec4 sampleCenter = texture(sourceMap, texcoord);
|
||||
|
||||
vec2 finalStep = getFilterScale() * direction * pixelStep;
|
||||
vec4 srcBlurred = vec4(0.0);
|
||||
int numTaps = getFilterNumTaps();
|
||||
|
||||
for(int i = 0; i < NUM_TAPS; i++) {
|
||||
for(int i = 0; i < numTaps; i++) {
|
||||
vec2 tapInfo = getFilterTap(i);
|
||||
// Fetch color and depth for current sample.
|
||||
vec2 sampleCoord = texcoord + (gaussianDistributionOffset[i] * finalStep);
|
||||
vec2 sampleCoord = texcoord + (getFilterTapOffset(tapInfo) * finalStep);
|
||||
vec4 srcSample = texture(sourceMap, sampleCoord);
|
||||
// Accumulate.
|
||||
srcBlurred += gaussianDistributionCurve[i] * srcSample;
|
||||
srcBlurred += getFilterTapWeight(tapInfo) * srcSample;
|
||||
}
|
||||
|
||||
return srcBlurred;
|
||||
|
@ -95,15 +106,6 @@ vec4 pixelShaderGaussian(vec2 texcoord, vec2 direction, vec2 pixelStep) {
|
|||
uniform sampler2D sourceMap;
|
||||
uniform sampler2D depthMap;
|
||||
|
||||
#define NUM_HALF_TAPS 4
|
||||
|
||||
const float gaussianDistributionCurveHalf[NUM_HALF_TAPS] = float[](
|
||||
0.383f, 0.242f, 0.061f, 0.006f
|
||||
);
|
||||
const float gaussianDistributionOffsetHalf[NUM_HALF_TAPS] = float[](
|
||||
0.0f, 1.0f, 2.0f, 3.0f
|
||||
);
|
||||
|
||||
vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep) {
|
||||
texcoord = evalTexcoordTransformed(texcoord);
|
||||
float sampleDepth = texture(depthMap, texcoord).x;
|
||||
|
@ -122,13 +124,17 @@ vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep
|
|||
float scale = distanceToProjectionWindow / sampleDepth;
|
||||
|
||||
vec2 finalStep = filterScale * scale * direction * pixelStep;
|
||||
int numTaps = getFilterNumTaps();
|
||||
|
||||
// Accumulate the center sample
|
||||
vec4 srcBlurred = gaussianDistributionCurve[0] * sampleCenter;
|
||||
vec2 tapInfo = getFilterTap(0);
|
||||
vec4 srcBlurred = getFilterTapWeight(tapInfo) * sampleCenter;
|
||||
|
||||
for(int i = 1; i < numTaps; i++) {
|
||||
tapInfo = getFilterTap(i);
|
||||
|
||||
for(int i = 1; i < NUM_TAPS; i++) {
|
||||
// Fetch color and depth for current sample.
|
||||
vec2 sampleCoord = texcoord + (gaussianDistributionOffset[i] * finalStep);
|
||||
vec2 sampleCoord = texcoord + (getFilterTapOffset(tapInfo) * finalStep);
|
||||
float srcDepth = texture(depthMap, sampleCoord).x;
|
||||
vec4 srcSample = texture(sourceMap, sampleCoord);
|
||||
|
||||
|
@ -137,29 +143,8 @@ vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep
|
|||
srcSample = mix(srcSample, sampleCenter, s);
|
||||
|
||||
// Accumulate.
|
||||
srcBlurred += gaussianDistributionCurve[i] * srcSample;
|
||||
srcBlurred += getFilterTapWeight(tapInfo) * srcSample;
|
||||
}
|
||||
|
||||
/*
|
||||
for(int i = 1; i < NUM_HALF_TAPS; i++) {
|
||||
// Fetch color and depth for current sample.
|
||||
vec2 texcoordOffset = (gaussianDistributionOffsetHalf[i] * finalStep);
|
||||
|
||||
float srcDepthN = texture(depthMap, texcoord - texcoordOffset).x;
|
||||
float srcDepthP = texture(depthMap, texcoord + texcoordOffset).x;
|
||||
vec4 srcSampleN = texture(sourceMap, texcoord - texcoordOffset);
|
||||
vec4 srcSampleP = texture(sourceMap, texcoord + texcoordOffset);
|
||||
|
||||
// If the difference in depth is huge, we lerp color back.
|
||||
float sN = clamp(depthThreshold * distanceToProjectionWindow * filterScale * abs(srcDepthN - sampleDepth), 0.0, 1.0);
|
||||
float sP = clamp(depthThreshold * distanceToProjectionWindow * filterScale * abs(srcDepthP - sampleDepth), 0.0, 1.0);
|
||||
|
||||
srcSampleN = mix(srcSampleN, sampleCenter, sN);
|
||||
srcSampleP = mix(srcSampleP, sampleCenter, sP);
|
||||
|
||||
// Accumulate.
|
||||
srcBlurred += gaussianDistributionCurveHalf[i] * (srcSampleP + srcSampleN);
|
||||
}*/
|
||||
|
||||
return srcBlurred;
|
||||
}
|
||||
|
|
10
libraries/render/src/render/BlurTask_shared.slh
Normal file
10
libraries/render/src/render/BlurTask_shared.slh
Normal file
|
@ -0,0 +1,10 @@
|
|||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// Created by Olivier Prat on 09/25/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#define BLUR_MAX_NUM_TAPS 21
|
Loading…
Reference in a new issue