mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Added some tweaking parameters to try to limit silhouette AO
This commit is contained in:
parent
8006d7c052
commit
6b8f47c75a
5 changed files with 97 additions and 104 deletions
|
@ -181,8 +181,12 @@ AmbientOcclusionEffectConfig::AmbientOcclusionEffectConfig() :
|
||||||
#endif
|
#endif
|
||||||
perspectiveScale{ 1.0f },
|
perspectiveScale{ 1.0f },
|
||||||
obscuranceLevel{ 0.5f },
|
obscuranceLevel{ 0.5f },
|
||||||
falloffBias{ 0.01f },
|
#if SSAO_USE_HORIZON_BASED
|
||||||
silhouetteRadius{ 0.3f },
|
falloffAngle{ 0.1f },
|
||||||
|
#else
|
||||||
|
falloffAngle{ 0.01f },
|
||||||
|
#endif
|
||||||
|
falloffDistance{ 0.3f },
|
||||||
edgeSharpness{ 1.0f },
|
edgeSharpness{ 1.0f },
|
||||||
blurDeviation{ 2.5f },
|
blurDeviation{ 2.5f },
|
||||||
numSpiralTurns{ 7.0f },
|
numSpiralTurns{ 7.0f },
|
||||||
|
@ -234,9 +238,9 @@ void AmbientOcclusionEffect::configure(const Config& config) {
|
||||||
current.w = config.obscuranceLevel;
|
current.w = config.obscuranceLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.falloffBias != _aoParametersBuffer->getFalloffBias()) {
|
if (config.falloffAngle != _aoParametersBuffer->getFalloffAngle()) {
|
||||||
auto& current = _aoParametersBuffer.edit().ditheringInfo;
|
auto& current = _aoParametersBuffer.edit().ditheringInfo;
|
||||||
current.z = config.falloffBias;
|
current.z = config.falloffAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.edgeSharpness != _aoParametersBuffer->getEdgeSharpness()) {
|
if (config.edgeSharpness != _aoParametersBuffer->getEdgeSharpness()) {
|
||||||
|
@ -297,9 +301,9 @@ void AmbientOcclusionEffect::configure(const Config& config) {
|
||||||
current.w = (float)config.borderingEnabled;
|
current.w = (float)config.borderingEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.silhouetteRadius != _aoParametersBuffer->getSilhouetteRadius()) {
|
if (config.falloffDistance != _aoParametersBuffer->getFalloffDistance()) {
|
||||||
auto& current = _aoParametersBuffer.edit().ditheringInfo;
|
auto& current = _aoParametersBuffer.edit().ditheringInfo;
|
||||||
current.y = (float)config.silhouetteRadius;
|
current.y = (float)config.falloffDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldUpdateGaussian) {
|
if (shouldUpdateGaussian) {
|
||||||
|
@ -450,6 +454,7 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
||||||
#endif
|
#endif
|
||||||
batch.popProfileRange();
|
batch.popProfileRange();
|
||||||
|
|
||||||
|
batch.pushProfileRange("Occlusion");
|
||||||
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);
|
||||||
|
|
||||||
|
@ -459,10 +464,11 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
||||||
batch.setPipeline(occlusionPipeline);
|
batch.setPipeline(occlusionPipeline);
|
||||||
batch.setResourceTexture(render_utils::slot::texture::SsaoPyramid, _framebuffer->getLinearDepthTexture());
|
batch.setResourceTexture(render_utils::slot::texture::SsaoPyramid, _framebuffer->getLinearDepthTexture());
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
|
batch.popProfileRange();
|
||||||
|
|
||||||
/* TEMPO OP if (_aoParametersBuffer->getBlurRadius() > 0)*/ {
|
{
|
||||||
PROFILE_RANGE_BATCH(batch, "Blur");
|
PROFILE_RANGE_BATCH(batch, "Bilateral Blur");
|
||||||
// Blur 1st pass
|
// Blur 1st pass
|
||||||
model.setScale(resolutionScale);
|
model.setScale(resolutionScale);
|
||||||
batch.setModelTransform(model);
|
batch.setModelTransform(model);
|
||||||
batch.setViewportTransform(firstBlurViewport);
|
batch.setViewportTransform(firstBlurViewport);
|
||||||
|
@ -482,8 +488,7 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
||||||
batch.setResourceTexture(render_utils::slot::texture::SsaoOcclusion, occlusionBlurredFBO->getRenderBuffer(0));
|
batch.setResourceTexture(render_utils::slot::texture::SsaoOcclusion, occlusionBlurredFBO->getRenderBuffer(0));
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
batch.setResourceTexture(render_utils::slot::texture::SsaoPyramid, nullptr);
|
batch.setResourceTexture(render_utils::slot::texture::SsaoPyramid, nullptr);
|
||||||
batch.setResourceTexture(render_utils::slot::texture::SsaoOcclusion, nullptr);
|
batch.setResourceTexture(render_utils::slot::texture::SsaoOcclusion, nullptr);
|
||||||
|
|
||||||
|
|
|
@ -62,8 +62,8 @@ class AmbientOcclusionEffectConfig : public render::GPUJobConfig::Persistent {
|
||||||
Q_PROPERTY(bool fetchMipsEnabled MEMBER fetchMipsEnabled NOTIFY dirty)
|
Q_PROPERTY(bool fetchMipsEnabled MEMBER fetchMipsEnabled NOTIFY dirty)
|
||||||
Q_PROPERTY(float radius MEMBER radius WRITE setRadius)
|
Q_PROPERTY(float radius MEMBER radius WRITE setRadius)
|
||||||
Q_PROPERTY(float obscuranceLevel MEMBER obscuranceLevel WRITE setObscuranceLevel)
|
Q_PROPERTY(float obscuranceLevel MEMBER obscuranceLevel WRITE setObscuranceLevel)
|
||||||
Q_PROPERTY(float falloffBias MEMBER falloffBias WRITE setFalloffBias)
|
Q_PROPERTY(float falloffAngle MEMBER falloffAngle WRITE setFalloffAngle)
|
||||||
Q_PROPERTY(float silhouetteRadius MEMBER silhouetteRadius WRITE setSilhouetteRadius)
|
Q_PROPERTY(float falloffDistance MEMBER falloffDistance WRITE setFalloffDistance)
|
||||||
Q_PROPERTY(float edgeSharpness MEMBER edgeSharpness WRITE setEdgeSharpness)
|
Q_PROPERTY(float edgeSharpness MEMBER edgeSharpness WRITE setEdgeSharpness)
|
||||||
Q_PROPERTY(float blurDeviation MEMBER blurDeviation WRITE setBlurDeviation)
|
Q_PROPERTY(float blurDeviation MEMBER blurDeviation WRITE setBlurDeviation)
|
||||||
Q_PROPERTY(float numSpiralTurns MEMBER numSpiralTurns WRITE setNumSpiralTurns)
|
Q_PROPERTY(float numSpiralTurns MEMBER numSpiralTurns WRITE setNumSpiralTurns)
|
||||||
|
@ -75,12 +75,12 @@ public:
|
||||||
AmbientOcclusionEffectConfig();
|
AmbientOcclusionEffectConfig();
|
||||||
|
|
||||||
const int MAX_RESOLUTION_LEVEL = 4;
|
const int MAX_RESOLUTION_LEVEL = 4;
|
||||||
const int MAX_BLUR_RADIUS = 6;
|
const int MAX_BLUR_RADIUS = 15;
|
||||||
|
|
||||||
void setRadius(float newRadius) { radius = std::max(0.01f, newRadius); emit dirty(); }
|
void setRadius(float newRadius) { radius = std::max(0.01f, newRadius); emit dirty(); }
|
||||||
void setObscuranceLevel(float level) { obscuranceLevel = std::max(0.01f, level); emit dirty(); }
|
void setObscuranceLevel(float level) { obscuranceLevel = std::max(0.01f, level); emit dirty(); }
|
||||||
void setFalloffBias(float bias) { falloffBias = std::max(0.0f, std::min(bias, 0.2f)); emit dirty(); }
|
void setFalloffAngle(float bias) { falloffAngle = std::max(0.0f, std::min(bias, 0.2f)); emit dirty(); }
|
||||||
void setSilhouetteRadius(float value) { silhouetteRadius = std::max(0.0f, value); emit dirty(); }
|
void setFalloffDistance(float value) { falloffDistance = std::max(0.0f, value); emit dirty(); }
|
||||||
void setEdgeSharpness(float sharpness) { edgeSharpness = std::max(0.0f, (float)sharpness); emit dirty(); }
|
void setEdgeSharpness(float sharpness) { edgeSharpness = std::max(0.0f, (float)sharpness); emit dirty(); }
|
||||||
void setBlurDeviation(float deviation) { blurDeviation = std::max(0.0f, deviation); emit dirty(); }
|
void setBlurDeviation(float deviation) { blurDeviation = std::max(0.0f, deviation); emit dirty(); }
|
||||||
void setNumSpiralTurns(float turns) { numSpiralTurns = std::max(0.0f, (float)turns); emit dirty(); }
|
void setNumSpiralTurns(float turns) { numSpiralTurns = std::max(0.0f, (float)turns); emit dirty(); }
|
||||||
|
@ -91,8 +91,8 @@ public:
|
||||||
float radius;
|
float radius;
|
||||||
float perspectiveScale;
|
float perspectiveScale;
|
||||||
float obscuranceLevel; // intensify or dim down the obscurance effect
|
float obscuranceLevel; // intensify or dim down the obscurance effect
|
||||||
float falloffBias;
|
float falloffAngle;
|
||||||
float silhouetteRadius;
|
float falloffDistance;
|
||||||
float edgeSharpness;
|
float edgeSharpness;
|
||||||
float blurDeviation;
|
float blurDeviation;
|
||||||
float numSpiralTurns; // defining an angle span to distribute the samples ray directions
|
float numSpiralTurns; // defining an angle span to distribute the samples ray directions
|
||||||
|
@ -134,7 +134,7 @@ public:
|
||||||
// Blurring info
|
// Blurring info
|
||||||
glm::vec4 blurInfo;
|
glm::vec4 blurInfo;
|
||||||
// gaussian distribution coefficients first is the sampling radius (max is 6)
|
// gaussian distribution coefficients first is the sampling radius (max is 6)
|
||||||
const static int GAUSSIAN_COEFS_LENGTH = 8;
|
const static int GAUSSIAN_COEFS_LENGTH = 16;
|
||||||
float _gaussianCoefs[GAUSSIAN_COEFS_LENGTH];
|
float _gaussianCoefs[GAUSSIAN_COEFS_LENGTH];
|
||||||
|
|
||||||
AOParameters();
|
AOParameters();
|
||||||
|
@ -143,10 +143,10 @@ public:
|
||||||
float getRadius() const { return radiusInfo.x; }
|
float getRadius() const { return radiusInfo.x; }
|
||||||
float getPerspectiveScale() const { return resolutionInfo.z; }
|
float getPerspectiveScale() const { return resolutionInfo.z; }
|
||||||
float getObscuranceLevel() const { return radiusInfo.w; }
|
float getObscuranceLevel() const { return radiusInfo.w; }
|
||||||
float getFalloffBias() const { return (float)ditheringInfo.z; }
|
float getFalloffAngle() const { return (float)ditheringInfo.z; }
|
||||||
|
float getFalloffDistance() const { return ditheringInfo.y; }
|
||||||
float getEdgeSharpness() const { return (float)blurInfo.x; }
|
float getEdgeSharpness() const { return (float)blurInfo.x; }
|
||||||
float getBlurDeviation() const { return blurInfo.z; }
|
float getBlurDeviation() const { return blurInfo.z; }
|
||||||
float getSilhouetteRadius() const { return ditheringInfo.y; }
|
|
||||||
|
|
||||||
float getNumSpiralTurns() const { return sampleInfo.z; }
|
float getNumSpiralTurns() const { return sampleInfo.z; }
|
||||||
int getNumSamples() const { return (int)sampleInfo.x; }
|
int getNumSamples() const { return (int)sampleInfo.x; }
|
||||||
|
|
|
@ -41,7 +41,7 @@ struct AmbientOcclusionParams {
|
||||||
vec4 _ditheringInfo;
|
vec4 _ditheringInfo;
|
||||||
vec4 _sampleInfo;
|
vec4 _sampleInfo;
|
||||||
vec4 _blurInfo;
|
vec4 _blurInfo;
|
||||||
float _gaussianCoefs[8];
|
float _gaussianCoefs[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(binding=RENDER_UTILS_BUFFER_SSAO_PARAMS) uniform ambientOcclusionParamsBuffer {
|
layout(binding=RENDER_UTILS_BUFFER_SSAO_PARAMS) uniform ambientOcclusionParamsBuffer {
|
||||||
|
@ -75,14 +75,14 @@ float getObscuranceScaling() {
|
||||||
float isDitheringEnabled() {
|
float isDitheringEnabled() {
|
||||||
return params._ditheringInfo.x;
|
return params._ditheringInfo.x;
|
||||||
}
|
}
|
||||||
float getSilhouetteRadius() {
|
float getFalloffDistance() {
|
||||||
return params._ditheringInfo.y;
|
return params._ditheringInfo.y;
|
||||||
}
|
}
|
||||||
float isBorderingEnabled() {
|
float isBorderingEnabled() {
|
||||||
return params._ditheringInfo.w;
|
return params._ditheringInfo.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
float getFalloffBias() {
|
float getFalloffAngle() {
|
||||||
return params._ditheringInfo.z;
|
return params._ditheringInfo.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ float getZEyeAtUV(vec2 texCoord, int level) {
|
||||||
return -texture(pyramidMap, texCoord, level).x;
|
return -texture(pyramidMap, texCoord, level).x;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int LOG_MAX_OFFSET = 3;
|
const int LOG_MAX_OFFSET = 1;
|
||||||
const int MAX_MIP_LEVEL = 5;
|
const int MAX_MIP_LEVEL = 5;
|
||||||
int evalMipFromRadius(float radius) {
|
int evalMipFromRadius(float radius) {
|
||||||
// mipLevel = floor(log(ssR / MAX_OFFSET));
|
// mipLevel = floor(log(ssR / MAX_OFFSET));
|
||||||
|
@ -249,7 +249,7 @@ vec3 fetchTapUnfiltered(ivec4 side, ivec2 ssC, vec3 tap, vec2 imageSize) {
|
||||||
return P;
|
return P;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 fetchTap(ivec4 side, ivec2 ssC, vec3 tap, vec2 imageSize) {
|
vec4 fetchTap(ivec4 side, ivec2 ssC, vec3 tap, vec2 imageSize) {
|
||||||
int mipLevel = evalMipFromRadius(tap.z * float(doFetchMips()));
|
int mipLevel = evalMipFromRadius(tap.z * float(doFetchMips()));
|
||||||
|
|
||||||
vec2 ssP = tap.xy + vec2(ssC);
|
vec2 ssP = tap.xy + vec2(ssC);
|
||||||
|
@ -259,15 +259,13 @@ vec3 fetchTap(ivec4 side, ivec2 ssC, vec3 tap, vec2 imageSize) {
|
||||||
vec2 tapUV = (vec2(ssP) + vec2(0.5)) / imageSize;
|
vec2 tapUV = (vec2(ssP) + vec2(0.5)) / imageSize;
|
||||||
vec2 fetchUV = vec2(tapUV.x + side.w * 0.5 * (side.x - tapUV.x), tapUV.y);
|
vec2 fetchUV = vec2(tapUV.x + side.w * 0.5 * (side.x - tapUV.x), tapUV.y);
|
||||||
|
|
||||||
vec3 P;
|
vec4 P;
|
||||||
P.xy = tapUV;
|
P.xy = tapUV;
|
||||||
P.z = -textureLod(pyramidMap, fetchUV, float(mipLevel)).x;
|
P.w = float(mipLevel);
|
||||||
|
P.z = -textureLod(pyramidMap, fetchUV, P.w).x;
|
||||||
return P;
|
return P;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
|
|
||||||
|
@ -289,59 +287,63 @@ float evalVisibilitySSAO(in vec3 centerPosition, in vec3 centerNormal, in vec3 t
|
||||||
// Fall off function as recommended in SSAO paper
|
// Fall off function as recommended in SSAO paper
|
||||||
const float epsilon = 0.01;
|
const float epsilon = 0.01;
|
||||||
float f = max(getRadius2() - vv, 0.0);
|
float f = max(getRadius2() - vv, 0.0);
|
||||||
return f * f * f * max((vn - getFalloffBias()) / (epsilon + vv), 0.0);
|
return f * f * f * max((vn - getFalloffAngle()) / (epsilon + vv), 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float computeHorizonFromTap(vec3 tapPositionES, vec3 fragPositionES, vec3 fragNormalES, float normalizedRadius) {
|
||||||
|
vec3 deltaVec = tapPositionES - fragPositionES;
|
||||||
|
float distance = abs(deltaVec.z);
|
||||||
|
float rawHorizon = dot(normalize(deltaVec), fragNormalES);
|
||||||
|
|
||||||
|
rawHorizon = (rawHorizon - getFalloffAngle()) / (1.0 - getFalloffAngle());
|
||||||
|
rawHorizon *= 1.0 - normalizedRadius * normalizedRadius;
|
||||||
|
rawHorizon *= 1.0 - smoothstep(getFalloffDistance()/2, getFalloffDistance(), distance);
|
||||||
|
|
||||||
|
return rawHorizon;
|
||||||
|
}
|
||||||
|
|
||||||
|
<@func computeHorizon()@>
|
||||||
|
vec3 tap = vec3(tapPixelPos, radius);
|
||||||
|
vec4 tapUVZ_mip = fetchTap(side, centerPixelPos, tap, imageSize);
|
||||||
|
vec3 tapPositionES = evalEyePositionFromZeye(side.x, tapUVZ_mip.z, tapUVZ_mip.xy);
|
||||||
|
float rawHorizon = computeHorizonFromTap(tapPositionES, fragPositionES, fragNormalES, radius / searchRadius);
|
||||||
|
|
||||||
|
<$horizon$> = max(<$horizon$>, rawHorizon);
|
||||||
|
<@endfunc@>
|
||||||
|
|
||||||
|
#define SSAO_LINEAR_SAMPLING 0
|
||||||
|
|
||||||
<@func updateHorizon(horizon, deltaPixelTap)@>
|
<@func updateHorizon(horizon, deltaPixelTap)@>
|
||||||
{
|
{
|
||||||
int stepIndex;
|
|
||||||
vec2 tapPixelPos = vec2(0);
|
vec2 tapPixelPos = vec2(0);
|
||||||
float radius = 0.0;
|
|
||||||
|
|
||||||
for (stepIndex=stepCount ; stepIndex>0 ; stepIndex--) {
|
#if !SSAO_LINEAR_SAMPLING
|
||||||
tapPixelPos += deltaPixelTap;
|
float radius = deltaRadius;
|
||||||
|
float mipLevel = evalMipFromRadius(radius * float(doFetchMips()));
|
||||||
|
|
||||||
|
while (radius<searchRadius) {
|
||||||
|
tapPixelPos += <$deltaPixelTap$>;
|
||||||
|
|
||||||
|
<$computeHorizon()$>
|
||||||
|
|
||||||
|
if (tapUVZ_mip.w != mipLevel) {
|
||||||
|
mipLevel = tapUVZ_mip.w;
|
||||||
|
deltaRadius *= 2;
|
||||||
|
<$deltaPixelTap$> *= 2;
|
||||||
|
}
|
||||||
|
radius += deltaRadius;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
float radius = 0.0;
|
||||||
|
int stepIndex;
|
||||||
|
|
||||||
|
for (stepIndex=0 ; stepIndex<stepCount ; stepIndex++) {
|
||||||
|
tapPixelPos += <$deltaPixelTap$>;
|
||||||
radius += deltaRadius;
|
radius += deltaRadius;
|
||||||
|
|
||||||
vec3 tap = vec3(tapPixelPos, radius);
|
<$computeHorizon()$>
|
||||||
vec3 tapUVZ = fetchTap(side, centerPixelPos, tap, imageSize);
|
|
||||||
vec3 tapPositionES = evalEyePositionFromZeye(side.x, tapUVZ.z, tapUVZ.xy);
|
|
||||||
vec3 deltaVec = tapPositionES - fragPositionES;
|
|
||||||
float deltaVecHeight = dot(deltaVec, fragNormalES);
|
|
||||||
float rawHorizon = dot(normalize(deltaVec), fragNormalES);
|
|
||||||
float falloff = max(0.0, 1.0 - deltaVecHeight / getSilhouetteRadius());
|
|
||||||
|
|
||||||
rawHorizon = rawHorizon < getFalloffBias() ? 0.0f : rawHorizon;
|
|
||||||
rawHorizon *= falloff * falloff;
|
|
||||||
|
|
||||||
<$horizon$> = max(<$horizon$>, rawHorizon);
|
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
<@endfunc@>
|
|
||||||
|
|
||||||
<@func searchBresenhamHorizon(deltaPixelCoord)@>
|
|
||||||
{
|
|
||||||
float epsilon = 1e-8;
|
|
||||||
vec2 deltaPixelTap = searchVec / absSearchVec.<$deltaPixelCoord$>;
|
|
||||||
vec2 absDeltaPixelTap = abs(deltaPixelTap);
|
|
||||||
bvec2 nullDelta = absDeltaPixelTap < epsilon;
|
|
||||||
|
|
||||||
pixelDelta1 = mix(pixelDelta1, vec2(1.0), pixelDelta1 < epsilon && nullDelta);
|
|
||||||
pixelDelta2 = mix(pixelDelta2, vec2(1.0), pixelDelta2 < epsilon && nullDelta);
|
|
||||||
|
|
||||||
pixelDelta1 = ceil(pixelDelta1 / absDeltaPixelTap);
|
|
||||||
pixelDelta2 = ceil(pixelDelta2 / absDeltaPixelTap);
|
|
||||||
|
|
||||||
int maxStepCount = max(0, int(ceil(absSearchVec.<$deltaPixelCoord$>)));
|
|
||||||
float deltaRadius = ssDiskRadius / maxStepCount;
|
|
||||||
int stepCount;
|
|
||||||
|
|
||||||
// Forward search for h1
|
|
||||||
stepCount = clamp(int(min(pixelDelta1.x, pixelDelta1.y)), 0, maxStepCount);
|
|
||||||
<$updateHorizon(horizons.x, deltaPixelTap)$>
|
|
||||||
|
|
||||||
// Backward search for h2
|
|
||||||
stepCount = clamp(int(min(pixelDelta2.x, pixelDelta2.y)), 0, maxStepCount);
|
|
||||||
<$updateHorizon(horizons.y, -deltaPixelTap)$>
|
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
|
@ -379,7 +381,8 @@ vec2 searchHorizons(ivec4 side, ivec2 centerPixelPos, vec2 imageSize, vec2 delta
|
||||||
int stepCount = int(max(absClampedSearchVec.x, absClampedSearchVec.y));
|
int stepCount = int(max(absClampedSearchVec.x, absClampedSearchVec.y));
|
||||||
if (stepCount>0) {
|
if (stepCount>0) {
|
||||||
vec2 deltaPixelTap = clampedSearchVec / float(stepCount);
|
vec2 deltaPixelTap = clampedSearchVec / float(stepCount);
|
||||||
float deltaRadius = length(deltaPixelTap);
|
float searchRadius = length(clampedSearchVec);
|
||||||
|
float deltaRadius = searchRadius / float(stepCount);
|
||||||
<$updateHorizon(horizons.x, deltaPixelTap)$>
|
<$updateHorizon(horizons.x, deltaPixelTap)$>
|
||||||
}
|
}
|
||||||
// Backward search for h2
|
// Backward search for h2
|
||||||
|
@ -388,32 +391,11 @@ vec2 searchHorizons(ivec4 side, ivec2 centerPixelPos, vec2 imageSize, vec2 delta
|
||||||
stepCount = int(max(absClampedSearchVec.x, absClampedSearchVec.y));
|
stepCount = int(max(absClampedSearchVec.x, absClampedSearchVec.y));
|
||||||
if (stepCount>0) {
|
if (stepCount>0) {
|
||||||
vec2 deltaPixelTap = clampedSearchVec / float(stepCount);
|
vec2 deltaPixelTap = clampedSearchVec / float(stepCount);
|
||||||
float deltaRadius = length(deltaPixelTap);
|
float searchRadius = length(clampedSearchVec);
|
||||||
|
float deltaRadius = searchRadius / float(stepCount);
|
||||||
<$updateHorizon(horizons.y, deltaPixelTap)$>
|
<$updateHorizon(horizons.y, deltaPixelTap)$>
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// <!
|
|
||||||
//
|
|
||||||
|
|
||||||
/* TEMPO OP
|
|
||||||
// Bresenham style walk along segment
|
|
||||||
if (absSearchVec.x > absSearchVec.y) {
|
|
||||||
<$searchBresenhamHorizon(x)$>
|
|
||||||
} else {
|
|
||||||
<$searchBresenhamHorizon(y)$>
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 angles = acos(vec3(horizons, fragNormalES.z)) - PI/2.0;
|
|
||||||
angles.x = -angles.x;
|
|
||||||
// Clamp to limit horizon defined by normal plane
|
|
||||||
horizons.xy = angles.zz + max(angles.xy - angles.zz, vec2(-PI/2.0, PI/2.0));
|
|
||||||
*/
|
|
||||||
|
|
||||||
//
|
|
||||||
// !>
|
|
||||||
//
|
|
||||||
|
|
||||||
return horizons;
|
return horizons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,7 +442,7 @@ float fetchOcclusion(vec2 coords) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const float BLUR_WEIGHT_OFFSET = 0.01;
|
const float BLUR_WEIGHT_OFFSET = 0.01;
|
||||||
const float BLUR_EDGE_SCALE = 10.0;
|
const float BLUR_EDGE_SCALE = 300.0;
|
||||||
|
|
||||||
vec2 evalTapWeightedValue(ivec3 side, int r, ivec2 destPixelCoord, vec2 scaledTexCoord, vec2 fullTexCoord, float key) {
|
vec2 evalTapWeightedValue(ivec3 side, int r, ivec2 destPixelCoord, vec2 scaledTexCoord, vec2 fullTexCoord, float key) {
|
||||||
ivec2 tapOffset = <$axis$> * r;
|
ivec2 tapOffset = <$axis$> * r;
|
||||||
|
@ -479,7 +461,9 @@ vec2 evalTapWeightedValue(ivec3 side, int r, ivec2 destPixelCoord, vec2 scaledTe
|
||||||
float weight = BLUR_WEIGHT_OFFSET + getBlurCoef(abs(r));
|
float weight = BLUR_WEIGHT_OFFSET + getBlurCoef(abs(r));
|
||||||
|
|
||||||
// range domain (the "bilateral" weight). As depth difference increases, decrease weight.
|
// range domain (the "bilateral" weight). As depth difference increases, decrease weight.
|
||||||
weight *= max(0.0, 1.0 - (getBlurEdgeSharpness() * BLUR_EDGE_SCALE) * abs(tapDepth - key));
|
// weight *= max(0.0, 1.0 - (getBlurEdgeSharpness() * BLUR_EDGE_SCALE) * abs(tapDepth - key));
|
||||||
|
float zDistance = tapDepth - key;
|
||||||
|
weight *= exp(-(getBlurEdgeSharpness() * BLUR_EDGE_SCALE) * zDistance * zDistance);
|
||||||
|
|
||||||
return vec2(tapOcclusion * weight, weight);
|
return vec2(tapOcclusion * weight, weight);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
<$declarePackOcclusionDepth()$>
|
<$declarePackOcclusionDepth()$>
|
||||||
|
|
||||||
#define SSAO_USE_HORIZON_BASED 1
|
#define SSAO_USE_HORIZON_BASED 1
|
||||||
|
#define SSAO_HBAO_MAX_RADIUS 100.0
|
||||||
|
|
||||||
layout(location=0) out vec4 outFragColor;
|
layout(location=0) out vec4 outFragColor;
|
||||||
|
|
||||||
|
@ -46,6 +47,9 @@ void main(void) {
|
||||||
|
|
||||||
// Choose the screen-space sample radius
|
// Choose the screen-space sample radius
|
||||||
float ssDiskRadius = evalDiskRadius(fragPositionES.z, imageSize);
|
float ssDiskRadius = evalDiskRadius(fragPositionES.z, imageSize);
|
||||||
|
#if SSAO_USE_HORIZON_BASED
|
||||||
|
ssDiskRadius = min(ssDiskRadius, SSAO_HBAO_MAX_RADIUS);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Let's make noise
|
// Let's make noise
|
||||||
float randomPatternRotationAngle = getAngleDithering(centerPixelPos);
|
float randomPatternRotationAngle = getAngleDithering(centerPixelPos);
|
||||||
|
|
|
@ -37,10 +37,10 @@ Rectangle {
|
||||||
"Level:obscuranceLevel:1.0:false",
|
"Level:obscuranceLevel:1.0:false",
|
||||||
"Num Taps:numSamples:32:true",
|
"Num Taps:numSamples:32:true",
|
||||||
"Taps Spiral:numSpiralTurns:10.0:false",
|
"Taps Spiral:numSpiralTurns:10.0:false",
|
||||||
"Falloff Bias:falloffBias:0.2:false",
|
"Falloff Angle:falloffAngle:0.2:false",
|
||||||
"Silhouette Radius:silhouetteRadius:1.0:false",
|
"Falloff Distance:falloffDistance:2.0:false",
|
||||||
"Blur Edge Sharpness:edgeSharpness:1.0:false",
|
"Blur Edge Sharpness:edgeSharpness:1.0:false",
|
||||||
"Blur Radius:blurRadius:10.0:false",
|
"Blur Radius:blurRadius:15.0:false",
|
||||||
]
|
]
|
||||||
ConfigSlider {
|
ConfigSlider {
|
||||||
label: qsTr(modelData.split(":")[0])
|
label: qsTr(modelData.split(":")[0])
|
||||||
|
|
Loading…
Reference in a new issue