Switched back to cos HBAO

This commit is contained in:
Olivier Prat 2018-10-02 10:26:55 +02:00
parent 7f6c9a6cc1
commit 454531e3c3
5 changed files with 66 additions and 49 deletions

View file

@ -209,7 +209,7 @@ AmbientOcclusionEffectConfig::AmbientOcclusionEffectConfig() :
radius{ 0.5f },
perspectiveScale{ 1.0f },
obscuranceLevel{ 0.25f },
falloffAngle{ 0.7f },
falloffAngle{ 0.4f },
edgeSharpness{ 1.0f },
blurDeviation{ 2.5f },
numSpiralTurns{ 7.0f },
@ -219,15 +219,16 @@ AmbientOcclusionEffectConfig::AmbientOcclusionEffectConfig() :
ditheringEnabled{ true },
borderingEnabled{ true },
fetchMipsEnabled{ true },
horizonBased{ true } {
horizonBased{ true },
jitterEnabled{ true }{
}
AmbientOcclusionEffect::AOParameters::AOParameters() {
_resolutionInfo = { -1.0f, 1.0f, 1.0f, 0.0f };
_radiusInfo = { 0.5f, 0.5f * 0.5f, 1.0f / (0.25f * 0.25f * 0.25f), 1.0f };
_ditheringInfo = { 0.0f, 0.0f, 0.01f, 1.0f };
_sampleInfo = { 11.0f, 1.0f / 11.0f, 7.0f, 1.0f };
_falloffInfo = { 0.5f, 2.0f, 0.866f, 1.1547f };
_resolutionInfo = glm::vec4{ 0.0f };
_radiusInfo = glm::vec4{ 0.0f };
_ditheringInfo = glm::vec4{ 0.0f };
_sampleInfo = glm::vec4{ 0.0f };
_falloffInfo = glm::vec4{ 0.0f };
}
AmbientOcclusionEffect::BlurParameters::BlurParameters() {
@ -242,6 +243,8 @@ void AmbientOcclusionEffect::configure(const Config& config) {
bool shouldUpdateBlurs = false;
_isJitterEnabled = config.jitterEnabled;
const double RADIUS_POWER = 6.0;
const auto& radius = config.radius;
if (radius != _aoParametersBuffer->getRadius() || config.horizonBased != _aoParametersBuffer->isHorizonBased()) {
@ -321,6 +324,7 @@ void AmbientOcclusionEffect::configure(const Config& config) {
}
_randomSamples[i] = r * 2.0f * M_PI / config.numSamples;
}
updateJitterSamples();
}
if (config.fetchMipsEnabled != _aoParametersBuffer->isFetchMipsEnabled()) {
@ -472,6 +476,14 @@ int AmbientOcclusionEffect::getDepthResolutionLevel() const {
return std::min(1, _aoParametersBuffer->getResolutionLevel());
}
void AmbientOcclusionEffect::updateJitterSamples() {
const int SSAO_RANDOM_SAMPLE_COUNT = int(_randomSamples.size() / (SSAO_SPLIT_COUNT*SSAO_SPLIT_COUNT));
for (int splitId = 0; splitId < SSAO_SPLIT_COUNT*SSAO_SPLIT_COUNT; splitId++) {
auto& sample = _aoFrameParametersBuffer[splitId].edit();
sample._angleInfo.x = _randomSamples[splitId + SSAO_RANDOM_SAMPLE_COUNT * _frameId];
}
}
void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) {
assert(renderContext->args);
assert(renderContext->args->hasViewFrustum());
@ -534,12 +546,11 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
auto occlusionDepthSize = glm::ivec2(occlusionDepthTexture->getDimensions());
// Update sample rotation
const int SSAO_RANDOM_SAMPLE_COUNT = int(_randomSamples.size() / (SSAO_SPLIT_COUNT*SSAO_SPLIT_COUNT));
for (int splitId=0 ; splitId < SSAO_SPLIT_COUNT*SSAO_SPLIT_COUNT ; splitId++) {
auto& sample = _aoFrameParametersBuffer[splitId].edit();
sample._angleInfo.x = _randomSamples[splitId + SSAO_RANDOM_SAMPLE_COUNT * _frameId];
if (_isJitterEnabled) {
const int SSAO_RANDOM_SAMPLE_COUNT = int(_randomSamples.size() / (SSAO_SPLIT_COUNT*SSAO_SPLIT_COUNT));
updateJitterSamples();
_frameId = (_frameId + 1) % SSAO_RANDOM_SAMPLE_COUNT;
}
//_frameId = (_frameId + 1) % SSAO_RANDOM_SAMPLE_COUNT;
gpu::doInBatch("AmbientOcclusionEffect::run", args->_context, [=](gpu::Batch& batch) {
PROFILE_RANGE_BATCH(batch, "SSAO");

View file

@ -83,6 +83,7 @@ class AmbientOcclusionEffectConfig : public render::GPUJobConfig::Persistent {
Q_PROPERTY(bool ditheringEnabled MEMBER ditheringEnabled NOTIFY dirty)
Q_PROPERTY(bool borderingEnabled MEMBER borderingEnabled NOTIFY dirty)
Q_PROPERTY(bool fetchMipsEnabled MEMBER fetchMipsEnabled NOTIFY dirty)
Q_PROPERTY(bool jitterEnabled MEMBER jitterEnabled NOTIFY dirty)
Q_PROPERTY(float radius MEMBER radius WRITE setRadius)
Q_PROPERTY(float obscuranceLevel MEMBER obscuranceLevel WRITE setObscuranceLevel)
Q_PROPERTY(float falloffAngle MEMBER falloffAngle WRITE setFalloffAngle)
@ -123,6 +124,7 @@ public:
bool ditheringEnabled; // randomize the distribution of taps per pixel, should always be true
bool borderingEnabled; // avoid evaluating information from non existing pixels out of the frame, should always be true
bool fetchMipsEnabled; // fetch taps in sub mips to otpimize cache, should always be true
bool jitterEnabled; // Add small jittering to AO samples at each frame
signals:
void dirty();
@ -181,6 +183,7 @@ private:
void updateBlurParameters();
void updateFramebufferSizes();
void updateJitterSamples();
int getDepthResolutionLevel() const;
@ -204,6 +207,7 @@ private:
AmbientOcclusionFramebufferPointer _framebuffer;
std::array<float, 8 * SSAO_SPLIT_COUNT*SSAO_SPLIT_COUNT> _randomSamples;
int _frameId{ 0 };
bool _isJitterEnabled{ true };
gpu::RangeTimerPointer _gpuTimer;

View file

@ -390,12 +390,14 @@ float evalVisibilitySSAO(in vec3 centerPosition, in vec3 centerNormal, in vec3 t
return f * f * f * max((vn - getFalloffCosAngle()) / (epsilon + vv), 0.0);
}
#define HBAO_USE_COS_ANGLE 0
#define HBAO_USE_COS_ANGLE 1
float computeWeightForHorizon(float horizonLimit, float distanceSquared) {
return max(0.0, 1.0 - distanceSquared / getRadius2());
}
float computeWeightedHorizon(float horizonLimit, float distanceSquared) {
float radiusFalloff = distanceSquared / getRadius2();
radiusFalloff = max(0.0, 1.0 - radiusFalloff);
float radiusFalloff = computeWeightForHorizon(horizonLimit, distanceSquared);
#if !HBAO_USE_COS_ANGLE
horizonLimit = getFalloffSinAngle() - horizonLimit;
@ -417,44 +419,46 @@ float computeWeightedHorizon(float horizonLimit, float distanceSquared) {
vec3 tapPositionES = evalEyePositionFromZeye(side.x, tapMipZ.y, fragUVPos);
vec3 deltaVec = tapPositionES - fragPositionES;
float distanceSquared = dot(deltaVec, deltaVec);
float distance = sqrt(distanceSquared);
float deltaDotNormal = dot(deltaVec, fragFrameES.normal);
#if HBAO_USE_COS_ANGLE
float tapHorizonLimit = deltaDotNormal;
#else
float tapHorizonLimit = dot(deltaVec, fragFrameES.tangent);
#endif
float epsilon = 0.0001;
tapHorizonLimit /= (distance + epsilon);
tapHorizonLimit *= inversesqrt(distanceSquared);
if (distanceSquared < getRadius2() && deltaDotNormal>0.0 &&
if (distanceSquared < getRadius2() && deltaDotNormal>0.0) {
#if HBAO_USE_COS_ANGLE
tapHorizonLimit > horizonLimit
#else
tapHorizonLimit < horizonLimit
#endif
) {
tapHorizonLimit = computeWeightedHorizon(tapHorizonLimit, distanceSquared);
#if HBAO_USE_COS_ANGLE
horizonLimit = max(horizonLimit, tapHorizonLimit);
float weight = computeWeightForHorizon(tapHorizonLimit, distanceSquared);
if (tapHorizonLimit > horizonLimit) {
occlusion += weight * (tapHorizonLimit - horizonLimit);
horizonLimit = tapHorizonLimit;
} else if (dot(deltaVec, fragFrameES.tangent) < 0.0) {
// This is a hack to try to handle the case where the occlusion angle is
// greater than 90°
occlusion = mix(occlusion, (occlusion+1.0) * 0.5, weight);
}
#else
horizonLimit = min(horizonLimit, tapHorizonLimit);
if (tapHorizonLimit < horizonLimit) {
tapHorizonLimit = computeWeightedHorizon(tapHorizonLimit, distanceSquared);
horizonLimit = min(horizonLimit, tapHorizonLimit);
}
#endif
}
<@endfunc@>
#define HBAO_HORIZON_SEARCH_CONSTANT_STEP 0
float computeHorizon(ivec4 side, vec2 fragUVPos, vec3 fragPositionES, TBNFrame fragFrameES, vec2 searchVec, float searchRadius, int stepCount) {
vec2 absSearchVec = abs(searchVec);
float computeOcclusion(ivec4 side, vec2 fragUVPos, vec3 fragPositionES, TBNFrame fragFrameES, vec2 searchDir, float searchRadius, int stepCount) {
#if HBAO_USE_COS_ANGLE
float horizonLimit = getFalloffCosAngle();
float occlusion = 0.0;
#else
float horizonLimit = getFalloffSinAngle();
#endif
if (stepCount>0) {
vec2 deltaTapUV = searchVec / float(stepCount);
vec2 deltaTapUV = searchDir / float(stepCount);
float deltaRadius = searchRadius / float(stepCount);
#if HBAO_HORIZON_SEARCH_CONSTANT_STEP
@ -487,31 +491,32 @@ float computeHorizon(ivec4 side, vec2 fragUVPos, vec3 fragPositionES, TBNFrame f
#endif
}
return horizonLimit;
#if HBAO_USE_COS_ANGLE
occlusion = min(occlusion * getFalloffCosAngleScale(), 1.0);
#else
occlusion = horizonLimit > 0.0 ? horizonLimit * getFalloffSinAngleScale() : horizonLimit;
#endif
return occlusion;
}
float evalVisibilityHBAO(ivec4 side, vec2 fragUVPos, vec2 invSideImageSize, vec2 deltaTap, float diskPixelRadius,
vec3 fragPositionES, TBNFrame fragFrameES) {
vec2 pixelSearchVec = deltaTap * diskPixelRadius;
vec2 searchVec = pixelSearchVec * invSideImageSize;
vec2 searchDir = pixelSearchVec * invSideImageSize;
float obscuranceH1 = 0.0;
float obscuranceH2 = 0.0;
#if !HBAO_USE_COS_ANGLE
fragFrameES.tangent = normalize(fragFrameES.tangent * deltaTap.x + fragFrameES.binormal * deltaTap.y);
#endif
pixelSearchVec = abs(pixelSearchVec);
int stepCount = int(ceil(max(pixelSearchVec.x, pixelSearchVec.y)));
fragFrameES.tangent = normalize(fragFrameES.tangent * deltaTap.x + fragFrameES.binormal * deltaTap.y);
// Forward search for h1
obscuranceH1 = computeHorizon(side, fragUVPos, fragPositionES, fragFrameES, searchVec, diskPixelRadius, stepCount);
obscuranceH1 = computeOcclusion(side, fragUVPos, fragPositionES, fragFrameES, searchDir, diskPixelRadius, stepCount);
// Backward search for h2
#if !HBAO_USE_COS_ANGLE
fragFrameES.tangent = -fragFrameES.tangent;
#endif
obscuranceH2 = computeHorizon(side, fragUVPos, fragPositionES, fragFrameES, -searchVec, diskPixelRadius, stepCount);
obscuranceH2 = computeOcclusion(side, fragUVPos, fragPositionES, fragFrameES, -searchDir, diskPixelRadius, stepCount);
return obscuranceH1 + obscuranceH2;
}

View file

@ -60,9 +60,7 @@ void main(void) {
fragFrameES.tangent = vec3(0.0);
fragFrameES.binormal = vec3(0.0);
fragFrameES.normal = fragNormalES;
#if !HBAO_USE_COS_ANGLE
buildTangentBinormal(side, fragUVPos, fragPositionES, fragNormalES, deltaDepthUV, fragFrameES.tangent, fragFrameES.binormal);
#endif
// Let's make noise
float randomPatternRotationAngle = getAngleDithering(fragPixelPos);
@ -79,12 +77,10 @@ void main(void) {
}
obscuranceSum *= invNumSamples;
#if HBAO_USE_COS_ANGLE
obscuranceSum *= 0.5 / PI;
obscuranceSum = 1.0 - obscuranceSum * obscuranceSum * getObscuranceScaling();
obscuranceSum *= 0.5;
obscuranceSum = 1.0 - obscuranceSum * getObscuranceScaling();
#else
obscuranceSum *= 0.5;
obscuranceSum += 1.0 - getFalloffSinAngle();
obscuranceSum = mix(1.0, obscuranceSum, getObscuranceScaling());
#endif
} else {

View file

@ -59,6 +59,7 @@ Rectangle {
Repeater {
model: [
"horizonBased:horizonBased",
"jitterEnabled:jitterEnabled",
"ditheringEnabled:ditheringEnabled",
"fetchMipsEnabled:fetchMipsEnabled",
"borderingEnabled:borderingEnabled"