Code refactor: rename subsurface to local traversal, for reuse.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Mon, 30 Oct 2017 19:25:08 +0000 (20:25 +0100)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Tue, 7 Nov 2017 21:35:12 +0000 (22:35 +0100)
17 files changed:
intern/cycles/device/device.h
intern/cycles/kernel/CMakeLists.txt
intern/cycles/kernel/bvh/bvh.h
intern/cycles/kernel/bvh/bvh_local.h [moved from intern/cycles/kernel/bvh/bvh_subsurface.h with 76% similarity]
intern/cycles/kernel/bvh/qbvh_local.h [moved from intern/cycles/kernel/bvh/qbvh_subsurface.h with 82% similarity]
intern/cycles/kernel/geom/geom_motion_triangle_intersect.h
intern/cycles/kernel/geom/geom_motion_triangle_shader.h
intern/cycles/kernel/geom/geom_triangle_intersect.h
intern/cycles/kernel/kernel_path_branched.h
intern/cycles/kernel/kernel_path_subsurface.h
intern/cycles/kernel/kernel_shader.h
intern/cycles/kernel/kernel_subsurface.h
intern/cycles/kernel/kernel_types.h
intern/cycles/kernel/split/kernel_split_data_types.h
intern/cycles/kernel/split/kernel_subsurface_scatter.h
intern/cycles/render/graph.h
intern/cycles/render/shader.cpp

index 4f78b9e82a4903ae5d59a7abd6caf2f9f547ac45..6bf3bbe6c257d17f08cad9e9632ae1e5d2c93cb6 100644 (file)
@@ -139,6 +139,9 @@ public:
        /* Denoising features. */
        bool use_denoising;
 
+       /* Use raytracing in shaders. */
+       bool use_shader_raytrace;
+
        DeviceRequestedFeatures()
        {
                /* TODO(sergey): Find more meaningful defaults. */
@@ -158,6 +161,7 @@ public:
                use_shadow_tricks = false;
                use_principled = false;
                use_denoising = false;
+               use_shader_raytrace = false;
        }
 
        bool modified(const DeviceRequestedFeatures& requested_features)
@@ -177,7 +181,8 @@ public:
                         use_transparent == requested_features.use_transparent &&
                         use_shadow_tricks == requested_features.use_shadow_tricks &&
                         use_principled == requested_features.use_principled &&
-                        use_denoising == requested_features.use_denoising);
+                        use_denoising == requested_features.use_denoising &&
+                        use_shader_raytrace == requested_features.use_shader_raytrace);
        }
 
        /* Convert the requested features structure to a build options,
@@ -230,6 +235,9 @@ public:
                if(!use_denoising) {
                        build_options += " -D__NO_DENOISING__";
                }
+               if(!use_shader_raytrace) {
+                       build_options += " -D__NO_SHADER_RAYTRACE__";
+               }
                return build_options;
        }
 };
index bd51bc4d3718d4dde5a35678facfb4b9f849fa4f..9d52cef1f2cee2a3381d3c7948923a3b51fe5568 100644 (file)
@@ -65,14 +65,14 @@ set(SRC_BVH_HEADERS
        bvh/bvh.h
        bvh/bvh_nodes.h
        bvh/bvh_shadow_all.h
-       bvh/bvh_subsurface.h
+       bvh/bvh_local.h
        bvh/bvh_traversal.h
        bvh/bvh_types.h
        bvh/bvh_volume.h
        bvh/bvh_volume_all.h
        bvh/qbvh_nodes.h
        bvh/qbvh_shadow_all.h
-       bvh/qbvh_subsurface.h
+       bvh/qbvh_local.h
        bvh/qbvh_traversal.h
        bvh/qbvh_volume.h
        bvh/qbvh_volume_all.h
index cf0c8542d69fdce55f44f0d0840c4048c50113d2..d3e0b25a20063958611472211ee4f5d170342df6 100644 (file)
@@ -68,17 +68,17 @@ CCL_NAMESPACE_BEGIN
 
 /* Subsurface scattering BVH traversal */
 
-#if defined(__SUBSURFACE__)
-#  define BVH_FUNCTION_NAME bvh_intersect_subsurface
+#if defined(__BVH_LOCAL__)
+#  define BVH_FUNCTION_NAME bvh_intersect_local
 #  define BVH_FUNCTION_FEATURES BVH_HAIR
-#  include "kernel/bvh/bvh_subsurface.h"
+#  include "kernel/bvh/bvh_local.h"
 
 #  if defined(__OBJECT_MOTION__)
-#    define BVH_FUNCTION_NAME bvh_intersect_subsurface_motion
+#    define BVH_FUNCTION_NAME bvh_intersect_local_motion
 #    define BVH_FUNCTION_FEATURES BVH_MOTION|BVH_HAIR
-#    include "kernel/bvh/bvh_subsurface.h"
+#    include "kernel/bvh/bvh_local.h"
 #  endif
-#endif  /* __SUBSURFACE__ */
+#endif  /* __BVH_LOCAL__ */
 
 /* Volume BVH traversal */
 
