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:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2017-10-30 22:25:08 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2017-11-08 00:35:12 +0300
commitf79f38673145c716f9a693084b0bc4c4873e66c1 (patch)
tree42fe530c4e218f23b5989b123d5d3641a77ee68c /intern/cycles
parentd0af56fe3b6490445ba3e501b0fb98cfec622aa3 (diff)
Code refactor: rename subsurface to local traversal, for reuse.
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/device/device.h10
-rw-r--r--intern/cycles/kernel/CMakeLists.txt4
-rw-r--r--intern/cycles/kernel/bvh/bvh.h50
-rw-r--r--intern/cycles/kernel/bvh/bvh_local.h (renamed from intern/cycles/kernel/bvh/bvh_subsurface.h)77
-rw-r--r--intern/cycles/kernel/bvh/qbvh_local.h (renamed from intern/cycles/kernel/bvh/qbvh_subsurface.h)63
-rw-r--r--intern/cycles/kernel/geom/geom_motion_triangle_intersect.h54
-rw-r--r--intern/cycles/kernel/geom/geom_motion_triangle_shader.h18
-rw-r--r--intern/cycles/kernel/geom/geom_triangle_intersect.h43
-rw-r--r--intern/cycles/kernel/kernel_path_branched.h2
-rw-r--r--intern/cycles/kernel/kernel_path_subsurface.h2
-rw-r--r--intern/cycles/kernel/kernel_shader.h2
-rw-r--r--intern/cycles/kernel/kernel_subsurface.h38
-rw-r--r--intern/cycles/kernel/kernel_types.h43
-rw-r--r--intern/cycles/kernel/split/kernel_split_data_types.h2
-rw-r--r--intern/cycles/kernel/split/kernel_subsurface_scatter.h6
-rw-r--r--intern/cycles/render/graph.h1
-rw-r--r--intern/cycles/render/shader.cpp3
17 files changed, 231 insertions, 187 deletions
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index 4f78b9e82a4..6bf3bbe6c25 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -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;
}
};
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index bd51bc4d371..9d52cef1f2c 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -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
diff --git a/intern/cycles/kernel/bvh/bvh.h b/intern/cycles/kernel/bvh/bvh.h
index cf0c8542d69..d3e0b25a200 100644
--- a/intern/cycles/kernel/bvh/bvh.h
+++ b/intern/cycles/kernel/bvh/bvh.h
@@ -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
diff --git a/intern/cycles/kernel/bvh/bvh_subsurface.h b/intern/cycles/kernel/bvh/bvh_local.h
index bda7e34907a..12d14428d6d 100644
--- a/intern/cycles/kernel/bvh/bvh_subsurface.h
+++ b/intern/cycles/kernel/bvh/bvh_local.h
@@ -18,7 +18,7 @@
*/
#ifdef __QBVH__
-# include "kernel/bvh/qbvh_subsurface.h"
+# include "kernel/bvh/qbvh_local.h"
#endif
#if BVH_FEATURE(BVH_HAIR)
@@ -27,9 +27,10 @@
# 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);
}
diff --git a/intern/cycles/kernel/bvh/qbvh_subsurface.h b/intern/cycles/kernel/bvh/qbvh_local.h
index be7658d11d7..2386fa1a1e8 100644
--- a/intern/cycles/kernel/bvh/qbvh_subsurface.h
+++ b/intern/cycles/kernel/bvh/qbvh_local.h
@@ -14,9 +14,10 @@
* 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;
}
diff --git a/intern/cycles/kernel/geom/geom_motion_triangle_intersect.h b/intern/cycles/kernel/geom/geom_motion_triangle_intersect.h
index f74995becf5..4a19f2ba031 100644
--- a/intern/cycles/kernel/geom/geom_motion_triangle_intersect.h
+++ b/intern/cycles/kernel/geom/geom_motion_triangle_intersect.h
@@ -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
diff --git a/intern/cycles/kernel/geom/geom_motion_triangle_shader.h b/intern/cycles/kernel/geom/geom_motion_triangle_shader.h
index cb456056e20..4789137d5b0 100644
--- a/intern/cycles/kernel/geom/geom_motion_triangle_shader.h
+++ b/intern/cycles/kernel/geom/geom_motion_triangle_shader.h
@@ -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);
}
diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h
index 804e74d7e37..7daa378f81e 100644
--- a/intern/cycles/kernel/geom/geom_triangle_intersect.h
+++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h
@@ -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;
diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h
index f93366eade1..b37bc65f4df 100644
--- a/intern/cycles/kernel/kernel_path_branched.h
+++ b/intern/cycles/kernel/kernel_path_branched.h
@@ -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,
diff --git a/intern/cycles/kernel/kernel_path_subsurface.h b/intern/cycles/kernel/kernel_path_subsurface.h
index 1436e8e5a5b..c29b41e4222 100644
--- a/intern/cycles/kernel/kernel_path_subsurface.h
+++ b/intern/cycles/kernel/kernel_path_subsurface.h
@@ -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,
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 42f8737555e..239c6b12bdf 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -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;
diff --git a/intern/cycles/kernel/kernel_subsurface.h b/intern/cycles/kernel/kernel_subsurface.h
index 6f75601d8c6..87e7d7ff398 100644
--- a/intern/cycles/kernel/kernel_subsurface.h
+++ b/intern/cycles/kernel/kernel_subsurface.h
@@ -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) {
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 65cae035f29..73cf63d42be 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -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
*
diff --git a/intern/cycles/kernel/split/kernel_split_data_types.h b/intern/cycles/kernel/split/kernel_split_data_types.h
index d3464fede41..5c2aadcf4ec 100644
--- a/intern/cycles/kernel/split/kernel_split_data_types.h
+++ b/intern/cycles/kernel/split/kernel_split_data_types.h
@@ -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];
diff --git a/intern/cycles/kernel/split/kernel_subsurface_scatter.h b/intern/cycles/kernel/split/kernel_subsurface_scatter.h
index 8d774c020ee..c5504d0a89b 100644
--- a/intern/cycles/kernel/split/kernel_subsurface_scatter.h
+++ b/intern/cycles/kernel/split/kernel_subsurface_scatter.h
@@ -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,
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index f0fd789c6bd..1d1701b30a2 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -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;
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 70f6d5bab47..abb9e19a074 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -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;
+ }
}
}