[Bf-blender-cvs] [50dbc55b955] cycles-x: Cycles X: refactor path termination in preparation for volume bounces
Brecht Van Lommel
noreply at git.blender.org
Mon Jun 28 17:15:24 CEST 2021
Commit: 50dbc55b9554a3e81d0475935f109943e9e9031d
Author: Brecht Van Lommel
Date: Thu Jun 17 17:56:33 2021 +0200
Branches: cycles-x
https://developer.blender.org/rB50dbc55b9554a3e81d0475935f109943e9e9031d
Cycles X: refactor path termination in preparation for volume bounces
To support similar logic as transparent and emissive surfaces.
===================================================================
M intern/cycles/kernel/integrator/integrator_intersect_closest.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/kernel_path_state.h
M intern/cycles/kernel/kernel_types.h
===================================================================
diff --git a/intern/cycles/kernel/integrator/integrator_intersect_closest.h b/intern/cycles/kernel/integrator/integrator_intersect_closest.h
index a4538e8f771..39a0cad8c03 100644
--- a/intern/cycles/kernel/integrator/integrator_intersect_closest.h
+++ b/intern/cycles/kernel/integrator/integrator_intersect_closest.h
@@ -34,11 +34,17 @@ ccl_device_forceinline bool integrator_intersect_terminate(INTEGRATOR_STATE_ARGS
const int shader_flags)
{
- /* Optional AO bounce termination. */
+ /* Optional AO bounce termination.
+ * We continue evaluating emissive/transparent surfaces and volumes, similar
+ * to direct lighting. Only if we know there are none can we terminate the
+ * path immediately. */
if (path_state_ao_bounce(INTEGRATOR_STATE_PASS)) {
if (shader_flags & (SD_HAS_TRANSPARENT_SHADOW | SD_HAS_EMISSION)) {
INTEGRATOR_STATE_WRITE(path, flag) |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
}
+ else if (!integrator_state_volume_stack_is_empty(INTEGRATOR_STATE_PASS)) {
+ INTEGRATOR_STATE_WRITE(path, flag) |= PATH_RAY_TERMINATE_AFTER_VOLUME;
+ }
else {
return true;
}
@@ -52,15 +58,20 @@ ccl_device_forceinline bool integrator_intersect_terminate(INTEGRATOR_STATE_ARGS
* and evaluating the shader when not needed. Only for emission and transparent
* surfaces in front of emission do we need to evaluate the shader, since we
* perform MIS as part of indirect rays. */
- const float probability = path_state_continuation_probability(INTEGRATOR_STATE_PASS);
+ const int path_flag = INTEGRATOR_STATE(path, flag);
+ const float probability = path_state_continuation_probability(INTEGRATOR_STATE_PASS, path_flag);
if (probability != 1.0f) {
const float terminate = path_state_rng_1D(kg, &rng_state, PRNG_TERMINATE);
if (probability == 0.0f || terminate >= probability) {
- if (shader_flags & (SD_HAS_TRANSPARENT_SHADOW | SD_HAS_EMISSION)) {
- /* Mark path to be terminated right after shader evaluation. */
- INTEGRATOR_STATE_WRITE(path, flag) |= PATH_RAY_TERMINATE_IMMEDIATE;
+ if (shader_flags & SD_HAS_EMISSION) {
+ /* Mark path to be terminated right after shader evaluation on the surface. */
+ INTEGRATOR_STATE_WRITE(path, flag) |= PATH_RAY_TERMINATE_ON_NEXT_SURFACE;
+ }
+ else if (!integrator_state_volume_stack_is_empty(INTEGRATOR_STATE_PASS)) {
+ /* TODO: only do this for emissive volumes. */
+ INTEGRATOR_STATE_WRITE(path, flag) |= PATH_RAY_TERMINATE_IN_NEXT_VOLUME;
}
else {
return true;
@@ -130,11 +141,20 @@ ccl_device void integrator_intersect_closest(INTEGRATOR_STATE_ARGS)
integrator_state_write_isect(INTEGRATOR_STATE_PASS, &isect);
#ifdef __VOLUME__
- if (INTEGRATOR_STATE_ARRAY(volume_stack, 0, shader) != SHADER_NONE) {
- /* Continue with volume kernel if we are inside a volume, regardless
- * if we hit anything. */
- INTEGRATOR_PATH_NEXT(DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST,
- DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME);
+ if (!integrator_state_volume_stack_is_empty(INTEGRATOR_STATE_PASS)) {
+ const int shader = (hit) ? intersection_get_shader(kg, &isect) : SHADER_NONE;
+ const int flags = (hit) ? kernel_tex_fetch(__shaders, shader).flags : 0;
+
+ if (!integrator_intersect_terminate<DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST>(
+ INTEGRATOR_STATE_PASS, &isect, flags)) {
+ /* Continue with volume kernel if we are inside a volume, regardless
+ * if we hit anything. */
+ INTEGRATOR_PATH_NEXT(DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST,
+ DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME);
+ }
+ else {
+ INTEGRATOR_PATH_TERMINATE(DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST);
+ }
return;
}
#endif
diff --git a/intern/cycles/kernel/integrator/integrator_shade_shadow.h b/intern/cycles/kernel/integrator/integrator_shade_shadow.h
index d140a7461d4..4bc9d00817f 100644
--- a/intern/cycles/kernel/integrator/integrator_shade_shadow.h
+++ b/intern/cycles/kernel/integrator/integrator_shade_shadow.h
@@ -105,7 +105,7 @@ ccl_device_inline bool integrate_transparent_shadow(INTEGRATOR_STATE_ARGS, const
/* Volume shaders. */
if (hit < num_recorded_hits || !shadow_intersections_has_remaining(num_hits)) {
# ifdef __VOLUME__
- if (INTEGRATOR_STATE_ARRAY(shadow_volume_stack, 0, shader) != SHADER_NONE) {
+ if (!integrator_state_shadow_volume_stack_is_empty(INTEGRATOR_STATE_PASS)) {
const float3 shadow = integrate_transparent_volume_shadow(
INTEGRATOR_STATE_PASS, hit, num_recorded_hits);
const float3 throughput = INTEGRATOR_STATE(shadow_path, throughput) * shadow;
diff --git a/intern/cycles/kernel/integrator/integrator_shade_surface.h b/intern/cycles/kernel/integrator/integrator_shade_surface.h
index d07f6704b8c..6f04d261e11 100644
--- a/intern/cycles/kernel/integrator/integrator_shade_surface.h
+++ b/intern/cycles/kernel/integrator/integrator_shade_surface.h
@@ -297,14 +297,17 @@ ccl_device bool integrate_surface(INTEGRATOR_STATE_ARGS,
if (!(sd.flag & SD_HAS_ONLY_VOLUME)) {
#endif
- const int path_flag = INTEGRATOR_STATE(path, flag);
+ {
+ const int path_flag = INTEGRATOR_STATE(path, flag);
#ifdef __SUBSURFACE__
- /* Can skip shader evaluation for BSSRDF exit point without bump mapping. */
- if (!(path_flag & PATH_RAY_SUBSURFACE) || ((sd.flag & SD_HAS_BSSRDF_BUMP)))
+ /* Can skip shader evaluation for BSSRDF exit point without bump mapping. */
+ if (!(path_flag & PATH_RAY_SUBSURFACE) || ((sd.flag & SD_HAS_BSSRDF_BUMP)))
#endif
- {
- /* Evaluate shader. */
- shader_eval_surface<node_feature_mask>(INTEGRATOR_STATE_PASS, &sd, render_buffer, path_flag);
+ {
+ /* Evaluate shader. */
+ shader_eval_surface<node_feature_mask>(
+ INTEGRATOR_STATE_PASS, &sd, render_buffer, path_flag);
+ }
}
#ifdef __SUBSURFACE__
@@ -344,7 +347,11 @@ ccl_device bool integrate_surface(INTEGRATOR_STATE_ARGS,
/* Perform path termination. Most paths have already been terminated in
* the intersect_closest kernel, this is just for emission and for dividing
* throughput by the probability at the right moment. */
- const float probability = path_state_continuation_probability(INTEGRATOR_STATE_PASS);
+ const int path_flag = INTEGRATOR_STATE(path, flag);
+ const float probability = (path_flag & PATH_RAY_TERMINATE_ON_NEXT_SURFACE) ?
+ 0.0f :
+ path_state_continuation_probability(INTEGRATOR_STATE_PASS,
+ path_flag);
if (probability == 0.0f) {
return false;
}
diff --git a/intern/cycles/kernel/integrator/integrator_state_util.h b/intern/cycles/kernel/integrator/integrator_state_util.h
index 2d38522e9b7..a15c187b127 100644
--- a/intern/cycles/kernel/integrator/integrator_state_util.h
+++ b/intern/cycles/kernel/integrator/integrator_state_util.h
@@ -113,6 +113,11 @@ ccl_device_forceinline void integrator_state_write_volume_stack(INTEGRATOR_STATE
INTEGRATOR_STATE_ARRAY_WRITE(volume_stack, i, shader) = entry.shader;
}
+ccl_device_forceinline bool integrator_state_volume_stack_is_empty(INTEGRATOR_STATE_CONST_ARGS)
+{
+ return INTEGRATOR_STATE_ARRAY(volume_stack, 0, shader) == SHADER_NONE;
+}
+
/* Shadow Intersection */
ccl_device_forceinline void integrator_state_write_shadow_isect(
@@ -162,6 +167,12 @@ integrator_state_read_shadow_volume_stack(INTEGRATOR_STATE_CONST_ARGS, int i)
return entry;
}
+ccl_device_forceinline bool integrator_state_shadow_volume_stack_is_empty(
+ INTEGRATOR_STATE_CONST_ARGS)
+{
+ return INTEGRATOR_STATE_ARRAY(shadow_volume_stack, 0, shader) == SHADER_NONE;
+}
+
ccl_device_forceinline void integrator_state_write_shadow_volume_stack(INTEGRATOR_STATE_ARGS,
int i,
VolumeStack entry)
diff --git a/intern/cycles/kernel/kernel_path_state.h b/intern/cycles/kernel/kernel_path_state.h
index c2a156c9b77..f736285dfa1 100644
--- a/intern/cycles/kernel/kernel_path_state.h
+++ b/intern/cycles/kernel/kernel_path_state.h
@@ -105,7 +105,7 @@ ccl_device_inline void path_state_next(INTEGRATOR_STATE_ARGS, int label)
flag |= PATH_RAY_TRANSPARENT;
if (transparent_bounce >= kernel_data.integrator.transparent_max_bounce) {
- flag |= PATH_RAY_TERMINATE_IMMEDIATE;
+ flag |= PATH_RAY_TERMINATE_ON_NEXT_SURFACE;
}
if (!kernel_data.integrator.transparent_shadows)
@@ -245,15 +245,10 @@ ccl_device_inline uint path_state_ray_visibility(INTEGRATOR_STATE_CONST_ARGS)
return visibility;
}
-ccl_device_inline float path_state_continuation_probability(INTEGRATOR_STATE_CONST_ARGS)
+ccl_device_inline float path_state_continuation_probability(INTEGRATOR_STATE_CONST_ARGS,
+ const uint32_t path_flag)
{
- const uint32_t flag = INTEGRATOR_STATE(path, flag);
-
- if (flag & PATH_RAY_TERMINATE_IMMEDIATE) {
- /* Ray is to be terminated immediately. */
- return 0.0f;
- }
- else if (flag & PATH_RAY_TRANSPARENT) {
+ if (path_flag & PATH_RAY_TRANSPARENT) {
const uint32_t transparent_bounce = INTEGRATOR_STATE(path, transparent_bounce);
/* Do at least specified number of bounces without RR. */
if (transparent_bounce <= kernel_data.integrator.transparent_min_bounce) {
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index f8a470291d4..38b0f830f79 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -263,44 +263,49 @@ enum PathRayFlag {
PATH_RAY_TRANSPARENT_BACKGROUND = (1 << 14),
/* Terminate ray immediately at next bounce. */
- PATH_RAY_TERMINATE_IMMEDIATE = (1 << 15),
+ PATH_RAY_TERMINATE_ON_NEXT_SURFACE = (1 << 15),
+ PATH_RAY_TERMINATE_IN_NEXT_VOLUME = (1 << 16),
/* Ray is to be terminated, but continue with transparent bounces and
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list