mirror of
https://github.com/lubosz/overte.git
synced 2025-04-11 06:32:09 +02:00
Switched back to cos HBAO
This commit is contained in:
parent
7f6c9a6cc1
commit
454531e3c3
5 changed files with 66 additions and 49 deletions
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -59,6 +59,7 @@ Rectangle {
|
|||
Repeater {
|
||||
model: [
|
||||
"horizonBased:horizonBased",
|
||||
"jitterEnabled:jitterEnabled",
|
||||
"ditheringEnabled:ditheringEnabled",
|
||||
"fetchMipsEnabled:fetchMipsEnabled",
|
||||
"borderingEnabled:borderingEnabled"
|
||||
|
|
Loading…
Reference in a new issue