More improvements to SSAO

- we add an 'intensity' parameter that allows to control the strength
  of the AO effect. This is useful for aesthetic reasons.

- the default intensity is now 2x that of before this change, which
  makes the intensity parameter match AO papers this implementation
  is inspired of.

- bias is now z-dependent, which reduces some self shadowing wrt the
  depth.
This commit is contained in:
Pixelflinger
2019-11-15 09:42:37 -08:00
committed by Mathias Agopian
parent 5583dc26f9
commit 0da551c7fd
6 changed files with 27 additions and 8 deletions
@@ -241,8 +241,14 @@ Java_com_google_android_filament_View_nGetAmbientOcclusion(JNIEnv*, jclass, jlon
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetAmbientOcclusionOptions(JNIEnv*, jclass,
jlong nativeView, jfloat radius, jfloat bias, jfloat power, jfloat resolution) {
jlong nativeView, jfloat radius, jfloat bias, jfloat power, jfloat resolution, jfloat intensity) {
View* view = (View*) nativeView;
View::AmbientOcclusionOptions options = { .radius = radius, .bias = bias, .power = power, .resolution = resolution};
View::AmbientOcclusionOptions options = {
.radius = radius,
.bias = bias,
.power = power,
.resolution = resolution,
.intensity = intensity
};
view->setAmbientOcclusionOptions(options);
}
@@ -149,6 +149,11 @@ public class View {
* How each dimension of the AO buffer is scaled. Must be positive and <= 1.
*/
public float resolution = 0.5f;
/**
* Strength of the Ambient Occlusion effect. Must be positive.
*/
public float intensity = 1.0f;
}
/**
@@ -761,7 +766,8 @@ public class View {
*/
public void setAmbientOcclusionOptions(@NonNull AmbientOcclusionOptions options) {
mAmbientOcclusionOptions = options;
nSetAmbientOcclusionOptions(getNativeObject(), options.radius, options.bias, options.power, options.resolution);
nSetAmbientOcclusionOptions(getNativeObject(), options.radius, options.bias, options.power,
options.resolution, options.intensity);
}
/**
@@ -819,5 +825,5 @@ public class View {
private static native boolean nIsFrontFaceWindingInverted(long nativeView);
private static native void nSetAmbientOcclusion(long nativeView, int ordinal);
private static native int nGetAmbientOcclusion(long nativeView);
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution);
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity);
}
+2 -1
View File
@@ -147,9 +147,10 @@ public:
*/
struct AmbientOcclusionOptions {
float radius = 0.3f; //!< Ambient Occlusion radius in meters, between 0 and ~10.
float bias = 0.005f; //!< Self-occlusion bias in meters. Use to avoid self-occlusion. Between 0 and a few mm.
float bias = 0.0001f; //!< Self-occlusion bias in meters. Use to avoid self-occlusion. Between 0 and a few mm.
float power = 0.0f; //!< Controls ambient occlusion's contrast. Between 0 (linear) and 1 (squared)
float resolution = 0.5; //!< How each dimension of the AO buffer is scaled. Must be positive and <= 1.
float intensity = 1.0; //!< Strength of the Ambient Occlusion effect.
};
/**
+1
View File
@@ -377,6 +377,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::ssao(FrameGraph& fg, RenderP
pInstance->setParameter("projectionScaleRadius", projectionScale * data.options.radius);
pInstance->setParameter("bias", data.options.bias);
pInstance->setParameter("power", data.options.power);
pInstance->setParameter("intensity", std::max(0.0f, data.options.intensity));
pInstance->setParameter("maxLevel", uint32_t(levelCount - 1));
pInstance->commit(driver);
+6 -2
View File
@@ -30,6 +30,10 @@ material {
type : float,
name : power
},
{
type : float,
name : intensity
},
{
type : int,
name : maxLevel
@@ -234,7 +238,7 @@ fragment {
float vn = dot(v, normal); // distance * cos(v, normal)
const float uu = 0.015;
float falloff = saturate(1.0 - vv * materialParams.invRadiusSquared);
float occlusion = falloff * max(0.0, vn - materialParams.bias) / (vv + uu);
float occlusion = falloff * max(0.0, vn + origin.z * materialParams.bias) / (vv + uu);
return occlusion;
}
@@ -258,7 +262,7 @@ fragment {
occlusion += computeAmbientOcclusionSAO(i, ssDiskRadius, ssOrigin, origin, normal, noise);
}
float ao = 1.0 - occlusion / float(kSpiralSampleCount);
float ao = max(0.0, 1.0 - (2.0 / float(kSpiralSampleCount)) * materialParams.intensity * occlusion);
// simulate user-controled ao^n with n[1, 2]
ao = mix(ao, ao * ao, materialParams.power);
+2 -1
View File
@@ -347,7 +347,8 @@ static void gui(filament::Engine* engine, filament::View*) {
DebugRegistry& debug = engine->getDebugRegistry();
ImGui::Checkbox("enabled###ssao", &params.ssao);
ImGui::SliderFloat("radius", &params.ssaoOptions.radius, 0.05f, 5.0f);
ImGui::SliderFloat("bias", &params.ssaoOptions.bias, 0.0f, 0.1f);
ImGui::SliderFloat("bias", &params.ssaoOptions.bias, 0.0f, 0.01f, "%.6f");
ImGui::SliderFloat("intensity", &params.ssaoOptions.intensity, 0.0f, 10.0f);
ImGui::SliderFloat("power", &params.ssaoOptions.power, 0.0f, 1.0f);
}
ImGui::Unindent();