From cb334428b012294a4503a34e1e2eca5c84d516bd Mon Sep 17 00:00:00 2001 From: Sebastian Herholz Date: Wed, 24 Nov 2021 14:04:34 +0100 Subject: Cycles: fix bugs in point and spot light multiple importance sampling * Spot lights are now handled as disks aligned with the direction of the spotlight instead of view aligned disks. * Point light is now handled separately from the spot light, to fix a case where multiple lights are intersected in a row. Before the origin of the ray was the previously intersected light and not the origin of the initial ray traced from the last surface/volume interaction. This makes both strategies in multiple importance sampling converge to the same result. It changes the render results in some scenes, for example the junkshop scene where there are large point lights overlapping scene geometry and each other. Differential Revision: https://developer.blender.org/D13233 --- intern/cycles/util/math_intersect.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'intern/cycles/util') diff --git a/intern/cycles/util/math_intersect.h b/intern/cycles/util/math_intersect.h index 54ce3ab4b66..0fce9ff24fd 100644 --- a/intern/cycles/util/math_intersect.h +++ b/intern/cycles/util/math_intersect.h @@ -85,6 +85,35 @@ ccl_device bool ray_aligned_disk_intersect(float3 ray_P, return true; } +ccl_device bool ray_disk_intersect(float3 ray_P, + float3 ray_D, + float ray_t, + float3 disk_P, + float3 disk_N, + float disk_radius, + ccl_private float3 *isect_P, + ccl_private float *isect_t) +{ + const float3 vp = ray_P - disk_P; + const float dp = dot(vp, disk_N); + const float cos_angle = dot(disk_N, -ray_D); + if (dp * cos_angle > 0.f) // front of light + { + float t = dp / cos_angle; + if (t < 0.f) { /* Ray points away from the light. */ + return false; + } + float3 P = ray_P + t * ray_D; + float3 T = P - disk_P; + if (dot(T, T) < sqr(disk_radius) /*&& t > 0.f*/ && t <= ray_t) { + *isect_P = ray_P + t * ray_D; + *isect_t = t; + return true; + } + } + return false; +} + ccl_device_forceinline bool ray_triangle_intersect(float3 ray_P, float3 ray_dir, float ray_t, -- cgit v1.2.3