Added config parameter to switch between HBAO / SSAO

This commit is contained in:
Olivier Prat 2018-09-27 16:39:42 +02:00
parent 94a162893a
commit 349a8b39ad
6 changed files with 51 additions and 53 deletions

View file

@ -202,36 +202,24 @@ gpu::TexturePointer AmbientOcclusionFramebuffer::getNormalTexture() {
AmbientOcclusionEffectConfig::AmbientOcclusionEffectConfig() :
render::GPUJobConfig::Persistent(QStringList() << "Render" << "Engine" << "Ambient Occlusion", false),
#if SSAO_USE_HORIZON_BASED
radius{ 0.3f },
#else
radius{ 0.5f },
#endif
perspectiveScale{ 1.0f },
obscuranceLevel{ 0.5f },
#if SSAO_USE_HORIZON_BASED
falloffAngle{ 0.3f },
#else
falloffAngle{ 0.01f },
#endif
edgeSharpness{ 1.0f },
blurDeviation{ 2.5f },
numSpiralTurns{ 7.0f },
#if SSAO_USE_HORIZON_BASED
numSamples{ 1 },
#else
numSamples{ 16 },
#endif
resolutionLevel{ 2 },
blurRadius{ 4 },
ditheringEnabled{ true },
borderingEnabled{ true },
fetchMipsEnabled{ true } {
fetchMipsEnabled{ true },
horizonBased{ true } {
}
AmbientOcclusionEffect::AOParameters::AOParameters() {
_resolutionInfo = { -1.0f, 0.0f, 1.0f, 0.0f };
_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 };
@ -251,14 +239,19 @@ void AmbientOcclusionEffect::configure(const Config& config) {
const double RADIUS_POWER = 6.0;
const auto& radius = config.radius;
if (radius != _aoParametersBuffer->getRadius()) {
if (radius != _aoParametersBuffer->getRadius() || config.horizonBased != _aoParametersBuffer->isHorizonBased()) {
auto& current = _aoParametersBuffer.edit()._radiusInfo;
current.x = radius;
current.y = radius * radius;
current.z = 10.0f;
#if !SSAO_USE_HORIZON_BASED
current.z *= (float)(1.0 / pow((double)radius, RADIUS_POWER));
#endif
if (!config.horizonBased) {
current.z *= (float)(1.0 / pow((double)radius, RADIUS_POWER));
}
}
if (config.horizonBased != _aoParametersBuffer->isHorizonBased()) {
auto& current = _aoParametersBuffer.edit()._resolutionInfo;
current.y = config.horizonBased & 1;
}
if (config.obscuranceLevel != _aoParametersBuffer->getObscuranceLevel()) {
@ -501,6 +494,7 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
const auto depthResolutionLevel = getDepthResolutionLevel();
const auto depthResolutionScale = powf(0.5f, depthResolutionLevel);
const auto isHorizonBased = _aoParametersBuffer->isHorizonBased();
auto linearDepthTexture = linearDepthFramebuffer->getLinearDepthTexture();
auto occlusionDepthTexture = linearDepthTexture;
@ -538,9 +532,7 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
auto occlusionPipeline = getOcclusionPipeline();
auto firstHBlurPipeline = getHBlurPipeline();
auto lastVBlurPipeline = getVBlurPipeline();
#if SSAO_USE_HORIZON_BASED
auto mipCreationPipeline = getMipCreationPipeline();
#endif
#if SSAO_USE_QUAD_SPLIT
auto gatherPipeline = getGatherPipeline();
auto buildNormalsPipeline = getBuildNormalsPipeline();
@ -571,14 +563,14 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
batch.setProjectionTransform(glm::mat4());
batch.setModelTransform(Transform());
batch.pushProfileRange("Depth Mip Generation");
// We need this with the mips levels
#if SSAO_USE_HORIZON_BASED
batch.setPipeline(mipCreationPipeline);
batch.generateTextureMipsWithPipeline(occlusionDepthTexture);
#else
batch.generateTextureMips(occlusionDepthTexture);
#endif
batch.pushProfileRange("Depth Mip Generation");
if (isHorizonBased) {
batch.setPipeline(mipCreationPipeline);
batch.generateTextureMipsWithPipeline(occlusionDepthTexture);
} else {
batch.generateTextureMips(occlusionDepthTexture);
}
batch.popProfileRange();
#if SSAO_USE_QUAD_SPLIT
@ -731,8 +723,6 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
config->setGPUBatchRunTime(_gpuTimer->getGPUAverage(), _gpuTimer->getBatchAverage());
}
DebugAmbientOcclusion::DebugAmbientOcclusion() {
}

View file

@ -79,6 +79,7 @@ using AmbientOcclusionFramebufferPointer = std::shared_ptr<AmbientOcclusionFrame
class AmbientOcclusionEffectConfig : public render::GPUJobConfig::Persistent {
Q_OBJECT
Q_PROPERTY(bool enabled MEMBER enabled NOTIFY dirty)
Q_PROPERTY(bool horizonBased MEMBER horizonBased NOTIFY dirty)
Q_PROPERTY(bool ditheringEnabled MEMBER ditheringEnabled NOTIFY dirty)
Q_PROPERTY(bool borderingEnabled MEMBER borderingEnabled NOTIFY dirty)
Q_PROPERTY(bool fetchMipsEnabled MEMBER fetchMipsEnabled NOTIFY dirty)
@ -118,6 +119,7 @@ public:
int numSamples;
int resolutionLevel;
int blurRadius; // 0 means no blurring
bool horizonBased; // Use horizon based AO
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
@ -154,8 +156,10 @@ public:
int getNumSamples() const { return (int)_sampleInfo.x; }
bool isFetchMipsEnabled() const { return _sampleInfo.w; }
bool isDitheringEnabled() const { return _ditheringInfo.x; }
bool isBorderingEnabled() const { return _ditheringInfo.w; }
bool isDitheringEnabled() const { return _ditheringInfo.x != 0.0f; }
bool isBorderingEnabled() const { return _ditheringInfo.w != 0.0f; }
bool isHorizonBased() const { return _resolutionInfo.y != 0.0f; }
};
using AOParametersBuffer = gpu::StructBuffer<AOParameters>;

View file

@ -51,6 +51,10 @@ int getResolutionLevel() {
return int(params._resolutionInfo.x);
}
bool isHorizonBased() {
return params._resolutionInfo.y!=0.0;
}
vec2 getNormalsSideSize() {
return params._sideSizes[0].xy;
}

View file

@ -51,9 +51,9 @@ void main(void) {
// Choose the screen-space sample radius
float diskPixelRadius = evalDiskRadius(fragPositionES.z, sideDepthSize);
#if SSAO_USE_HORIZON_BASED
diskPixelRadius = min(diskPixelRadius, SSAO_HBAO_MAX_RADIUS);
#endif
if (isHorizonBased()) {
diskPixelRadius = min(diskPixelRadius, SSAO_HBAO_MAX_RADIUS);
}
// Let's make noise
float randomPatternRotationAngle = getAngleDithering(fragPixelPos);
@ -63,24 +63,24 @@ void main(void) {
int numSamples = int(getNumSamples());
float invNumSamples = getInvNumSamples();
// Steps are in the depth texture resolution
vec2 depthTexFragPixelPos = fragUVPos * sideDepthSize;
for (int i = 0; i < numSamples; ++i) {
#if SSAO_USE_HORIZON_BASED
vec3 deltaTap = getUnitTapLocation(i, 1.0, randomPatternRotationAngle, PI);
obscuranceSum += evalVisibilityHBAO(side, fragUVPos, deltaDepthUV, deltaTap.xy, diskPixelRadius, fragPositionES, fragNormalES);
#else
vec3 tap = getTapLocationClampedSSAO(i, randomPatternRotationAngle, diskPixelRadius, depthTexFragPixelPos, sideDepthSize);
vec2 tapUV = fragUVPos + tap.xy * deltaDepthUV;
vec2 tapMipZ = fetchTapWithUV(side, tapUV, tap.z);
vec3 tapPositionES = evalEyePositionFromZeye(side.x, tapMipZ.y, tapUV);
obscuranceSum += float(tap.z > 0.0) * evalVisibilitySSAO(fragPositionES, fragNormalES, tapPositionES);
#endif
}
if (isHorizonBased()) {
for (int i = 0; i < numSamples; ++i) {
vec3 deltaTap = getUnitTapLocation(i, 1.0, randomPatternRotationAngle, PI);
obscuranceSum += evalVisibilityHBAO(side, fragUVPos, deltaDepthUV, deltaTap.xy, diskPixelRadius, fragPositionES, fragNormalES);
}
obscuranceSum *= 0.5 / PI;
} else {
// Steps are in the depth texture resolution
vec2 depthTexFragPixelPos = fragUVPos * sideDepthSize;
#if SSAO_USE_HORIZON_BASED
obscuranceSum *= 0.5 / PI;
#endif
for (int i = 0; i < numSamples; ++i) {
vec3 tap = getTapLocationClampedSSAO(i, randomPatternRotationAngle, diskPixelRadius, depthTexFragPixelPos, sideDepthSize);
vec2 tapUV = fragUVPos + tap.xy * deltaDepthUV;
vec2 tapMipZ = fetchTap(side, tapUV, tap.z);
vec3 tapPositionES = evalEyePositionFromZeye(side.x, tapMipZ.y, tapUV);
obscuranceSum += float(tap.z > 0.0) * evalVisibilitySSAO(fragPositionES, fragNormalES, tapPositionES);
}
}
float occlusion = clamp(1.0 - obscuranceSum * getObscuranceScaling() * invNumSamples, 0.0, 1.0);

View file

@ -14,7 +14,6 @@
#ifndef RENDER_UTILS_SSAO_SHARED_H
#define RENDER_UTILS_SSAO_SHARED_H
#define SSAO_USE_HORIZON_BASED 1
#define SSAO_USE_QUAD_SPLIT 1
#if SSAO_USE_QUAD_SPLIT

View file

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