diff options
author | Brecht Van Lommel <brecht@blender.org> | 2021-09-20 17:16:11 +0300 |
---|---|---|
committer | Brecht Van Lommel <brecht@blender.org> | 2021-10-19 16:11:09 +0300 |
commit | fd77a28031daff3122ded3a1cb37a7fb44feedf6 (patch) | |
tree | f54967b7f5f1175555aa21d613137fe436d7fc8c /intern/cycles/kernel/bvh/bvh.h | |
parent | d06828f0b8ebb083de59fd2cb8c5f8fe6af1da22 (diff) |
Cycles: bake transparent shadows for hair
These transparent shadows can be expansive to evaluate. Especially on the
GPU they can lead to poor occupancy when only some pixels require many kernel
launches to trace and evaluate many layers of transparency.
Baked transparency allows tracing a single ray in many cases by accumulating
the throughput directly in the intersection program without recording hits
or evaluating shaders. Transparency is baked at curve vertices and
interpolated, for most shaders this will look practically the same as actual
shader evaluation.
Fixes T91428, performance regression with spring demo file due to transparent
hair, and makes it render significantly faster than Blender 2.93.
Differential Revision: https://developer.blender.org/D12880
Diffstat (limited to 'intern/cycles/kernel/bvh/bvh.h')
-rw-r--r-- | intern/cycles/kernel/bvh/bvh.h | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/intern/cycles/kernel/bvh/bvh.h b/intern/cycles/kernel/bvh/bvh.h index 0d9ba7e6369..813ac15711e 100644 --- a/intern/cycles/kernel/bvh/bvh.h +++ b/intern/cycles/kernel/bvh/bvh.h @@ -367,12 +367,13 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals kg, ccl_private const Ray *ray, uint visibility, uint max_hits, - ccl_private uint *num_hits) + ccl_private uint *num_recorded_hits, + ccl_private float *throughput) { # ifdef __KERNEL_OPTIX__ uint p0 = state; - uint p1 = 0; /* Unused */ - uint p2 = 0; /* Number of hits. */ + uint p1 = __float_as_uint(1.0f); /* Throughput. */ + uint p2 = 0; /* Number of hits. */ uint p3 = max_hits; uint p4 = visibility; uint p5 = false; @@ -382,7 +383,6 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals kg, ray_mask = 0xFF; } - *num_hits = 0; /* Initialize hit count to zero. */ optixTrace(scene_intersect_valid(ray) ? kernel_data.bvh.scene : 0, ray->P, ray->D, @@ -402,12 +402,14 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals kg, p4, p5); - *num_hits = p2; + *num_recorded_hits = uint16_unpack_from_uint_0(p2); + *throughput = __uint_as_float(p1); return p5; # else /* __KERNEL_OPTIX__ */ if (!scene_intersect_valid(ray)) { - *num_hits = 0; + *num_recorded_hits = 0; + *throughput = 1.0f; return false; } @@ -422,7 +424,8 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals kg, kernel_embree_setup_ray(*ray, rtc_ray, visibility); rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray); - *num_hits = ctx.num_hits; + *num_recorded_hits = ctx.num_recorded_hits; + *throughput = ctx.throughput; return ctx.opaque_hit; } # endif /* __EMBREE__ */ @@ -431,21 +434,25 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals kg, if (kernel_data.bvh.have_motion) { # ifdef __HAIR__ if (kernel_data.bvh.have_curves) { - return bvh_intersect_shadow_all_hair_motion(kg, ray, state, visibility, max_hits, num_hits); + return bvh_intersect_shadow_all_hair_motion( + kg, ray, state, visibility, max_hits, num_recorded_hits, throughput); } # endif /* __HAIR__ */ - return bvh_intersect_shadow_all_motion(kg, ray, state, visibility, max_hits, num_hits); + return bvh_intersect_shadow_all_motion( + kg, ray, state, visibility, max_hits, num_recorded_hits, throughput); } # endif /* __OBJECT_MOTION__ */ # ifdef __HAIR__ if (kernel_data.bvh.have_curves) { - return bvh_intersect_shadow_all_hair(kg, ray, state, visibility, max_hits, num_hits); + return bvh_intersect_shadow_all_hair( + kg, ray, state, visibility, max_hits, num_recorded_hits, throughput); } # endif /* __HAIR__ */ - return bvh_intersect_shadow_all(kg, ray, state, visibility, max_hits, num_hits); + return bvh_intersect_shadow_all( + kg, ray, state, visibility, max_hits, num_recorded_hits, throughput); # endif /* __KERNEL_OPTIX__ */ } #endif /* __SHADOW_RECORD_ALL__ */ |