[Bf-blender-cvs] [14a3ceae0a4] cycles-x: Cycles X: restore support for rendering SSS inside volumes
Brecht Van Lommel
noreply at git.blender.org
Fri Jul 23 20:19:34 CEST 2021
Commit: 14a3ceae0a47bb3ec8dc71432db3818775a284d5
Author: Brecht Van Lommel
Date: Fri Jul 23 19:34:26 2021 +0200
Branches: cycles-x
https://developer.blender.org/rB14a3ceae0a47bb3ec8dc71432db3818775a284d5
Cycles X: restore support for rendering SSS inside volumes
I found no GPU rendering performance difference in the two benchmark scenes
with SSS: junkshop and monster. In scenes with overlap between SSS and volumes
there will of course be a slowdown.
There is test reports/T39823 for this, which now seems to work correctly.
Differential Revision: https://developer.blender.org/D12017
===================================================================
M intern/cycles/kernel/integrator/integrator_intersect_subsurface.h
M intern/cycles/kernel/integrator/integrator_intersect_volume_stack.h
M intern/cycles/kernel/integrator/integrator_subsurface.h
===================================================================
diff --git a/intern/cycles/kernel/integrator/integrator_intersect_subsurface.h b/intern/cycles/kernel/integrator/integrator_intersect_subsurface.h
index b8bafd8d1bc..93831c67cf4 100644
--- a/intern/cycles/kernel/integrator/integrator_intersect_subsurface.h
+++ b/intern/cycles/kernel/integrator/integrator_intersect_subsurface.h
@@ -28,25 +28,6 @@ ccl_device void integrator_intersect_subsurface(INTEGRATOR_STATE_ARGS)
}
#endif
- /* TODO: update volume stack. Instead of a special for_subsurface, we could
- * just re-init the volume stack completely, sharing the same kernel as for
- * cameras. */
-#if 0
-# ifdef __VOLUME__
- bool need_update_volume_stack = kernel_data.integrator.use_volumes &&
- sd->object_flag & SD_OBJECT_INTERSECTS_VOLUME;
-
- if (need_update_volume_stack) {
- Ray volume_ray = *ray;
- /* Setup ray from previous surface point to the new one. */
- volume_ray.D = normalize_len(hit_ray->P - volume_ray.P, &volume_ray.t);
-
- kernel_volume_stack_update_for_subsurface(
- kg, emission_sd, &volume_ray, hit_state->volume_stack);
- }
-# endif /* __VOLUME__ */
-#endif
-
INTEGRATOR_PATH_TERMINATE(DEVICE_KERNEL_INTEGRATOR_INTERSECT_SUBSURFACE);
}
diff --git a/intern/cycles/kernel/integrator/integrator_intersect_volume_stack.h b/intern/cycles/kernel/integrator/integrator_intersect_volume_stack.h
index daec67dc358..b7cd3f27531 100644
--- a/intern/cycles/kernel/integrator/integrator_intersect_volume_stack.h
+++ b/intern/cycles/kernel/integrator/integrator_intersect_volume_stack.h
@@ -23,6 +23,51 @@
CCL_NAMESPACE_BEGIN
+ccl_device void integrator_volume_stack_update_for_subsurface(INTEGRATOR_STATE_ARGS,
+ const float3 from_P,
+ const float3 to_P)
+{
+ ShaderDataTinyStorage stack_sd_storage;
+ ShaderData *stack_sd = AS_SHADER_DATA(&stack_sd_storage);
+
+ kernel_assert(kernel_data.integrator.use_volumes);
+
+ Ray volume_ray ccl_optional_struct_init;
+ volume_ray.P = from_P;
+ volume_ray.D = normalize_len(to_P - from_P, &volume_ray.t);
+
+#ifdef __VOLUME_RECORD_ALL__
+ Intersection hits[2 * VOLUME_STACK_SIZE + 1];
+ uint num_hits = scene_intersect_volume_all(
+ kg, &volume_ray, hits, 2 * VOLUME_STACK_SIZE, PATH_RAY_ALL_VISIBILITY);
+ if (num_hits > 0) {
+ Intersection *isect = hits;
+
+ qsort(hits, num_hits, sizeof(Intersection), intersections_compare);
+
+ for (uint hit = 0; hit < num_hits; ++hit, ++isect) {
+ shader_setup_from_ray(kg, stack_sd, &volume_ray, isect);
+ volume_stack_enter_exit(INTEGRATOR_STATE_PASS, stack_sd);
+ }
+ }
+#else
+ Intersection isect;
+ int step = 0;
+ while (step < 2 * VOLUME_STACK_SIZE &&
+ scene_intersect_volume(kg, &volume_ray, &isect, PATH_RAY_ALL_VISIBILITY)) {
+ shader_setup_from_ray(kg, stack_sd, &volume_ray, &isect);
+ volume_stack_enter_exit(INTEGRATOR_STATE_PASS, stack_sd);
+
+ /* Move ray forward. */
+ volume_ray.P = ray_offset(stack_sd->P, -stack_sd->Ng);
+ if (volume_ray.t != FLT_MAX) {
+ volume_ray.D = normalize_len(to_P - volume_ray.P, &volume_ray.t);
+ }
+ ++step;
+ }
+#endif
+}
+
ccl_device void integrator_intersect_volume_stack(INTEGRATOR_STATE_ARGS)
{
ShaderDataTinyStorage stack_sd_storage;
diff --git a/intern/cycles/kernel/integrator/integrator_subsurface.h b/intern/cycles/kernel/integrator/integrator_subsurface.h
index 5522b6b4028..8c438223b66 100644
--- a/intern/cycles/kernel/integrator/integrator_subsurface.h
+++ b/intern/cycles/kernel/integrator/integrator_subsurface.h
@@ -28,6 +28,8 @@
#include "kernel/closure/bssrdf.h"
#include "kernel/closure/volume.h"
+#include "kernel/integrator/integrator_intersect_volume_stack.h"
+
CCL_NAMESPACE_BEGIN
#ifdef __SUBSURFACE__
@@ -301,9 +303,11 @@ ccl_device_inline bool subsurface_random_walk(INTEGRATOR_STATE_ARGS)
Transform ob_tfm = object_fetch_transform_motion_test(kg, object, time, &ob_itfm);
# endif
+ const float3 ray_start_P = ray_offset(P, -Ng);
+
/* Setup ray. */
Ray ray ccl_optional_struct_init;
- ray.P = ray_offset(P, -Ng);
+ ray.P = ray_start_P;
ray.D = D;
ray.t = FLT_MAX;
ray.time = time;
@@ -525,6 +529,18 @@ ccl_device_inline bool subsurface_random_walk(INTEGRATOR_STATE_ARGS)
return false;
}
+# ifdef __VOLUME__
+ /* Update volume stack if needed. */
+ if (kernel_data.integrator.use_volumes) {
+ const int object = intersection_get_object(kg, &ss_isect.hits[0]);
+ const int object_flag = kernel_tex_fetch(__object_flag, object);
+
+ if (object_flag & SD_OBJECT_INTERSECTS_VOLUME) {
+ integrator_volume_stack_update_for_subsurface(INTEGRATOR_STATE_PASS, ray_start_P, ray.P);
+ }
+ }
+# endif /* __VOLUME__ */
+
/* Pretend ray is coming from the outside towards the exit point. This ensures
* correct front/back facing normals.
* TODO: find a more elegant solution? */
More information about the Bf-blender-cvs
mailing list