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:
committed by
Mathias Agopian
parent
5583dc26f9
commit
0da551c7fd
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -347,7 +347,8 @@ static void gui(filament::Engine* engine, filament::View*) {
|
||||
DebugRegistry& debug = engine->getDebugRegistry();
|
||||
ImGui::Checkbox("enabled###ssao", ¶ms.ssao);
|
||||
ImGui::SliderFloat("radius", ¶ms.ssaoOptions.radius, 0.05f, 5.0f);
|
||||
ImGui::SliderFloat("bias", ¶ms.ssaoOptions.bias, 0.0f, 0.1f);
|
||||
ImGui::SliderFloat("bias", ¶ms.ssaoOptions.bias, 0.0f, 0.01f, "%.6f");
|
||||
ImGui::SliderFloat("intensity", ¶ms.ssaoOptions.intensity, 0.0f, 10.0f);
|
||||
ImGui::SliderFloat("power", ¶ms.ssaoOptions.power, 0.0f, 1.0f);
|
||||
}
|
||||
ImGui::Unindent();
|
||||
|
||||
Reference in New Issue
Block a user