Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl21
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl3
2 files changed, 19 insertions, 5 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
index 4398247472d..e65993175ab 100644
--- a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
@@ -193,6 +193,7 @@ void occlusion_eval(OcclusionData data,
vec3 Ng,
const float inverted,
out float visibility,
+ out float visibility_error,
out vec3 bent_normal)
{
if ((int(aoSettings) & USE_AO) == 0) {
@@ -219,6 +220,7 @@ void occlusion_eval(OcclusionData data,
vec2 noise = get_ao_noise();
vec2 dir = get_ao_dir(noise.x);
+ visibility_error = 0.0;
visibility = 0.0;
bent_normal = N * 0.001;
@@ -258,12 +260,17 @@ void occlusion_eval(OcclusionData data,
float a = dot(-cos(2.0 * h - angle_N) + N_cos + 2.0 * h * N_sin, vec2(0.25));
/* Correct normal not on plane (Eq. 8). */
visibility += proj_N_len * a;
+ /* Using a very low number of slices (2) leads to over-darkening of surfaces orthogonal to
+ * the view. This is particularly annoying for sharp reflections occlusion. So we compute how
+ * much the error is and correct the visibility later. */
+ visibility_error += proj_N_len;
/* Rotate 90 degrees. */
dir = vec2(-dir.y, dir.x);
}
/* We integrated 2 directions. */
visibility *= 0.5;
+ visibility_error *= 0.5;
visibility = min(visibility, data.custom_occlusion);
@@ -297,8 +304,9 @@ float gtao_multibounce(float visibility, vec3 albedo)
float diffuse_occlusion(OcclusionData data, vec3 V, vec3 N, vec3 Ng)
{
vec3 unused;
+ float unused_error;
float visibility;
- occlusion_eval(data, V, N, Ng, 0.0, visibility, unused);
+ occlusion_eval(data, V, N, Ng, 0.0, visibility, unused_error, unused);
/* Scale by user factor */
visibility = pow(saturate(visibility), aoFactor);
return visibility;
@@ -308,7 +316,8 @@ float diffuse_occlusion(
OcclusionData data, vec3 V, vec3 N, vec3 Ng, vec3 albedo, out vec3 bent_normal)
{
float visibility;
- occlusion_eval(data, V, N, Ng, 0.0, visibility, bent_normal);
+ float unused_error;
+ occlusion_eval(data, V, N, Ng, 0.0, visibility, unused_error, bent_normal);
visibility = gtao_multibounce(visibility, albedo);
/* Scale by user factor */
@@ -351,8 +360,12 @@ float specular_occlusion(
OcclusionData data, vec3 V, vec3 N, float roughness, inout vec3 specular_dir)
{
vec3 visibility_dir;
+ float visibility_error;
float visibility;
- occlusion_eval(data, V, N, N, 0.0, visibility, visibility_dir);
+ occlusion_eval(data, V, N, N, 0.0, visibility, visibility_error, visibility_dir);
+
+ /* Correct visibility error for very sharp surfaces. */
+ visibility *= mix(safe_rcp(visibility_error), 1.0, roughness);
specular_dir = normalize(mix(specular_dir, visibility_dir, roughness * (1.0 - visibility)));
@@ -368,7 +381,7 @@ float specular_occlusion(
float specular_solid_angle = spherical_cap_intersection(M_PI_2, spec_angle, cone_nor_dist);
float specular_occlusion = isect_solid_angle / specular_solid_angle;
/* Mix because it is unstable in unoccluded areas. */
- visibility = mix(isect_solid_angle / specular_solid_angle, 1.0, pow(visibility, 8.0));
+ visibility = mix(specular_occlusion, 1.0, pow(visibility, 8.0));
/* Scale by user factor */
visibility = pow(saturate(visibility), aoFactor);
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl
index edf2c93c9a0..12921a31b23 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl
@@ -15,8 +15,9 @@ void node_ambient_occlusion(vec4 color,
vec3 N = normalize(normal);
vec3 Ng = safe_normalize(cross(dFdx(worldPosition), dFdy(worldPosition)));
+ float unused_error;
vec3 unused;
- occlusion_eval(data, V, N, Ng, inverted, result_ao, unused);
+ occlusion_eval(data, V, N, Ng, inverted, result_ao, unused_error, unused);
result_color = result_ao * color;
}
#else