Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel/bvh/shadow_all.h')
-rw-r--r--intern/cycles/kernel/bvh/shadow_all.h73
1 files changed, 39 insertions, 34 deletions
diff --git a/intern/cycles/kernel/bvh/shadow_all.h b/intern/cycles/kernel/bvh/shadow_all.h
index a5769e91a28..2f58929c1e5 100644
--- a/intern/cycles/kernel/bvh/shadow_all.h
+++ b/intern/cycles/kernel/bvh/shadow_all.h
@@ -29,8 +29,8 @@ ccl_device_inline
IntegratorShadowState state,
const uint visibility,
const uint max_hits,
- ccl_private uint *num_recorded_hits,
- ccl_private float *throughput)
+ ccl_private uint *r_num_recorded_hits,
+ ccl_private float *r_throughput)
{
/* todo:
* - likely and unlikely for if() statements
@@ -60,15 +60,18 @@ ccl_device_inline
* recorded hits is exceeded and we no longer need to find hits beyond the max
* distance found. */
float t_max_world = ray->t;
- /* Equal to t_max_world when traversing top level BVH, transformed into local
- * space when entering instances. */
- float t_max_current = t_max_world;
+
+ /* Current maximum distance to the intersection.
+ * Is calculated as a ray length, transformed to an object space when entering
+ * instance node. */
+ float t_max_current = ray->t;
+
/* Conversion from world to local space for the current instance if any, 1.0
* otherwise. */
float t_world_to_instance = 1.0f;
- *num_recorded_hits = 0;
- *throughput = 1.0f;
+ *r_num_recorded_hits = 0;
+ *r_throughput = 1.0f;
/* traversal loop */
do {
@@ -237,10 +240,10 @@ ccl_device_inline
/* Always use baked shadow transparency for curves. */
if (isect.type & PRIMITIVE_CURVE) {
- *throughput *= intersection_curve_shadow_transparency(
+ *r_throughput *= intersection_curve_shadow_transparency(
kg, isect.object, isect.prim, isect.u);
- if (*throughput < CURVE_SHADOW_TRANSPARENCY_CUTOFF) {
+ if (*r_throughput < CURVE_SHADOW_TRANSPARENCY_CUTOFF) {
return true;
}
else {
@@ -249,37 +252,39 @@ ccl_device_inline
}
if (record_intersection) {
- /* Increase the number of hits, possibly beyond max_hits, we will
- * simply not record those and only keep the max_hits closest. */
- uint record_index = (*num_recorded_hits)++;
-
+ /* Test if we need to record this transparent intersection. */
const uint max_record_hits = min(max_hits, INTEGRATOR_SHADOW_ISECT_SIZE);
- if (record_index >= max_record_hits - 1) {
- /* 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_record_hits, record_index);
- float max_recorded_t = INTEGRATOR_STATE_ARRAY(state, shadow_isect, 0, t);
- int max_recorded_hit = 0;
-
- for (int i = 1; i < num_recorded_hits; i++) {
- const float isect_t = INTEGRATOR_STATE_ARRAY(state, shadow_isect, i, t);
- if (isect_t > max_recorded_t) {
- max_recorded_t = isect_t;
- max_recorded_hit = i;
+ if (*r_num_recorded_hits < max_record_hits || isect.t < t_max_world) {
+ /* If maximum number of hits was reached, replace the intersection with the
+ * highest distance. We want to find the N closest intersections. */
+ const uint num_recorded_hits = min(*r_num_recorded_hits, max_record_hits);
+ uint isect_index = num_recorded_hits;
+ if (num_recorded_hits + 1 >= max_record_hits) {
+ float max_t = INTEGRATOR_STATE_ARRAY(state, shadow_isect, 0, t);
+ uint max_recorded_hit = 0;
+
+ for (uint i = 1; i < num_recorded_hits; ++i) {
+ const float isect_t = INTEGRATOR_STATE_ARRAY(state, shadow_isect, i, t);
+ if (isect_t > max_t) {
+ max_recorded_hit = i;
+ max_t = isect_t;
+ }
+ }
+
+ if (num_recorded_hits >= max_record_hits) {
+ isect_index = max_recorded_hit;
}
- }
- if (record_index >= max_record_hits) {
- record_index = max_recorded_hit;
+ /* Limit the ray distance and stop counting hits beyond this. */
+ t_max_world = max(isect.t, max_t);
}
- /* Limit the ray distance and stop counting hits beyond this. */
- t_max_world = max(max_recorded_t, isect.t);
- t_max_current = t_max_world * t_world_to_instance;
+ integrator_state_write_shadow_isect(state, &isect, isect_index);
}
- integrator_state_write_shadow_isect(state, &isect, record_index);
+ /* Always increase the number of recorded hits, even beyond the maximum,
+ * so that we can detect this and trace another ray if needed. */
+ ++(*r_num_recorded_hits);
}
}
}
@@ -318,7 +323,7 @@ ccl_device_inline
#endif
/* Restore world space ray length. */
- t_max_current = t_max_world;
+ t_max_current = ray->t;
object = OBJECT_NONE;
t_world_to_instance = 1.0f;