diff options
author | Brecht Van Lommel <brecht@blender.org> | 2021-09-20 18:59:20 +0300 |
---|---|---|
committer | Brecht Van Lommel <brecht@blender.org> | 2021-09-21 15:55:54 +0300 |
commit | 08031197250aeecbaca3803254e6f25b8c7b7b37 (patch) | |
tree | 6fe7ab045f0dc0a423d6557c4073f34309ef4740 /intern/cycles/kernel/bvh/bvh_shadow_all.h | |
parent | fa6b1007bad065440950cd67deb16a04f368856f (diff) |
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
Diffstat (limited to 'intern/cycles/kernel/bvh/bvh_shadow_all.h')
-rw-r--r-- | intern/cycles/kernel/bvh/bvh_shadow_all.h | 105 |
1 files changed, 62 insertions, 43 deletions
diff --git a/intern/cycles/kernel/bvh/bvh_shadow_all.h b/intern/cycles/kernel/bvh/bvh_shadow_all.h index 2e94b1d7c37..0ae36fccf9b 100644 --- a/intern/cycles/kernel/bvh/bvh_shadow_all.h +++ b/intern/cycles/kernel/bvh/bvh_shadow_all.h @@ -36,7 +36,7 @@ ccl_device #else ccl_device_inline #endif - bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, + bool BVH_FUNCTION_FULL_NAME(BVH)(const KernelGlobals *kg, const Ray *ray, Intersection *isect_array, const uint visibility, @@ -68,10 +68,10 @@ ccl_device_inline Transform ob_itfm; #endif - int num_hits_in_instance = 0; + float t_world_to_instance = 1.0f; *num_hits = 0; - isect_array->t = tmax; + Intersection *isect = isect_array; /* traversal loop */ do { @@ -147,13 +147,14 @@ ccl_device_inline switch (p_type) { case PRIMITIVE_TRIANGLE: { - hit = triangle_intersect(kg, isect_array, P, dir, visibility, object, prim_addr); + hit = triangle_intersect( + kg, isect, P, dir, isect_t, visibility, object, prim_addr); break; } #if BVH_FEATURE(BVH_MOTION) case PRIMITIVE_MOTION_TRIANGLE: { hit = motion_triangle_intersect( - kg, isect_array, P, dir, ray->time, visibility, object, prim_addr); + kg, isect, P, dir, isect_t, ray->time, visibility, object, prim_addr); break; } #endif @@ -163,8 +164,16 @@ ccl_device_inline case PRIMITIVE_CURVE_RIBBON: case PRIMITIVE_MOTION_CURVE_RIBBON: { const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr); - hit = curve_intersect( - kg, isect_array, P, dir, visibility, object, prim_addr, ray->time, curve_type); + hit = curve_intersect(kg, + isect, + P, + dir, + isect_t, + visibility, + object, + prim_addr, + ray->time, + curve_type); break; } #endif @@ -176,27 +185,49 @@ ccl_device_inline /* shadow ray early termination */ if (hit) { + /* Convert intersection distance to world space. */ + isect->t /= t_world_to_instance; + /* detect if this surface has a shader with transparent shadows */ /* todo: optimize so primitive visibility flag indicates if * the primitive has a transparent shadow shader? */ - const int flags = intersection_get_shader_flags(kg, isect_array); + const int flags = intersection_get_shader_flags(kg, isect); - /* if no transparent shadows, all light is blocked */ - if (!(flags & SD_HAS_TRANSPARENT_SHADOW)) { - return true; - } - /* if maximum number of hits reached, block all light */ - else if (*num_hits == max_hits) { + if (!(flags & SD_HAS_TRANSPARENT_SHADOW) || max_hits == 0) { + /* If no transparent shadows, all light is blocked and we can + * stop immediately. */ return true; } - /* move on to next entry in intersections array */ - isect_array++; + /* Increase the number of hits, possibly beyond max_hits, we will + * simply not record those and only keep the max_hits closest. */ (*num_hits)++; - num_hits_in_instance++; - isect_array->t = isect_t; + if (*num_hits >= max_hits) { + /* If maximum number of hits reached, find the intersection with + * the largest distance to potentially replace when another hit + * is found. */ + const int num_recorded_hits = min(max_hits, *num_hits); + float max_recorded_t = isect_array[0].t; + int max_recorded_hit = 0; + + for (int i = 1; i < num_recorded_hits; i++) { + if (isect_array[i].t > max_recorded_t) { + max_recorded_t = isect_array[i].t; + max_recorded_hit = i; + } + } + + isect = isect_array + max_recorded_hit; + + /* Limit the ray distance and stop counting hits beyond this. */ + isect_t = max_recorded_t * t_world_to_instance; + } + else { + /* Still have space for intersection, use next hit. */ + isect = isect + 1; + } } prim_addr++; @@ -207,13 +238,14 @@ ccl_device_inline object = kernel_tex_fetch(__prim_object, -prim_addr - 1); #if BVH_FEATURE(BVH_MOTION) - isect_t = bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, isect_t, &ob_itfm); + t_world_to_instance = bvh_instance_motion_push( + kg, object, ray, &P, &dir, &idir, &ob_itfm); #else - isect_t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect_t); + t_world_to_instance = bvh_instance_push(kg, object, ray, &P, &dir, &idir); #endif - num_hits_in_instance = 0; - isect_array->t = isect_t; + /* Convert intersection to object space. */ + isect_t *= t_world_to_instance; ++stack_ptr; kernel_assert(stack_ptr < BVH_STACK_SIZE); @@ -228,32 +260,19 @@ ccl_device_inline kernel_assert(object != OBJECT_NONE); /* Instance pop. */ - if (num_hits_in_instance) { - float t_fac; - #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX, &ob_itfm); #else - bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac); + bvh_instance_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX); #endif - /* scale isect->t to adjust for instancing */ - for (int i = 0; i < num_hits_in_instance; i++) { - (isect_array - i - 1)->t *= t_fac; - } - } - else { -#if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX, &ob_itfm); -#else - bvh_instance_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX); -#endif - } - - isect_t = tmax; - isect_array->t = isect_t; + /* Restore world space ray length. If max number of hits exceeded this + * distance is reduced to recorded only the closest hits. If not use + * the original ray length. */ + isect_t = (max_hits && *num_hits > max_hits) ? isect->t : tmax; object = OBJECT_NONE; + t_world_to_instance = 1.0f; node_addr = traversal_stack[stack_ptr]; --stack_ptr; } @@ -262,7 +281,7 @@ ccl_device_inline return false; } -ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg, +ccl_device_inline bool BVH_FUNCTION_NAME(const KernelGlobals *kg, const Ray *ray, Intersection *isect_array, const uint visibility, |