EEVEE-Next: Add horizon scan to raytracing module #114259

Merged
Clément Foucault merged 51 commits from fclem/blender:eevee-next-horizon-gi into main 2023-11-21 16:24:23 +01:00
2 changed files with 28 additions and 20 deletions
Showing only changes of commit 34e6c95e92 - Show all commits

View File

@ -88,30 +88,12 @@ vec3 horizon_scan_eval(vec3 vP,
vec3 vP_front = drw_point_screen_to_view(vec3(sample_uv, sample_depth));
vec3 vP_back = vP_front - global_thickness * vV;
horizon_scan_occluder_clip_segment_to_sphere(vP_front, vP_back, vP, search_distance);
float dist_front, dist_back;
vec3 vL_front = normalize_and_get_length(vP_front - vP, dist_front);
vec3 vL_back = normalize_and_get_length(vP_back - vP, dist_back);
/* TODO(fclem): This will not fade object correctly.
* The correct way is to clip front and back to the sphere intersection. */
if (vP_front.z > vP.z && vP.z > vP_back.z) {
/* The surface is interesecting the search_distance sphere. */
}
else if (vP_front.z > vP.z) {
/* The surface is in-front of the search_distance sphere center. */
if (dist_back > search_distance) {
/* No intersection with the search_distance sphere. */
continue;
}
}
else if (vP_front.z > vP.z) {
/* The surface is behind of the search_distance sphere center. */
if (dist_front > search_distance) {
/* No intersection with the search_distance sphere. */
continue;
}
}
/* Ordered pair of angle. Mininum in X, Maximum in Y.
* Front will always have the smallest angle here since it is the closest to the view. */
vec2 theta = acos_fast(vec2(dot(vL_front, vV), dot(vL_back, vV)));

View File

@ -81,3 +81,29 @@ float bsdf_eval(vec3 N, vec3 L)
{
return dot(N, L);
}
void horizon_scan_occluder_clip_segment_to_sphere(inout vec3 segment_start,
inout vec3 segment_end,
vec3 sphere_center,
float sphere_radius)
{
/* TODO(fclem): This will not fade object correctly.
* The correct way is to clip front and back to the sphere intersection. */
if (segment_start.z > sphere_center.z && sphere_center.z > segment_end.z) {
/* The segment is interesecting the sphere. */
}
else if (segment_start.z > sphere_center.z) {
/* The segment is in-front of the sphere center. */
if (distance(segment_end, sphere_center) > sphere_radius) {
/* No intersection with the sphere. */
segment_start = segment_end;
}
}
else if (segment_start.z > sphere_center.z) {
/* The segment is behind of the sphere center. */
if (distance(segment_start, sphere_center) > sphere_radius) {
/* No intersection with the sphere. */
segment_start = segment_end;
}
}
}