[Bf-blender-cvs] [ef4f3201b73] cycles-x: Fix various issues in shadow handling of volumes
Brecht Van Lommel
noreply at git.blender.org
Mon Jun 28 17:15:23 CEST 2021
Commit: ef4f3201b731cc48ae330e84f91597ab0345196c
Author: Brecht Van Lommel
Date: Thu Jun 17 17:22:41 2021 +0200
Branches: cycles-x
https://developer.blender.org/rBef4f3201b731cc48ae330e84f91597ab0345196c
Fix various issues in shadow handling of volumes
Properly compute volume shading for all segments before, between and after
surface hits.
===================================================================
M intern/cycles/kernel/integrator/integrator_intersect_shadow.h
M intern/cycles/kernel/integrator/integrator_shade_shadow.h
M intern/cycles/kernel/integrator/integrator_shade_surface.h
M intern/cycles/kernel/integrator/integrator_state_util.h
M intern/cycles/kernel/integrator/integrator_subsurface.h
===================================================================
diff --git a/intern/cycles/kernel/integrator/integrator_intersect_shadow.h b/intern/cycles/kernel/integrator/integrator_intersect_shadow.h
index 06830d3d1c9..0582670a5da 100644
--- a/intern/cycles/kernel/integrator/integrator_intersect_shadow.h
+++ b/intern/cycles/kernel/integrator/integrator_intersect_shadow.h
@@ -97,6 +97,9 @@ ccl_device bool integrate_intersect_shadow_transparent(INTEGRATOR_STATE_ARGS,
INTEGRATOR_STATE_WRITE(shadow_path, num_hits) = num_hits;
}
+ else {
+ INTEGRATOR_STATE_WRITE(shadow_path, num_hits) = 0;
+ }
return opaque_hit;
}
diff --git a/intern/cycles/kernel/integrator/integrator_shade_shadow.h b/intern/cycles/kernel/integrator/integrator_shade_shadow.h
index 975ad750df8..d140a7461d4 100644
--- a/intern/cycles/kernel/integrator/integrator_shade_shadow.h
+++ b/intern/cycles/kernel/integrator/integrator_shade_shadow.h
@@ -59,7 +59,9 @@ ccl_device_inline float3 integrate_transparent_surface_shadow(INTEGRATOR_STATE_A
}
# ifdef __VOLUME__
-ccl_device_inline float3 integrate_transparent_volume_shadow(INTEGRATOR_STATE_ARGS, const int hit)
+ccl_device_inline float3 integrate_transparent_volume_shadow(INTEGRATOR_STATE_ARGS,
+ const int hit,
+ const int num_recorded_hits)
{
/* TODO: deduplicate with surface, or does it not matter for memory usage? */
ShaderDataTinyStorage shadow_sd_storage;
@@ -67,10 +69,14 @@ ccl_device_inline float3 integrate_transparent_volume_shadow(INTEGRATOR_STATE_AR
/* Setup shader data. */
Ray ray ccl_optional_struct_init;
- integrator_state_read_ray(INTEGRATOR_STATE_PASS, &ray);
+ integrator_state_read_shadow_ray(INTEGRATOR_STATE_PASS, &ray);
- Intersection isect ccl_optional_struct_init;
- integrator_state_read_shadow_isect(INTEGRATOR_STATE_PASS, &isect, hit);
+ /* Modify ray position and length to match current segment. */
+ const float start_t = (hit == 0) ? 0.0f : INTEGRATOR_STATE_ARRAY(shadow_isect, hit - 1, t);
+ const float end_t = (hit < num_recorded_hits) ? INTEGRATOR_STATE_ARRAY(shadow_isect, hit, t) :
+ ray.t;
+ ray.P += start_t * ray.D;
+ ray.t = end_t - start_t;
shader_setup_from_volume(kg, shadow_sd, &ray);
@@ -81,49 +87,55 @@ ccl_device_inline float3 integrate_transparent_volume_shadow(INTEGRATOR_STATE_AR
}
/* Integrate extinction over segment. */
- const float start_t = (hit == 0) ? 0.0f : INTEGRATOR_STATE_ARRAY(shadow_isect, hit - 1, t);
- const float end_t = isect.t;
- const float t = end_t - start_t;
-
- return exp3(-sigma_a * t);
+ return volume_color_transmittance(sigma_a, ray.t);
}
# endif
+ccl_device_inline bool shadow_intersections_has_remaining(const int num_hits)
+{
+ return num_hits >= INTEGRATOR_SHADOW_ISECT_SIZE;
+}
+
ccl_device_inline bool integrate_transparent_shadow(INTEGRATOR_STATE_ARGS, const int num_hits)
{
/* Accumulate shadow for transparent surfaces. */
const int num_recorded_hits = min(num_hits, INTEGRATOR_SHADOW_ISECT_SIZE);
- for (int hit = 0; hit < num_recorded_hits; hit++) {
-# ifdef __VOLUME__
+ for (int hit = 0; hit < num_recorded_hits + 1; hit++) {
/* Volume shaders. */
- if (INTEGRATOR_STATE_ARRAY(shadow_volume_stack, 0, shader) != SHADER_NONE) {
- const float3 shadow = integrate_transparent_volume_shadow(INTEGRATOR_STATE_PASS, hit);
+ if (hit < num_recorded_hits || !shadow_intersections_has_remaining(num_hits)) {
+# ifdef __VOLUME__
+ if (INTEGRATOR_STATE_ARRAY(shadow_volume_stack, 0, shader) != SHADER_NONE) {
+ const float3 shadow = integrate_transparent_volume_shadow(
+ INTEGRATOR_STATE_PASS, hit, num_recorded_hits);
+ const float3 throughput = INTEGRATOR_STATE(shadow_path, throughput) * shadow;
+ if (is_zero(throughput)) {
+ return true;
+ }
+
+ INTEGRATOR_STATE_WRITE(shadow_path, throughput) = throughput;
+ }
+# endif
+ }
+
+ /* Surface shaders. */
+ if (hit < num_recorded_hits) {
+ const float3 shadow = integrate_transparent_surface_shadow(INTEGRATOR_STATE_PASS, hit);
const float3 throughput = INTEGRATOR_STATE(shadow_path, throughput) * shadow;
if (is_zero(throughput)) {
return true;
}
INTEGRATOR_STATE_WRITE(shadow_path, throughput) = throughput;
+ INTEGRATOR_STATE_WRITE(shadow_path, transparent_bounce) += 1;
}
-# endif
-
- /* Surface shaders. */
- const float3 shadow = integrate_transparent_surface_shadow(INTEGRATOR_STATE_PASS, hit);
- const float3 throughput = INTEGRATOR_STATE(shadow_path, throughput) * shadow;
- if (is_zero(throughput)) {
- return true;
- }
-
- INTEGRATOR_STATE_WRITE(shadow_path, throughput) = throughput;
- INTEGRATOR_STATE_WRITE(shadow_path, transparent_bounce) += 1;
/* Note we do not need to check max_transparent_bounce here, the number
* of intersections is already limited and made opaque in the
* INTERSECT_SHADOW kernel. */
}
- if (num_hits >= INTEGRATOR_SHADOW_ISECT_SIZE) {
+ if (shadow_intersections_has_remaining(num_hits)) {
/* There are more hits that we could not recorded due to memory usage,
* adjust ray to intersect again from the last hit. */
const float last_hit_t = INTEGRATOR_STATE_ARRAY(shadow_isect, num_recorded_hits - 1, t);
@@ -151,7 +163,7 @@ ccl_device void integrator_shade_shadow(INTEGRATOR_STATE_ARGS,
}
#endif
- if (num_hits >= INTEGRATOR_SHADOW_ISECT_SIZE) {
+ if (shadow_intersections_has_remaining(num_hits)) {
/* More intersections to find, continue shadow ray. */
INTEGRATOR_SHADOW_PATH_NEXT(DEVICE_KERNEL_INTEGRATOR_SHADE_SHADOW,
DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW);
diff --git a/intern/cycles/kernel/integrator/integrator_shade_surface.h b/intern/cycles/kernel/integrator/integrator_shade_surface.h
index d305f20d361..f06813a7178 100644
--- a/intern/cycles/kernel/integrator/integrator_shade_surface.h
+++ b/intern/cycles/kernel/integrator/integrator_shade_surface.h
@@ -178,7 +178,7 @@ ccl_device_forceinline void integrate_surface_direct_light(INTEGRATOR_STATE_ARGS
integrator_state_copy_volume_stack_to_shadow(INTEGRATOR_STATE_PASS);
- /* Branch of shadow kernel. */
+ /* Branch off shadow kernel. */
INTEGRATOR_SHADOW_PATH_INIT(DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW);
}
#endif
diff --git a/intern/cycles/kernel/integrator/integrator_state_util.h b/intern/cycles/kernel/integrator/integrator_state_util.h
index ec811088b2c..2d38522e9b7 100644
--- a/intern/cycles/kernel/integrator/integrator_state_util.h
+++ b/intern/cycles/kernel/integrator/integrator_state_util.h
@@ -157,8 +157,8 @@ ccl_device_forceinline void integrator_state_copy_volume_stack_to_shadow(INTEGRA
ccl_device_forceinline VolumeStack
integrator_state_read_shadow_volume_stack(INTEGRATOR_STATE_CONST_ARGS, int i)
{
- VolumeStack entry = {INTEGRATOR_STATE_ARRAY(volume_stack, i, object),
- INTEGRATOR_STATE_ARRAY(volume_stack, i, shader)};
+ VolumeStack entry = {INTEGRATOR_STATE_ARRAY(shadow_volume_stack, i, object),
+ INTEGRATOR_STATE_ARRAY(shadow_volume_stack, i, shader)};
return entry;
}
diff --git a/intern/cycles/kernel/integrator/integrator_subsurface.h b/intern/cycles/kernel/integrator/integrator_subsurface.h
index a25e84519d5..fe7bb1f3000 100644
--- a/intern/cycles/kernel/integrator/integrator_subsurface.h
+++ b/intern/cycles/kernel/integrator/integrator_subsurface.h
@@ -124,7 +124,7 @@ ccl_device bool subsurface_bounce(INTEGRATOR_STATE_ARGS, ShaderData *sd, const S
INTEGRATOR_STATE_WRITE(subsurface, radius) = bssrdf->radius;
INTEGRATOR_STATE_WRITE(subsurface, roughness) = roughness;
- return true;
+ return LABEL_SUBSURFACE_SCATTER;
}
ccl_device void subsurface_shader_data_setup(INTEGRATOR_STATE_ARGS, ShaderData *sd)
More information about the Bf-blender-cvs
mailing list