Eevee: Contact Shadows: Fix remaining artifacts.

There was noise correlation between the rotation random number and the radius random number used in the contact shadow algo.
Hacking a new distribution from the old distribution (may not be ideal because it's discrepency may be high)
Also distribute samples evenly on the shadow disc. (add sqrt)

Fix the "bias floating shadows", was cause by the discarding of backfacing geom which makes no sense in this case.
This commit is contained in:
Clément Foucault 2017-10-12 17:35:59 +02:00
parent e416f417e0
commit a09b8c08fc
4 changed files with 15 additions and 8 deletions

View File

@ -57,7 +57,7 @@ vec4 do_planar_ssr(int index, vec3 V, vec3 N, vec3 T, vec3 B, vec3 planeNormal,
* below the reflection plane). This way it's garanted that the hit will
* be in front of the camera. That let us tag the bad rays with a negative
* sign in the Z component. */
vec3 hit_pos = raycast(index, viewPosition, R * 1e16, 1e16, jitter, ssrQuality, a2);
vec3 hit_pos = raycast(index, viewPosition, R * 1e16, 1e16, jitter, ssrQuality, a2, false);
return vec4(hit_pos, pdf);
}
@ -76,7 +76,7 @@ vec4 do_ssr(vec3 V, vec3 N, vec3 T, vec3 B, vec3 viewPosition, float a2, vec3 ra
vec3 R = reflect(-V, H);
pdf = min(1024e32, pdf); /* Theoretical limit of 16bit float */
vec3 hit_pos = raycast(-1, viewPosition, R * 1e16, ssrThickness, jitter, ssrQuality, a2);
vec3 hit_pos = raycast(-1, viewPosition, R * 1e16, ssrThickness, jitter, ssrQuality, a2, true);
return vec4(hit_pos, pdf);
}

View File

@ -202,7 +202,9 @@ float light_visibility(LightData ld, vec3 W,
make_orthonormal_basis(L.xyz / L.w, T, B);
vec3 rand = texture(utilTex, vec3(gl_FragCoord.xy / LUT_SIZE, 2.0)).xzw;
rand.yz *= rand.x * data.sh_contact_spread;
/* XXX This is a hack to not have noise correlation artifacts.
* A better solution to have better noise is welcome. */
rand.yz *= fast_sqrt(fract(rand.x * 7919.0)) * data.sh_contact_spread;
/* We use the full l_vector.xyz so that the spread is minimize
* if the shading point is further away from the light source */
@ -210,7 +212,8 @@ float light_visibility(LightData ld, vec3 W,
ray_dir = transform_direction(ViewMatrix, ray_dir);
ray_dir = normalize(ray_dir);
vec3 ray_origin = viewPosition + viewNormal * data.sh_contact_offset;
vec3 hit_pos = raycast(-1, ray_origin, ray_dir * trace_distance, data.sh_contact_thickness, rand.x, 0.75, 0.01);
vec3 hit_pos = raycast(-1, ray_origin, ray_dir * trace_distance, data.sh_contact_thickness, rand.x,
0.75, 0.01, false);
if (hit_pos.z > 0.0) {
hit_pos = get_view_space_from_depth(hit_pos.xy, hit_pos.z);

View File

@ -118,7 +118,9 @@ void prepare_raycast(vec3 ray_origin, vec3 ray_end, float thickness, out vec4 ss
// #define GROUPED_FETCHES /* is still slower, need to see where is the bottleneck. */
/* Return the hit position, and negate the z component (making it positive) if not hit occured. */
/* __ray_end__ is the ray direction premultiplied by it's maximum length */
vec3 raycast(int index, vec3 ray_origin, vec3 ray_end, float thickness, float ray_jitter, float trace_quality, float roughness)
vec3 raycast(
int index, vec3 ray_origin, vec3 ray_end, float thickness, float ray_jitter,
float trace_quality, float roughness, const bool discard_backface)
{
vec4 ss_step, ss_start;
float max_time;
@ -199,8 +201,10 @@ vec3 raycast(int index, vec3 ray_origin, vec3 ray_end, float thickness, float ra
#endif
}
/* Discard backface hits */
hit = hit && (prev_delta > 0.0);
if (discard_backface) {
/* Discard backface hits */
hit = hit && (prev_delta > 0.0);
}
/* Reject hit if background. */
hit = hit && (depth_sample != 1.0);

View File

@ -33,7 +33,7 @@ vec4 screen_space_refraction(vec3 viewPosition, vec3 N, vec3 V, float ior, float
R = transform_direction(ViewMatrix, R);
vec3 hit_pos = raycast(-1, viewPosition, R * 1e16, ssrThickness, jitter, ssrQuality, roughnessSquared);
vec3 hit_pos = raycast(-1, viewPosition, R * 1e16, ssrThickness, jitter, ssrQuality, roughnessSquared, false);
if ((hit_pos.z > 0.0) && (F_eta(ior, dot(H, V)) < 1.0)) {
hit_pos = get_view_space_from_depth(hit_pos.xy, hit_pos.z);