@@ -201,31 +201,31 @@ ccl_device_intersect bool scene_intersect(KernelGlobals *kg,
 #endif /* __KERNEL_CPU__ */
 }
 
-#ifdef __SUBSURFACE__
+#ifdef __BVH_LOCAL__
 /* Note: ray is passed by value to work around a possible CUDA compiler bug. */
-ccl_device_intersect void scene_intersect_subsurface(KernelGlobals *kg,
-                                                     const Ray ray,
-                                                     SubsurfaceIntersection *ss_isect,
-                                                     int subsurface_object,
-                                                     uint *lcg_state,
-                                                     int max_hits)
+ccl_device_intersect void scene_intersect_local(KernelGlobals *kg,
+                                                const Ray ray,
+                                                LocalIntersection *local_isect,
+                                                int local_object,
+                                                uint *lcg_state,
+                                                int max_hits)
 {
 #ifdef __OBJECT_MOTION__
        if(kernel_data.bvh.have_motion) {
-               return bvh_intersect_subsurface_motion(kg,
-                                                      &ray,
-                                                      ss_isect,
-                                                      subsurface_object,
-                                                      lcg_state,
-                                                      max_hits);
+               return bvh_intersect_local_motion(kg,
+                                                 &ray,
+                                                 local_isect,
+                                                 local_object,
+                                                 lcg_state,
+                                                 max_hits);
        }
 #endif /* __OBJECT_MOTION__ */
-       return bvh_intersect_subsurface(kg,
-                                       &ray,
-                                       ss_isect,
-                                       subsurface_object,
-                                       lcg_state,
-                                       max_hits);
+       return bvh_intersect_local(kg,
+                                   &ray,
+                                   local_isect,
+                                   local_object,
+                                   lcg_state,
+                                   max_hits);
 }
 #endif
 
similarity index 76%
rename from intern/cycles/kernel/bvh/bvh_subsurface.h
rename to intern/cycles/kernel/bvh/bvh_local.h
index bda7e34907a00e0bb2ba79955a852cbda9d619a7..12d14428d6df06b3c134143d3159c5ce9a9965c6 100644 (file)
@@ -18,7 +18,7 @@
  */
 
 #ifdef __QBVH__
-#  include "kernel/bvh/qbvh_subsurface.h"
+#  include "kernel/bvh/qbvh_local.h"
 #endif
 
 #if BVH_FEATURE(BVH_HAIR)
 #  define NODE_INTERSECT bvh_aligned_node_intersect
 #endif
 
-/* This is a template BVH traversal function for subsurface scattering, where
- * various features can be enabled/disabled. This way we can compile optimized
- * versions for each case without new features slowing things down.
+/* This is a template BVH traversal function for finding local intersections
+ * around the shading point, for subsurface scattering and bevel. We disable
+ * various features for performance, and for instanced objects avoid traversing
+ * other parts of the scene.
  *
  * BVH_MOTION: motion blur rendering
  *
@@ -42,8 +43,8 @@ ccl_device_inline
 #endif
 void BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
                                  const Ray *ray,
-                                 SubsurfaceIntersection *ss_isect,
-                                 int subsurface_object,
+                                 LocalIntersection *local_isect,
+                                 int local_object,
                                  uint *lcg_state,
                                  int max_hits)
 {
@@ -60,7 +61,7 @@ void BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
 
        /* traversal variables in registers */
        int stack_ptr = 0;
-       int node_addr = kernel_tex_fetch(__object_node, subsurface_object);
+       int node_addr = kernel_tex_fetch(__object_node, local_object);
 
        /* ray parameters in registers */
        float3 P = ray->P;
@@ -69,14 +70,14 @@ void BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
        int object = OBJECT_NONE;
        float isect_t = ray->t;
 
-       ss_isect->num_hits = 0;
+       local_isect->num_hits = 0;
 
-       const int object_flag = kernel_tex_fetch(__object_flag, subsurface_object);
+       const int object_flag = kernel_tex_fetch(__object_flag, local_object);
        if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
 #if BVH_FEATURE(BVH_MOTION)
                Transform ob_itfm;
                isect_t = bvh_instance_motion_push(kg,
-                                                  subsurface_object,
+                                                  local_object,
                                                   ray,
                                                   &P,
                                                   &dir,
@@ -84,9 +85,9 @@ void BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
                                                   isect_t,
                                                   &ob_itfm);
 #else
-               isect_t = bvh_instance_push(kg, subsurface_object, ray, &P, &dir, &idir, isect_t);
+               isect_t = bvh_instance_push(kg, local_object, ray, &P, &dir, &idir, isect_t);
 #endif
-               object = subsurface_object;
+               object = local_object;
        }
 
 #if defined(__KERNEL_SSE2__)
