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/bvh/bvh_embree.cpp')
-rw-r--r--intern/cycles/bvh/bvh_embree.cpp45
1 files changed, 31 insertions, 14 deletions
diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp
index 343d62dedf4..cd19e009bf3 100644
--- a/intern/cycles/bvh/bvh_embree.cpp
+++ b/intern/cycles/bvh/bvh_embree.cpp
@@ -80,31 +80,49 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
Intersection current_isect;
kernel_embree_convert_hit(kg, ray, hit, &current_isect);
- /* If no transparent shadows, all light is blocked. */
+ /* If no transparent shadows or max number of hits exceeded, all light is blocked. */
const int flags = intersection_get_shader_flags(kg, current_isect.prim, current_isect.type);
- if (!(flags & (SD_HAS_TRANSPARENT_SHADOW)) || ctx->max_hits == 0) {
+ if (!(flags & (SD_HAS_TRANSPARENT_SHADOW)) || ctx->num_hits >= ctx->max_hits) {
ctx->opaque_hit = true;
return;
}
+ ++ctx->num_hits;
+
+ /* Always use baked shadow transparency for curves. */
+ if (current_isect.type & PRIMITIVE_ALL_CURVE) {
+ ctx->throughput *= intersection_curve_shadow_transparency(
+ kg, current_isect.object, current_isect.prim, current_isect.u);
+
+ if (ctx->throughput < CURVE_SHADOW_TRANSPARENCY_CUTOFF) {
+ ctx->opaque_hit = true;
+ return;
+ }
+ else {
+ *args->valid = 0;
+ return;
+ }
+ }
+
/* Test if we need to record this transparent intersection. */
- if (ctx->num_hits < ctx->max_hits || ray->tfar < ctx->max_t) {
+ const uint max_record_hits = min(ctx->max_hits, INTEGRATOR_SHADOW_ISECT_SIZE);
+ if (ctx->num_recorded_hits < max_record_hits || ray->tfar < ctx->max_t) {
/* If maximum number of hits was reached, replace the intersection with the
* highest distance. We want to find the N closest intersections. */
- const int num_recorded_hits = min(ctx->num_hits, ctx->max_hits);
- int isect_index = num_recorded_hits;
- if (num_recorded_hits + 1 >= ctx->max_hits) {
+ const uint num_recorded_hits = min(ctx->num_recorded_hits, max_record_hits);
+ uint isect_index = num_recorded_hits;
+ if (num_recorded_hits + 1 >= max_record_hits) {
float max_t = ctx->isect_s[0].t;
- int max_recorded_hit = 0;
+ uint max_recorded_hit = 0;
- for (int i = 1; i < num_recorded_hits; ++i) {
+ for (uint i = 1; i < num_recorded_hits; ++i) {
if (ctx->isect_s[i].t > max_t) {
max_recorded_hit = i;
max_t = ctx->isect_s[i].t;
}
}
- if (num_recorded_hits >= ctx->max_hits) {
+ if (num_recorded_hits >= max_record_hits) {
isect_index = max_recorded_hit;
}
@@ -118,10 +136,9 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
ctx->isect_s[isect_index] = current_isect;
}
- /* Always increase the number of hits, even beyond ray.max_hits so that
- * the caller can detect this as and consider it opaque, or trace another
- * ray. */
- ++ctx->num_hits;
+ /* Always increase the number of recorded hits, even beyond the maximum,
+ * so that we can detect this and trace another ray if needed. */
+ ++ctx->num_recorded_hits;
/* This tells Embree to continue tracing. */
*args->valid = 0;
@@ -160,7 +177,7 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
if (ctx->lcg_state) {
/* See triangle_intersect_subsurface() for the native equivalent. */
- for (int i = min(ctx->max_hits, local_isect->num_hits) - 1; i >= 0; --i) {
+ for (int i = min((int)ctx->max_hits, local_isect->num_hits) - 1; i >= 0; --i) {
if (local_isect->hits[i].t == ray->tfar) {
/* This tells Embree to continue tracing. */
*args->valid = 0;