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/integrator/intersect_closest.h')
-rw-r--r--intern/cycles/kernel/integrator/intersect_closest.h46
1 files changed, 41 insertions, 5 deletions
diff --git a/intern/cycles/kernel/integrator/intersect_closest.h b/intern/cycles/kernel/integrator/intersect_closest.h
index 9fcbf89c579..b8ce625c11b 100644
--- a/intern/cycles/kernel/integrator/intersect_closest.h
+++ b/intern/cycles/kernel/integrator/intersect_closest.h
@@ -123,7 +123,9 @@ ccl_device_forceinline void integrator_split_shadow_catcher(
/* Continue with shading shadow catcher surface. */
const int shader = intersection_get_shader(kg, isect);
const int flags = kernel_tex_fetch(__shaders, shader).flags;
- const bool use_raytrace_kernel = (flags & SD_HAS_RAYTRACE);
+ const bool use_caustics = kernel_data.integrator.use_caustics &&
+ (object_flags & SD_OBJECT_CAUSTICS);
+ const bool use_raytrace_kernel = (flags & SD_HAS_RAYTRACE) || use_caustics;
if (use_raytrace_kernel) {
INTEGRATOR_PATH_INIT_SORTED(DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE, shader);
@@ -145,7 +147,10 @@ ccl_device_forceinline void integrator_intersect_next_kernel_after_shadow_catche
const int shader = intersection_get_shader(kg, &isect);
const int flags = kernel_tex_fetch(__shaders, shader).flags;
- const bool use_raytrace_kernel = (flags & SD_HAS_RAYTRACE);
+ const int object_flags = intersection_get_object_flags(kg, &isect);
+ const bool use_caustics = kernel_data.integrator.use_caustics &&
+ (object_flags & SD_OBJECT_CAUSTICS);
+ const bool use_raytrace_kernel = (flags & SD_HAS_RAYTRACE) || use_caustics;
if (use_raytrace_kernel) {
INTEGRATOR_PATH_NEXT_SORTED(
@@ -214,7 +219,10 @@ ccl_device_forceinline void integrator_intersect_next_kernel(
const int flags = kernel_tex_fetch(__shaders, shader).flags;
if (!integrator_intersect_terminate(kg, state, flags)) {
- const bool use_raytrace_kernel = (flags & SD_HAS_RAYTRACE);
+ const int object_flags = intersection_get_object_flags(kg, isect);
+ const bool use_caustics = kernel_data.integrator.use_caustics &&
+ (object_flags & SD_OBJECT_CAUSTICS);
+ const bool use_raytrace_kernel = (flags & SD_HAS_RAYTRACE) || use_caustics;
if (use_raytrace_kernel) {
INTEGRATOR_PATH_NEXT_SORTED(
current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE, shader);
@@ -261,7 +269,10 @@ ccl_device_forceinline void integrator_intersect_next_kernel_after_volume(
/* Hit a surface, continue with surface kernel unless terminated. */
const int shader = intersection_get_shader(kg, isect);
const int flags = kernel_tex_fetch(__shaders, shader).flags;
- const bool use_raytrace_kernel = (flags & SD_HAS_RAYTRACE);
+ const int object_flags = intersection_get_object_flags(kg, isect);
+ const bool use_caustics = kernel_data.integrator.use_caustics &&
+ (object_flags & SD_OBJECT_CAUSTICS);
+ const bool use_raytrace_kernel = (flags & SD_HAS_RAYTRACE) || use_caustics;
if (use_raytrace_kernel) {
INTEGRATOR_PATH_NEXT_SORTED(
@@ -328,12 +339,37 @@ ccl_device void integrator_intersect_closest(KernelGlobals kg,
isect.prim = PRIM_NONE;
}
+ /* Setup mnee flag to signal last intersection with a caster */
+ const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
+
+#ifdef __MNEE__
+ /* Path culling logic for MNEE (removes fireflies at the cost of bias) */
+ if (kernel_data.integrator.use_caustics) {
+ /* The following firefly removal mechanism works by culling light connections when
+ * a ray comes from a caustic caster directly after bouncing off a different caustic
+ * receiver */
+ bool from_caustic_caster = false;
+ bool from_caustic_receiver = false;
+ if (!(path_flag & PATH_RAY_CAMERA) && last_isect_object != OBJECT_NONE) {
+ const int object_flags = kernel_tex_fetch(__object_flag, last_isect_object);
+ from_caustic_receiver = (object_flags & SD_OBJECT_CAUSTICS_RECEIVER);
+ from_caustic_caster = (object_flags & SD_OBJECT_CAUSTICS_CASTER);
+ }
+
+ bool has_receiver_ancestor = INTEGRATOR_STATE(state, path, mnee) & PATH_MNEE_RECEIVER_ANCESTOR;
+ INTEGRATOR_STATE_WRITE(state, path, mnee) &= ~PATH_MNEE_CULL_LIGHT_CONNECTION;
+ if (from_caustic_caster && has_receiver_ancestor)
+ INTEGRATOR_STATE_WRITE(state, path, mnee) |= PATH_MNEE_CULL_LIGHT_CONNECTION;
+ if (from_caustic_receiver)
+ INTEGRATOR_STATE_WRITE(state, path, mnee) |= PATH_MNEE_RECEIVER_ANCESTOR;
+ }
+#endif /* __MNEE__ */
+
/* Light intersection for MIS. */
if (kernel_data.integrator.use_lamp_mis) {
/* NOTE: if we make lights visible to camera rays, we'll need to initialize
* these in the path_state_init. */
const int last_type = INTEGRATOR_STATE(state, isect, type);
- const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
hit = lights_intersect(
kg, state, &ray, &isect, last_isect_prim, last_isect_object, last_type, path_flag) ||
hit;