@@ -193,15 +194,16 @@ void BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
                                                /* intersect ray against primitive */
                                                for(; prim_addr < prim_addr2; prim_addr++) {
                                                        kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
-                                                       triangle_intersect_subsurface(kg,
-                                                                                     ss_isect,
-                                                                                     P,
-                                                                                     dir,
-                                                                                     object,
-                                                                                     prim_addr,
-                                                                                     isect_t,
-                                                                                     lcg_state,
-                                                                                     max_hits);
+                                                       triangle_intersect_local(kg,
+                                                                                local_isect,
+                                                                                P,
+                                                                                dir,
+                                                                                object,
+                                                                                local_object,
+                                                                                prim_addr,
+                                                                                isect_t,
+                                                                                lcg_state,
+                                                                                max_hits);
                                                }
                                                break;
                                        }
@@ -210,16 +212,17 @@ void BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
                                                /* intersect ray against primitive */
                                                for(; prim_addr < prim_addr2; prim_addr++) {
                                                        kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
-                                                       motion_triangle_intersect_subsurface(kg,
-                                                                                            ss_isect,
-                                                                                            P,
-                                                                                            dir,
-                                                                                            ray->time,
-                                                                                            object,
-                                                                                            prim_addr,
-                                                                                            isect_t,
-                                                                                            lcg_state,
-                                                                                            max_hits);
+                                                       motion_triangle_intersect_local(kg,
+                                                                                       local_isect,
+                                                                                       P,
+                                                                                       dir,
+                                                                                       ray->time,
+                                                                                       object,
+                                                                                       local_object,
+                                                                                       prim_addr,
+                                                                                       isect_t,
+                                                                                       lcg_state,
+                                                                                       max_hits);
                                                }
                                                break;
                                        }
@@ -235,8 +238,8 @@ void BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
 
 ccl_device_inline void BVH_FUNCTION_NAME(KernelGlobals *kg,
                                          const Ray *ray,
-                                         SubsurfaceIntersection *ss_isect,
-                                         int subsurface_object,
+                                         LocalIntersection *local_isect,
+                                         int local_object,
                                          uint *lcg_state,
                                          int max_hits)
 {
@@ -244,8 +247,8 @@ ccl_device_inline void BVH_FUNCTION_NAME(KernelGlobals *kg,
        if(kernel_data.bvh.use_qbvh) {
                return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
                                                    ray,
-                                                   ss_isect,
-                                                   subsurface_object,
+                                                   local_isect,
+                                                   local_object,
                                                    lcg_state,
                                                    max_hits);
        }
@@ -255,8 +258,8 @@ ccl_device_inline void BVH_FUNCTION_NAME(KernelGlobals *kg,
                kernel_assert(kernel_data.bvh.use_qbvh == false);
                return BVH_FUNCTION_FULL_NAME(BVH)(kg,
                                                   ray,
-                                                  ss_isect,
-                                                  subsurface_object,
+                                                  local_isect,
+                                                  local_object,
                                                   lcg_state,
                                                   max_hits);
        }
similarity index 82%
rename from intern/cycles/kernel/bvh/qbvh_subsurface.h
rename to intern/cycles/kernel/bvh/qbvh_local.h
index be7658d11d7f9928b3137edcc58b9311e406a7e7..2386fa1a1e82311743bb679885a3cb015285bbf3 100644 (file)
  * limitations under the License.
  */
 
-/* This is a template BVH traversal function for subsurface scattering, where
- * various features can be enabled/disabled. This way we can compile optimized
- * versions for each case without new features slowing things down.
+/* This is a template BVH traversal function for finding local intersections
+ * around the shading point, for subsurface scattering and bevel. We disable
+ * various features for performance, and for instanced objects avoid traversing
+ * other parts of the scene.
  *
  * BVH_MOTION: motion blur rendering
  *
@@ -30,8 +31,8 @@
 
 ccl_device void BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                                              const Ray *ray,
-                                             SubsurfaceIntersection *ss_isect,
-                                             int subsurface_object,
+                                             LocalIntersection *local_isect,
+                                             int local_object,
                                              uint *lcg_state,
                                              int max_hits)
 {
@@ -49,7 +50,7 @@ ccl_device void BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
 
        /* Traversal variables in registers. */
        int stack_ptr = 0;
-       int node_addr = kernel_tex_fetch(__object_node, subsurface_object);
+       int node_addr = kernel_tex_fetch(__object_node, local_object);
 
        /* Ray parameters in registers. */
        float3 P = ray->P;
@@ -58,14 +59,14 @@ ccl_device void BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
        int object = OBJECT_NONE;
        float isect_t = ray->t;
 
-       ss_isect->num_hits = 0;
+       local_isect->num_hits = 0;
 
-       const int object_flag = kernel_tex_fetch(__object_flag, subsurface_object);
+       const int object_flag = kernel_tex_fetch(__object_flag, local_object);
        if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
 #if BVH_FEATURE(BVH_MOTION)
                Transform ob_itfm;
                isect_t = bvh_instance_motion_push(kg,
-                                                  subsurface_object,
+                                                  local_object,
                                                   ray,
                                                   &P,
                                                   &dir,
@@ -73,9 +74,9 @@ ccl_device void BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                                                   isect_t,
                                                   &ob_itfm);
 #else
-               isect_t = bvh_instance_push(kg, subsurface_object, ray, &P, &dir, &idir, isect_t);
+               isect_t = bvh_instance_push(kg, local_object, ray, &P, &dir, &idir, isect_t);
 #endif
-               object = subsurface_object;
+               object = local_object;
        }
 
 #ifndef __KERNEL_SSE41__
@@ -249,15 +250,16 @@ ccl_device void BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                                                /* Intersect ray against primitive, */
                                                for(; prim_addr < prim_addr2; prim_addr++) {
                                                        kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
-                                                       triangle_intersect_subsurface(kg,
-                                                                                     ss_isect,
-                                                                                     P,
-                                                                                     dir,
-                                                                                     object,
-                                                                                     prim_addr,
-                                                                                     isect_t,
-                                                                                     lcg_state,
-                                                                                     max_hits);
+                                                       triangle_intersect_local(kg,
+                                                                                local_isect,
+                                                                                P,
+                                                                                dir,
+                                                                                object,
+                                                                                local_object,
+                                                                                prim_addr,
+                                                                                isect_t,
+                                                                                lcg_state,
+                                                                                max_hits);
                                                }
                                                break;
                                        }
@@ -266,16 +268,17 @@ ccl_device void BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                                                /* Intersect ray against primitive. */
                                                for(; prim_addr < prim_addr2; prim_addr++) {
                                                        kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
-                                                       motion_triangle_intersect_subsurface(kg,
-                                                                                            ss_isect,
-                                                                                            P,
-                                                                                            dir,
-                                                                                            ray->time,
-                                                                                            object,
-                                                                                            prim_addr,
-                                                                                            isect_t,
-                                                                                            lcg_state,
-                                                                                            max_hits);
+                                                       motion_triangle_intersect_local(kg,
+                                                                                       local_isect,
+                                                                                       P,
+                                                                                       dir,
+                                                                                       ray->time,
+                                                                                       object,
+                                                                                       local_object,
+                                                                                       prim_addr,
+                                                                                       isect_t,
+                                                                                       lcg_state,
+                                                                                       max_hits);
                                                }
                                                break;
                                        }
index f74995becf53c189f02edd4afe3895b15cfd5187..4a19f2ba0314abe941afa03d69b7ffee0a4f7d55 100644 (file)
@@ -97,17 +97,17 @@ ccl_device_inline float3 motion_triangle_refine(KernelGlobals *kg,
  * for instancing.
  */
 
-#ifdef __SUBSURFACE__
+#ifdef __BVH_LOCAL__
 #  if defined(__KERNEL_CUDA__) && (defined(i386) || defined(_M_IX86))
 ccl_device_noinline
 #  else
 ccl_device_inline
 #  endif
-float3 motion_triangle_refine_subsurface(KernelGlobals *kg,
-                                         ShaderData *sd,
-                                         const Intersection *isect,
-                                         const Ray *ray,
-                                         float3 verts[3])
+float3 motion_triangle_refine_local(KernelGlobals *kg,
+                                    ShaderData *sd,
+                                    const Intersection *isect,
+                                    const Ray *ray,
+                                    float3 verts[3])
 {
        float3 P = ray->P;
        float3 D = ray->D;
@@ -159,7 +159,7 @@ float3 motion_triangle_refine_subsurface(KernelGlobals *kg,
        return P + D*t;
 #  endif  /* __INTERSECTION_REFINE__ */
 }
-#endif  /* __SUBSURFACE__ */
+#endif  /* __BVH_LOCAL__ */
 
 
 /* Ray intersection. We simply compute the vertex positions at the given ray
@@ -215,31 +215,37 @@ ccl_device_inline bool motion_triangle_intersect(
        return false;
 }
 
-/* Special ray intersection routines for subsurface scattering. In that case we
+/* Special ray intersection routines for local intersections. In that case we
  * only want to intersect with primitives in the same object, and if case of
  * multiple hits we pick a single random primitive as the intersection point.
  */
-#ifdef __SUBSURFACE__
-ccl_device_inline void motion_triangle_intersect_subsurface(
+#ifdef __BVH_LOCAL__
+ccl_device_inline void motion_triangle_intersect_local(
         KernelGlobals *kg,
-        SubsurfaceIntersection *ss_isect,
+        LocalIntersection *local_isect,
         float3 P,
         float3 dir,
         float time,
         int object,
+        int local_object,
         int prim_addr,
         float tmax,
         uint *lcg_state,
         int max_hits)
 {
+       /* Only intersect with matching object, for instanced objects we
+        * already know we are only intersecting the right object. */
+       if(object == OBJECT_NONE) {
+               if(kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
+                       return;
+               }
+       }
+
        /* Primitive index for vertex location lookup. */
        int prim = kernel_tex_fetch(__prim_index, prim_addr);
-       int fobject = (object == OBJECT_NONE)
-                         ? kernel_tex_fetch(__prim_object, prim_addr)
-                         : object;
        /* Get vertex locations for intersection. */
        float3 verts[3];
-       motion_triangle_vertices(kg, fobject, prim, time, verts);
+       motion_triangle_vertices(kg, local_object, prim, time, verts);
        /* Ray-triangle intersection, unoptimized. */
        float t, u, v;
        if(ray_triangle_intersect(P,
@@ -252,27 +258,27 @@ ccl_device_inline void motion_triangle_intersect_subsurface(
 #endif
                                  &u, &v, &t))
        {
-               for(int i = min(max_hits, ss_isect->num_hits) - 1; i >= 0; --i) {
-                       if(ss_isect->hits[i].t == t) {
+               for(int i = min(max_hits, local_isect->num_hits) - 1; i >= 0; --i) {
+                       if(local_isect->hits[i].t == t) {
                                return;
                        }
                }
-               ss_isect->num_hits++;
+               local_isect->num_hits++;
                int hit;
-               if(ss_isect->num_hits <= max_hits) {
-                       hit = ss_isect->num_hits - 1;
+               if(local_isect->num_hits <= max_hits) {
+                       hit = local_isect->num_hits - 1;
                }
                else {
                        /* Reservoir sampling: if we are at the maximum number of
                         * hits, randomly replace element or skip it.
                         */
-                       hit = lcg_step_uint(lcg_state) % ss_isect->num_hits;
+                       hit = lcg_step_uint(lcg_state) % local_isect->num_hits;
 
                        if(hit >= max_hits)
                                return;
                }
                /* Record intersection. */
-               Intersection *isect = &ss_isect->hits[hit];
+               Intersection *isect = &local_isect->hits[hit];
                isect->t = t;
                isect->u = u;
                isect->v = v;
@@ -280,10 +286,10 @@ ccl_device_inline void motion_triangle_intersect_subsurface(
                isect->object = object;
                isect->type = PRIMITIVE_MOTION_TRIANGLE;
                /* Record geometric normal. */
-               ss_isect->Ng[hit] = normalize(cross(verts[1] - verts[0],
+               local_isect->Ng[hit] = normalize(cross(verts[1] - verts[0],
                                                    verts[2] - verts[0]));
        }
 }
-#endif  /* __SUBSURFACE__ */
+#endif  /* __BVH_LOCAL__ */
 
 CCL_NAMESPACE_END
index cb456056e20d6d1d43e53106409e3cdb7039886a..4789137d5b08f983633a4f9ec2474ab96b9b6032 100644 (file)
@@ -36,7 +36,7 @@ ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals *kg,
                                                       ShaderData *sd, const
                                                       Intersection *isect,
                                                       const Ray *ray,
-                                                      bool subsurface)
+                                                      bool is_local)
 {
        /* Get shader. */
        sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
@@ -66,16 +66,16 @@ ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals *kg,
        verts[1] = (1.0f - t)*verts[1] + t*next_verts[1];
        verts[2] = (1.0f - t)*verts[2] + t*next_verts[2];
        /* Compute refined position. */
-#ifdef __SUBSURFACE__
-       if(subsurface) {
-               sd->P = motion_triangle_refine_subsurface(kg,
-                                                                    sd,
-                                                                    isect,
-                                                                    ray,
-                                                                    verts);
+#ifdef __BVH_LOCAL__
+       if(is_local) {
+               sd->P = motion_triangle_refine_local(kg,
+                                                    sd,
+                                                    isect,
+                                                    ray,
+                                                    verts);
        }
        else
-#endif  /*  __SUBSURFACE__*/
+#endif  /*  __BVH_LOCAL__*/
        {
                sd->P = motion_triangle_refine(kg, sd, isect, ray, verts);
        }
index 804e74d7e37e2b4d291be63d017ec3abdab15d36..7daa378f81e5abfb1913b77d959ec98417605f75 100644 (file)
@@ -70,23 +70,32 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
        return false;
 }
 
-/* Special ray intersection routines for subsurface scattering. In that case we
+/* Special ray intersection routines for local intersection. In that case we
  * only want to intersect with primitives in the same object, and if case of
  * multiple hits we pick a single random primitive as the intersection point.
  */
 
-#ifdef __SUBSURFACE__
-ccl_device_inline void triangle_intersect_subsurface(
+#ifdef __BVH_LOCAL__
+ccl_device_inline void triangle_intersect_local(
         KernelGlobals *kg,
-        SubsurfaceIntersection *ss_isect,
+        LocalIntersection *local_isect,
         float3 P,
         float3 dir,
         int object,
+               int local_object,
         int prim_addr,
         float tmax,
         uint *lcg_state,
         int max_hits)
 {
+       /* Only intersect with matching object, for instanced objects we
+        * already know we are only intersecting the right object. */
+       if(object == OBJECT_NONE) {
+               if(kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
+                       return;
+               }
+       }
+
        const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, prim_addr);
 #if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
        const ssef *ssef_verts = (ssef*)&kg->__prim_tri_verts.data[tri_vindex];
@@ -109,29 +118,29 @@ ccl_device_inline void triangle_intersect_subsurface(
                return;
        }
 
-       for(int i = min(max_hits, ss_isect->num_hits) - 1; i >= 0; --i) {
-               if(ss_isect->hits[i].t == t) {
+       for(int i = min(max_hits, local_isect->num_hits) - 1; i >= 0; --i) {
+               if(local_isect->hits[i].t == t) {
                        return;
                }
        }
 
-       ss_isect->num_hits++;
+       local_isect->num_hits++;
        int hit;
 
-       if(ss_isect->num_hits <= max_hits) {
-               hit = ss_isect->num_hits - 1;
+       if(local_isect->num_hits <= max_hits) {
+               hit = local_isect->num_hits - 1;
        }
        else {
                /* reservoir sampling: if we are at the maximum number of
                 * hits, randomly replace element or skip it */
-               hit = lcg_step_uint(lcg_state) % ss_isect->num_hits;
+               hit = lcg_step_uint(lcg_state) % local_isect->num_hits;
 
                if(hit >= max_hits)
                        return;
        }
 
        /* record intersection */
-       Intersection *isect = &ss_isect->hits[hit];
+       Intersection *isect = &local_isect->hits[hit];
        isect->prim = prim_addr;
        isect->object = object;
        isect->type = PRIMITIVE_TRIANGLE;
@@ -145,9 +154,9 @@ ccl_device_inline void triangle_intersect_subsurface(
                     tri_b = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex+1)),
                     tri_c = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex+2));
 #endif
-       ss_isect->Ng[hit] = normalize(cross(tri_b - tri_a, tri_c - tri_a));
+       local_isect->Ng[hit] = normalize(cross(tri_b - tri_a, tri_c - tri_a));
 }
-#endif  /* __SUBSURFACE__ */
+#endif  /* __BVH_LOCAL__ */
 
 /* Refine triangle intersection to more precise hit point. For rays that travel
  * far the precision is often not so good, this reintersects the primitive from
@@ -226,10 +235,10 @@ ccl_device_inline float3 triangle_refine(KernelGlobals *kg,
 /* Same as above, except that isect->t is assumed to be in object space for
  * instancing.
  */
-ccl_device_inline float3 triangle_refine_subsurface(KernelGlobals *kg,
-                                                    ShaderData *sd,
-                                                    const Intersection *isect,
-                                                    const Ray *ray)
+ccl_device_inline float3 triangle_refine_local(KernelGlobals *kg,
+                                               ShaderData *sd,
+                                               const Intersection *isect,
+                                               const Ray *ray)
 {
        float3 P = ray->P;
        float3 D = ray->D;
index f93366eade1ca60dcb2184613e5481cda023b547..b37bc65f4dfbdbd0018c6b0df598fda43e37a686 100644 (file)
@@ -340,7 +340,7 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
                /* do subsurface scatter step with copy of shader data, this will
                 * replace the BSSRDF with a diffuse BSDF closure */
                for(int j = 0; j < num_samples; j++) {
-                       SubsurfaceIntersection ss_isect;
+                       LocalIntersection ss_isect;
                        float bssrdf_u, bssrdf_v;
                        path_branched_rng_2D(kg, bssrdf_rng_hash, state, j, num_samples, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
                        int num_hits = subsurface_scatter_multi_intersect(kg,
index 1436e8e5a5b0d5af75709e9fc623bc261c741332..c29b41e42222e8311f6461772824a0a0b197d4ce 100644 (file)
@@ -47,7 +47,7 @@ bool kernel_path_subsurface_scatter(
 
                uint lcg_state = lcg_state_init_addrspace(state, 0x68bc21eb);
 
-               SubsurfaceIntersection ss_isect;
+               LocalIntersection ss_isect;
                int num_hits = subsurface_scatter_multi_intersect(kg,
                                                                  &ss_isect,
                                                                  sd,
index 42f8737555e866a3b6ddf695ff61ca4f84ba99bc..239c6b12bdfcfb909550954769f912b8d45522b4 100644 (file)
@@ -181,7 +181,7 @@ void shader_setup_from_subsurface(
                sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
 
                /* static triangle */
-               sd->P = triangle_refine_subsurface(kg, sd, isect, ray);
+               sd->P = triangle_refine_local(kg, sd, isect, ray);
                sd->Ng = Ng;
                sd->N = Ng;
 
index 6f75601d8c6505426229b3b5528cadf31b0a11c0..87e7d7ff3980e193a64e146982388de0daec6c5c 100644 (file)
@@ -175,7 +175,7 @@ ccl_device void subsurface_color_bump_blur(KernelGlobals *kg,
  */
 ccl_device_inline int subsurface_scatter_multi_intersect(
         KernelGlobals *kg,
-        SubsurfaceIntersection *ss_isect,
+        LocalIntersection *ss_isect,
         ShaderData *sd,
         const ShaderClosure *sc,
         uint *lcg_state,
@@ -240,22 +240,22 @@ ccl_device_inline int subsurface_scatter_multi_intersect(
 
        /* intersect with the same object. if multiple intersections are found it
         * will use at most BSSRDF_MAX_HITS hits, a random subset of all hits */
-       scene_intersect_subsurface(kg,
-                                  *ray,
-                                  ss_isect,
-                                  sd->object,
-                                  lcg_state,
-                                  BSSRDF_MAX_HITS);
+       scene_intersect_local(kg,
+                             *ray,
+                             ss_isect,
+                             sd->object,
+                             lcg_state,
+                             BSSRDF_MAX_HITS);
        int num_eval_hits = min(ss_isect->num_hits, BSSRDF_MAX_HITS);
 
        for(int hit = 0; hit < num_eval_hits; hit++) {
                /* Quickly retrieve P and Ng without setting up ShaderData. */
                float3 hit_P;
                if(sd->type & PRIMITIVE_TRIANGLE) {
-                       hit_P = triangle_refine_subsurface(kg,
-                                                          sd,
-                                                          &ss_isect->hits[hit],
-                                                          ray);
+                       hit_P = triangle_refine_local(kg,
+                                                     sd,
+                                                     &ss_isect->hits[hit],
+                                                     ray);
                }
 #ifdef __OBJECT_MOTION__
                else  if(sd->type & PRIMITIVE_MOTION_TRIANGLE) {
@@ -266,11 +266,11 @@ ccl_device_inline int subsurface_scatter_multi_intersect(
                                kernel_tex_fetch(__prim_index, ss_isect->hits[hit].prim),
                                sd->time,
                                verts);
-                       hit_P = motion_triangle_refine_subsurface(kg,
-                                                                 sd,
-                                                                 &ss_isect->hits[hit],
-                                                                 ray,
-                                                                 verts);
+                       hit_P = motion_triangle_refine_local(kg,
+                                                            sd,
+                                                            &ss_isect->hits[hit],
+                                                            ray,
+                                                            verts);
                }
 #endif  /* __OBJECT_MOTION__ */
                else {
@@ -313,7 +313,7 @@ ccl_device_inline int subsurface_scatter_multi_intersect(
 
 ccl_device_noinline void subsurface_scatter_multi_setup(
         KernelGlobals *kg,
-        SubsurfaceIntersection* ss_isect,
+        LocalIntersection* ss_isect,
         int hit,
         ShaderData *sd,
         ccl_addr_space PathState *state,
@@ -403,8 +403,8 @@ ccl_device void subsurface_scatter_step(KernelGlobals *kg, ShaderData *sd, ccl_a
 
        /* intersect with the same object. if multiple intersections are
         * found it will randomly pick one of them */
-       SubsurfaceIntersection ss_isect;
-       scene_intersect_subsurface(kg, ray, &ss_isect, sd->object, lcg_state, 1);
+       LocalIntersection ss_isect;
+       scene_intersect_local(kg, ray, &ss_isect, sd->object, lcg_state, 1);
 
        /* evaluate bssrdf */
        if(ss_isect.num_hits > 0) {
index 65cae035f29f51f1997d4fc1ec5734df397d62c3..73cf63d42bebb2bf2f8c05b31312819df9f0f3da 100644 (file)
@@ -34,7 +34,7 @@
 
 CCL_NAMESPACE_BEGIN
 
-/* constants */
+/* Constants */
 #define OBJECT_SIZE            12
 #define OBJECT_VECTOR_SIZE     6
 #define LIGHT_SIZE             11
@@ -46,6 +46,7 @@ CCL_NAMESPACE_BEGIN
 
 #define BSSRDF_MIN_RADIUS                      1e-8f
 #define BSSRDF_MAX_HITS                                4
+#define LOCAL_MAX_HITS                         4
 
 #define BECKMANN_TABLE_SIZE            256
 
@@ -56,6 +57,7 @@ CCL_NAMESPACE_BEGIN
 
 #define VOLUME_STACK_SIZE              16
 
+/* Split kernel constants */
 #define WORK_POOL_SIZE_GPU 64
 #define WORK_POOL_SIZE_CPU 1
 #ifdef __KERNEL_GPU__
@@ -76,7 +78,7 @@ CCL_NAMESPACE_BEGIN
 #endif
 
 
-/* device capabilities */
+/* Device capabilities */
 #ifdef __KERNEL_CPU__
 #  ifdef __KERNEL_SSE2__
 #    define __QBVH__
@@ -161,7 +163,7 @@ CCL_NAMESPACE_BEGIN
 
 #endif  /* __KERNEL_OPENCL__ */
 
-/* kernel features */
+/* Kernel features */
 #define __SOBOL__
 #define __INSTANCING__
 #define __DPDU__
@@ -175,8 +177,8 @@ CCL_NAMESPACE_BEGIN
 #define __CLAMP_SAMPLE__
 #define __PATCH_EVAL__
 #define __SHADOW_TRICKS__
-
 #define __DENOISING_FEATURES__
+#define __SHADER_RAYTRACE__
 
 #ifdef __KERNEL_SHADING__
 #  define __SVM__
@@ -199,10 +201,6 @@ CCL_NAMESPACE_BEGIN
 #  define __BAKING__
 #endif
 
-#ifdef WITH_CYCLES_DEBUG
-#  define __KERNEL_DEBUG__
-#endif
-
 /* Scene-based selective features compilation. */
 #ifdef __NO_CAMERA_MOTION__
 #  undef __CAMERA_MOTION__
@@ -241,6 +239,18 @@ CCL_NAMESPACE_BEGIN
 #ifdef __NO_DENOISING__
 #  undef __DENOISING_FEATURES__
 #endif
+#ifdef __NO_SHADER_RAYTRACE__
+#  undef __SHADER_RAYTRACE__
+#endif
+
+/* Features that enable others */
+#ifdef WITH_CYCLES_DEBUG
+#  define __KERNEL_DEBUG__
+#endif
+
+#if defined(__SUBSURFACE__) || defined(__SHADER_RAYTRACE__)
+#  define __BVH_LOCAL__
+#endif
 
 /* Shader Evaluation */
 
@@ -1048,17 +1058,17 @@ typedef struct PathState {
 #endif
 } PathState;
 
-/* Subsurface */
-
-/* Struct to gather multiple SSS hits. */
-typedef struct SubsurfaceIntersection {
+/* Struct to gather multiple nearby intersections. */
+typedef struct LocalIntersection {
        Ray ray;
-       float3 weight[BSSRDF_MAX_HITS];
+       float3 weight[LOCAL_MAX_HITS];
 
        int num_hits;
-       struct Intersection hits[BSSRDF_MAX_HITS];
-       float3 Ng[BSSRDF_MAX_HITS];
-} SubsurfaceIntersection;
+       struct Intersection hits[LOCAL_MAX_HITS];
+       float3 Ng[LOCAL_MAX_HITS];
+} LocalIntersection;
+
+/* Subsurface */
 
 /* Struct to gather SSS indirect rays and delay tracing them. */
 typedef struct SubsurfaceIndirectRays {
@@ -1070,6 +1080,7 @@ typedef struct SubsurfaceIndirectRays {
        float3 throughputs[BSSRDF_MAX_HITS];
        struct PathRadianceState L_state[BSSRDF_MAX_HITS];
 } SubsurfaceIndirectRays;
+static_assert(BSSRDF_MAX_HITS <= LOCAL_MAX_HITS, "BSSRDF hits too high.");
 
 /* Constant Kernel Data
  *
index d3464fede418a3911a4a625037b44b13dd7e6353..5c2aadcf4ec6ab3182c8099c2dc51923511a3a15 100644 (file)
@@ -67,7 +67,7 @@ typedef ccl_global struct SplitBranchedState {
        int num_hits;
 
        uint lcg_state;
-       SubsurfaceIntersection ss_isect;
+       LocalIntersection ss_isect;
 
 #  ifdef __VOLUME__
        VolumeStack volume_stack[VOLUME_STACK_SIZE];
index 8d774c020eea6ad4c43c0b61a99185c53c86e843..c5504d0a89ba8dfacec7c8d323521797414a4dd5 100644 (file)
@@ -61,7 +61,7 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it
                /* do subsurface scatter step with copy of shader data, this will
                 * replace the BSSRDF with a diffuse BSDF closure */
                for(int j = branched_state->ss_next_sample; j < num_samples; j++) {
-                       ccl_global SubsurfaceIntersection *ss_isect = &branched_state->ss_isect;
+                       ccl_global LocalIntersection *ss_isect = &branched_state->ss_isect;
                        float bssrdf_u, bssrdf_v;
                        path_branched_rng_2D(kg,
                                             bssrdf_rng_hash,
@@ -75,7 +75,7 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it
                        /* intersection is expensive so avoid doing multiple times for the same input */
                        if(branched_state->next_hit == 0 && branched_state->next_closure == 0 && branched_state->next_sample == 0) {
                                uint lcg_state = branched_state->lcg_state;
-                               SubsurfaceIntersection ss_isect_private;
+                               LocalIntersection ss_isect_private;
 
                                branched_state->num_hits = subsurface_scatter_multi_intersect(kg,
                                                                                              &ss_isect_private,
@@ -102,7 +102,7 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it
                                *bssrdf_sd = *sd; /* note: copy happens each iteration of inner loop, this is
                                                   * important as the indirect path will write into bssrdf_sd */
 
-                               SubsurfaceIntersection ss_isect_private = *ss_isect;
+                               LocalIntersection ss_isect_private = *ss_isect;
                                subsurface_scatter_multi_setup(kg,
                                                               &ss_isect_private,
                                                               hit,
index f0fd789c6bd17b72893aeb859bea11d373970cba..1d1701b30a29d9e505ba86e0c6d4c15faa8f6eb5 100644 (file)
@@ -157,6 +157,7 @@ public:
        virtual bool has_object_dependency() { return false; }
        virtual bool has_integrator_dependency() { return false; }
        virtual bool has_volume_support() { return false; }
+       virtual bool has_raytrace() { return false; }
        vector<ShaderInput*> inputs;
        vector<ShaderOutput*> outputs;
 
index 70f6d5bab474ab4c5a3f55d0dd0692422c8c5bb2..abb9e19a0746874f5a92d6b89886c38d78b015f4 100644 (file)
@@ -592,6 +592,9 @@ void ShaderManager::get_requested_graph_features(ShaderGraph *graph,
                if(node->has_surface_transparent()) {
                        requested_features->use_transparent = true;
                }
+               if(node->has_raytrace()) {
+                       requested_features->use_shader_raytrace = true;
+               }
        }
 }