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
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2014-03-29 16:03:48 +0400
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2014-03-29 16:03:48 +0400
commit393216a6df934a78f541d98def7a948a89f9b5c8 (patch)
tree4dacc87743cf976dccada7a175477385e95fbee0 /intern
parent663a750c7fe3fdba0830e3054e98f8d3959f9ea3 (diff)
Cycles code refactor: move more code to geom folder, add some comments.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/kernel/CMakeLists.txt4
-rw-r--r--intern/cycles/kernel/geom/geom.h43
-rw-r--r--intern/cycles/kernel/geom/geom_attribute.h77
-rw-r--r--intern/cycles/kernel/geom/geom_bvh.h43
-rw-r--r--intern/cycles/kernel/geom/geom_curve.h19
-rw-r--r--intern/cycles/kernel/geom/geom_motion_curve.h13
-rw-r--r--intern/cycles/kernel/geom/geom_motion_triangle.h36
-rw-r--r--intern/cycles/kernel/geom/geom_object.h76
-rw-r--r--intern/cycles/kernel/geom/geom_primitive.h (renamed from intern/cycles/kernel/kernel_primitive.h)61
-rw-r--r--intern/cycles/kernel/geom/geom_triangle.h23
-rw-r--r--intern/cycles/kernel/kernel_path.h12
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp11
12 files changed, 295 insertions, 123 deletions
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 5fa027bc437..e473b1ab91c 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -35,7 +35,6 @@ set(SRC_HEADERS
kernel_passes.h
kernel_path.h
kernel_path_state.h
- kernel_primitive.h
kernel_projection.h
kernel_random.h
kernel_shader.h
@@ -109,6 +108,8 @@ set(SRC_SVM_HEADERS
)
set(SRC_GEOM_HEADERS
+ geom/geom.h
+ geom/geom_attribute.h
geom/geom_bvh.h
geom/geom_bvh_subsurface.h
geom/geom_bvh_traversal.h
@@ -116,6 +117,7 @@ set(SRC_GEOM_HEADERS
geom/geom_motion_curve.h
geom/geom_motion_triangle.h
geom/geom_object.h
+ geom/geom_primitive.h
geom/geom_triangle.h
)
diff --git a/intern/cycles/kernel/geom/geom.h b/intern/cycles/kernel/geom/geom.h
new file mode 100644
index 00000000000..a4e9bdb1c57
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom.h
@@ -0,0 +1,43 @@
+/*
+ * Adapted from code Copyright 2009-2010 NVIDIA Corporation
+ * Modifications Copyright 2011, Blender Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* bottom-most stack entry, indicating the end of traversal */
+#define ENTRYPOINT_SENTINEL 0x76543210
+
+/* 64 object BVH + 64 mesh BVH + 64 object node splitting */
+#define BVH_STACK_SIZE 192
+#define BVH_NODE_SIZE 4
+#define TRI_NODE_SIZE 3
+
+/* silly workaround for float extended precision that happens when compiling
+ * without sse support on x86, it results in different results for float ops
+ * that you would otherwise expect to compare correctly */
+#if !defined(__i386__) || defined(__SSE__)
+#define NO_EXTENDED_PRECISION
+#else
+#define NO_EXTENDED_PRECISION volatile
+#endif
+
+#include "geom_attribute.h"
+#include "geom_object.h"
+#include "geom_triangle.h"
+#include "geom_motion_triangle.h"
+#include "geom_motion_curve.h"
+#include "geom_curve.h"
+#include "geom_primitive.h"
+#include "geom_bvh.h"
+
diff --git a/intern/cycles/kernel/geom/geom_attribute.h b/intern/cycles/kernel/geom/geom_attribute.h
new file mode 100644
index 00000000000..cbc1fb4fbf2
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_attribute.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2011-2013 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+CCL_NAMESPACE_BEGIN
+
+/* Attributes
+ *
+ * We support an arbitrary number of attributes on various mesh elements.
+ * On vertices, triangles, curve keys, curves, meshes and volume grids.
+ * Most of the code for attribute reading is in the primitive files.
+ *
+ * Lookup of attributes is different between OSL and SVM, as OSL is ustring
+ * based while for SVM we use integer ids. */
+
+/* Find attribute based on ID */
+
+ccl_device_inline int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem)
+{
+ if(sd->object == PRIM_NONE)
+ return (int)ATTR_STD_NOT_FOUND;
+
+#ifdef __OSL__
+ if (kg->osl) {
+ return OSLShader::find_attribute(kg, sd, id, elem);
+ }
+ else
+#endif
+ {
+ /* for SVM, find attribute by unique id */
+ uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
+#ifdef __HAIR__
+ attr_offset = (sd->type & PRIMITIVE_ALL_CURVE)? attr_offset + ATTR_PRIM_CURVE: attr_offset;
+#endif
+ uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+
+ while(attr_map.x != id) {
+ attr_offset += ATTR_PRIM_TYPES;
+ attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+ }
+
+ *elem = (AttributeElement)attr_map.y;
+
+ if(sd->prim == PRIM_NONE && (AttributeElement)attr_map.y != ATTR_ELEMENT_MESH)
+ return ATTR_STD_NOT_FOUND;
+
+ /* return result */
+ return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
+ }
+}
+
+ccl_device Transform primitive_attribute_matrix(KernelGlobals *kg, const ShaderData *sd, int offset)
+{
+ Transform tfm;
+
+ tfm.x = kernel_tex_fetch(__attributes_float3, offset + 0);
+ tfm.y = kernel_tex_fetch(__attributes_float3, offset + 1);
+ tfm.z = kernel_tex_fetch(__attributes_float3, offset + 2);
+ tfm.w = kernel_tex_fetch(__attributes_float3, offset + 3);
+
+ return tfm;
+}
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/geom/geom_bvh.h b/intern/cycles/kernel/geom/geom_bvh.h
index 73bf0194d9a..12ebc646c14 100644
--- a/intern/cycles/kernel/geom/geom_bvh.h
+++ b/intern/cycles/kernel/geom/geom_bvh.h
@@ -15,36 +15,16 @@
* limitations under the License.
*/
-/*
- * "Persistent while-while kernel" used in:
+/* BVH
*
- * "Understanding the Efficiency of Ray Traversal on GPUs",
- * Timo Aila and Samuli Laine,
- * Proc. High-Performance Graphics 2009
- */
-
-/* bottom-most stack entry, indicating the end of traversal */
-#define ENTRYPOINT_SENTINEL 0x76543210
-
-/* 64 object BVH + 64 mesh BVH + 64 object node splitting */
-#define BVH_STACK_SIZE 192
-#define BVH_NODE_SIZE 4
-#define TRI_NODE_SIZE 3
-
-/* silly workaround for float extended precision that happens when compiling
- * without sse support on x86, it results in different results for float ops
- * that you would otherwise expect to compare correctly */
-#if !defined(__i386__) || defined(__SSE__)
-#define NO_EXTENDED_PRECISION
-#else
-#define NO_EXTENDED_PRECISION volatile
-#endif
-
-#include "geom_object.h"
-#include "geom_triangle.h"
-#include "geom_motion_triangle.h"
-#include "geom_motion_curve.h"
-#include "geom_curve.h"
+ * Bounding volume hierarchy for ray tracing. We compile different variations
+ * of the same BVH traversal function for faster rendering when some types of
+ * primitives are not needed, using #includes to work around the lack of
+ * C++ templates in OpenCL.
+ *
+ * Originally based on "Understanding the Efficiency of Ray Traversal on GPUs",
+ * the code has been extended and modified to support more primitives and work
+ * with CPU/CUDA/OpenCL. */
CCL_NAMESPACE_BEGIN
@@ -205,7 +185,10 @@ uint scene_intersect_subsurface(KernelGlobals *kg, const Ray *ray, Intersection
}
#endif
-/* Ray offset to avoid self intersection */
+/* Ray offset to avoid self intersection.
+ *
+ * This function should be used to compute a modified ray start position for
+ * rays leaving from a surface. */
ccl_device_inline float3 ray_offset(float3 P, float3 Ng)
{
diff --git a/intern/cycles/kernel/geom/geom_curve.h b/intern/cycles/kernel/geom/geom_curve.h
index 9d2f2ddb17a..b508f5045c1 100644
--- a/intern/cycles/kernel/geom/geom_curve.h
+++ b/intern/cycles/kernel/geom/geom_curve.h
@@ -14,9 +14,15 @@
CCL_NAMESPACE_BEGIN
+/* Curve Primitive
+ *
+ * Curve primitive for rendering hair and fur. These can be render as flat ribbons
+ * or curves with actual thickness. The curve can also be rendered as line segments
+ * rather than curves for better performance */
+
#ifdef __HAIR__
-/* curve attributes */
+/* Reading attributes on various curve elements */
ccl_device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
{
@@ -92,7 +98,7 @@ ccl_device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd
}
}
-/* hair info node functions */
+/* Curve thickness */
ccl_device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
{
@@ -119,6 +125,8 @@ ccl_device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
return r*2.0f;
}
+/* Curve tangent normal */
+
ccl_device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd)
{
float3 tgN = make_float3(0.0f,0.0f,0.0f);
@@ -137,9 +145,8 @@ ccl_device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd)
return tgN;
}
-#endif
+/* Curve bounds utility function */
-#ifdef __HAIR__
ccl_device_inline void curvebounds(float *lower, float *upper, float *extremta, float *extrema, float *extremtb, float *extremb, float p0, float p1, float p2, float p3)
{
float halfdiscroot = (p2 * p2 - 3 * p3 * p1);
@@ -827,9 +834,6 @@ ccl_device_inline bool bvh_curve_intersect(KernelGlobals *kg, Intersection *isec
#undef dot3
#endif
}
-#endif
-
-#ifdef __HAIR__
ccl_device_inline float3 curvetangent(float t, float3 p0, float3 p1, float3 p2, float3 p3)
{
@@ -993,6 +997,7 @@ ccl_device_inline float3 bvh_curve_refine(KernelGlobals *kg, ShaderData *sd, con
return P;
}
+
#endif
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/geom/geom_motion_curve.h b/intern/cycles/kernel/geom/geom_motion_curve.h
index 128e111be2f..1022a957b05 100644
--- a/intern/cycles/kernel/geom/geom_motion_curve.h
+++ b/intern/cycles/kernel/geom/geom_motion_curve.h
@@ -14,11 +14,20 @@
CCL_NAMESPACE_BEGIN
+/* Motion Curve Primitive
+ *
+ * These are stored as regular curves, plus extra positions and radii at times
+ * other than the frame center. Computing the curve keys at a given ray time is
+ * a matter of interpolation of the two steps between which the ray time lies.
+ *
+ * The extra curve keys are stored as ATTR_STD_MOTION_VERTEX_POSITION.
+ */
+
#ifdef __HAIR__
-/* todo: find a better (faster) solution for this, maybe store offset per object */
ccl_device_inline int find_attribute_curve_motion(KernelGlobals *kg, int object, uint id, AttributeElement *elem)
{
+ /* todo: find a better (faster) solution for this, maybe store offset per object */
uint attr_offset = object*kernel_data.bvh.attributes_map_stride + ATTR_PRIM_CURVE;
uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
@@ -41,7 +50,7 @@ ccl_device_inline void motion_curve_keys_for_step(KernelGlobals *kg, int offset,
keys[1] = kernel_tex_fetch(__curve_keys, k1);
}
else {
- /* center step not store in this array */
+ /* center step not stored in this array */
if(step > numsteps)
step--;
diff --git a/intern/cycles/kernel/geom/geom_motion_triangle.h b/intern/cycles/kernel/geom/geom_motion_triangle.h
index 08ddc8910a7..c5eb0974238 100644
--- a/intern/cycles/kernel/geom/geom_motion_triangle.h
+++ b/intern/cycles/kernel/geom/geom_motion_triangle.h
@@ -15,11 +15,24 @@
* limitations under the License.
*/
+/* Motion Triangle Primitive
+ *
+ * These are stored as regular triangles, plus extra positions and normals at
+ * times other than the frame center. Computing the triangle vertex positions
+ * or normals at a given ray time is a matter of interpolation of the two steps
+ * between which the ray time lies.
+ *
+ * The extra positions and normals are stored as ATTR_STD_MOTION_VERTEX_POSITION
+ * and ATTR_STD_MOTION_VERTEX_NORMAL mesh attributes.
+ */
+
CCL_NAMESPACE_BEGIN
-/* todo: find a better (faster) solution for this, maybe store offset per object */
+/* Time interpolation of vertex positions and normals */
+
ccl_device_inline int find_attribute_motion(KernelGlobals *kg, int object, uint id, AttributeElement *elem)
{
+ /* todo: find a better (faster) solution for this, maybe store offset per object */
uint attr_offset = object*kernel_data.bvh.attributes_map_stride;
uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
@@ -64,7 +77,7 @@ ccl_device_inline void motion_triangle_normals_for_step(KernelGlobals *kg, float
normals[2] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.z)));
}
else {
- /* center step not store in this array */
+ /* center step not stored in this array */
if(step > numsteps)
step--;
@@ -76,7 +89,6 @@ ccl_device_inline void motion_triangle_normals_for_step(KernelGlobals *kg, float
}
}
-/* return 3 triangle vertex locations */
ccl_device_inline void motion_triangle_vertices(KernelGlobals *kg, int object, int prim, float time, float3 verts[3])
{
/* get motion info */
@@ -160,7 +172,9 @@ ccl_device_inline float3 motion_triangle_refine(KernelGlobals *kg, ShaderData *s
#endif
}
-/* same as above, except that isect->t is assumed to be in object space for instancing */
+/* Same as above, except that isect->t is assumed to be in object space for instancing */
+
+#ifdef __SUBSURFACE__
ccl_device_inline float3 motion_triangle_refine_subsurface(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray, float3 verts[3])
{
float3 P = ray->P;
@@ -209,6 +223,11 @@ ccl_device_inline float3 motion_triangle_refine_subsurface(KernelGlobals *kg, Sh
return P + D*t;
#endif
}
+#endif
+
+/* Setup of motion triangle specific parts of ShaderData, moved into this one
+ * function to more easily share computation of interpolated positions and
+ * normals */
/* return 3 triangle vertex normals */
ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray, bool subsurface)
@@ -244,10 +263,14 @@ ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals *kg, ShaderD
verts[2] = (1.0f - t)*verts[2] + t*next_verts[2];
/* compute refined position */
+#ifdef __SUBSURFACE__
if(!subsurface)
+#endif
sd->P = motion_triangle_refine(kg, sd, isect, ray, verts);
+#ifdef __SUBSURFACE__
else
sd->P = motion_triangle_refine_subsurface(kg, sd, isect, ray, verts);
+#endif
/* compute face normal */
float3 Ng = normalize(cross(verts[1] - verts[0], verts[2] - verts[0]));
@@ -286,7 +309,8 @@ ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals *kg, ShaderD
}
}
-
+/* Ray intersection. We simply compute the vertex positions at the given ray
+ * time and do a ray intersection with the resulting triangle */
ccl_device_inline bool motion_triangle_intersect(KernelGlobals *kg, Intersection *isect,
float3 P, float3 idir, float time, uint visibility, int object, int triAddr)
@@ -317,11 +341,11 @@ ccl_device_inline bool motion_triangle_intersect(KernelGlobals *kg, Intersection
return false;
}
-#ifdef __SUBSURFACE__
/* Special ray intersection routines for subsurface scattering. 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(KernelGlobals *kg, Intersection *isect_array,
float3 P, float3 idir, float time, int object, int triAddr, float tmax, uint *num_hits, uint *lcg_state, int max_hits)
{
diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h
index 06f7d28c052..3be8a71ca83 100644
--- a/intern/cycles/kernel/geom/geom_object.h
+++ b/intern/cycles/kernel/geom/geom_object.h
@@ -12,8 +12,20 @@
* limitations under the License.
*/
+/* Object Primitive
+ *
+ * All mesh and curve primitives are part of an object. The same mesh and curves
+ * may be instanced multiple times by different objects.
+ *
+ * If the mesh is not instanced multiple times, the object will not be explicitly
+ * stored as a primitive in the BVH, rather the bare triangles are curved are
+ * directly primitives in the BVH with world space locations applied, and the object
+ * ID is looked up afterwards. */
+
CCL_NAMESPACE_BEGIN
+/* Object attributes, for now a fixed size and contents */
+
enum ObjectTransform {
OBJECT_TRANSFORM = 0,
OBJECT_TRANSFORM_MOTION_PRE = 0,
@@ -28,6 +40,8 @@ enum ObjectVectorTransform {
OBJECT_VECTOR_MOTION_POST = 3
};
+/* Object to world space transformation */
+
ccl_device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
{
int offset = object*OBJECT_SIZE + (int)type;
@@ -41,6 +55,8 @@ ccl_device_inline Transform object_fetch_transform(KernelGlobals *kg, int object
return tfm;
}
+/* Object to world space transformation for motion vectors */
+
ccl_device_inline Transform object_fetch_vector_transform(KernelGlobals *kg, int object, enum ObjectVectorTransform type)
{
int offset = object*OBJECT_VECTOR_SIZE + (int)type;
@@ -54,6 +70,8 @@ ccl_device_inline Transform object_fetch_vector_transform(KernelGlobals *kg, int
return tfm;
}
+/* Motion blurred object transformations */
+
#ifdef __OBJECT_MOTION__
ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
{
@@ -100,7 +118,9 @@ ccl_device_inline Transform object_fetch_transform_motion_test(KernelGlobals *kg
}
#endif
-ccl_device_inline void object_position_transform(KernelGlobals *kg, ShaderData *sd, float3 *P)
+/* Transform position from object to world space */
+
+ccl_device_inline void object_position_transform(KernelGlobals *kg, const ShaderData *sd, float3 *P)
{
#ifdef __OBJECT_MOTION__
*P = transform_point(&sd->ob_tfm, *P);
@@ -110,7 +130,9 @@ ccl_device_inline void object_position_transform(KernelGlobals *kg, ShaderData *
#endif
}
-ccl_device_inline void object_inverse_position_transform(KernelGlobals *kg, ShaderData *sd, float3 *P)
+/* Transform position from world to object space */
+
+ccl_device_inline void object_inverse_position_transform(KernelGlobals *kg, const ShaderData *sd, float3 *P)
{
#ifdef __OBJECT_MOTION__
*P = transform_point(&sd->ob_itfm, *P);
@@ -120,7 +142,9 @@ ccl_device_inline void object_inverse_position_transform(KernelGlobals *kg, Shad
#endif
}
-ccl_device_inline void object_inverse_normal_transform(KernelGlobals *kg, ShaderData *sd, float3 *N)
+/* Transform normal from world to object space */
+
+ccl_device_inline void object_inverse_normal_transform(KernelGlobals *kg, const ShaderData *sd, float3 *N)
{
#ifdef __OBJECT_MOTION__
*N = normalize(transform_direction_transposed(&sd->ob_tfm, *N));
@@ -130,7 +154,9 @@ ccl_device_inline void object_inverse_normal_transform(KernelGlobals *kg, Shader
#endif
}
-ccl_device_inline void object_normal_transform(KernelGlobals *kg, ShaderData *sd, float3 *N)
+/* Transform normal from object to world space */
+
+ccl_device_inline void object_normal_transform(KernelGlobals *kg, const ShaderData *sd, float3 *N)
{
#ifdef __OBJECT_MOTION__
*N = normalize(transform_direction_transposed(&sd->ob_itfm, *N));
@@ -140,7 +166,9 @@ ccl_device_inline void object_normal_transform(KernelGlobals *kg, ShaderData *sd
#endif
}
-ccl_device_inline void object_dir_transform(KernelGlobals *kg, ShaderData *sd, float3 *D)
+/* Transform direction vector from object to world space */
+
+ccl_device_inline void object_dir_transform(KernelGlobals *kg, const ShaderData *sd, float3 *D)
{
#ifdef __OBJECT_MOTION__
*D = transform_direction(&sd->ob_tfm, *D);
@@ -150,7 +178,9 @@ ccl_device_inline void object_dir_transform(KernelGlobals *kg, ShaderData *sd, f
#endif
}
-ccl_device_inline void object_inverse_dir_transform(KernelGlobals *kg, ShaderData *sd, float3 *D)
+/* Transform direction vector from world to object space */
+
+ccl_device_inline void object_inverse_dir_transform(KernelGlobals *kg, const ShaderData *sd, float3 *D)
{
#ifdef __OBJECT_MOTION__
*D = transform_direction(&sd->ob_itfm, *D);
@@ -160,7 +190,9 @@ ccl_device_inline void object_inverse_dir_transform(KernelGlobals *kg, ShaderDat
#endif
}
-ccl_device_inline float3 object_location(KernelGlobals *kg, ShaderData *sd)
+/* Object center position */
+
+ccl_device_inline float3 object_location(KernelGlobals *kg, const ShaderData *sd)
{
if(sd->object == OBJECT_NONE)
return make_float3(0.0f, 0.0f, 0.0f);
@@ -173,6 +205,8 @@ ccl_device_inline float3 object_location(KernelGlobals *kg, ShaderData *sd)
#endif
}
+/* Total surface area of object */
+
ccl_device_inline float object_surface_area(KernelGlobals *kg, int object)
{
int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES;
@@ -180,6 +214,8 @@ ccl_device_inline float object_surface_area(KernelGlobals *kg, int object)
return f.x;
}
+/* Pass ID number of object */
+
ccl_device_inline float object_pass_id(KernelGlobals *kg, int object)
{
if(object == OBJECT_NONE)
@@ -190,6 +226,8 @@ ccl_device_inline float object_pass_id(KernelGlobals *kg, int object)
return f.y;
}
+/* Per object random number for shader variation */
+
ccl_device_inline float object_random_number(KernelGlobals *kg, int object)
{
if(object == OBJECT_NONE)
@@ -200,6 +238,8 @@ ccl_device_inline float object_random_number(KernelGlobals *kg, int object)
return f.z;
}
+/* Particle ID from which this object was generated */
+
ccl_device_inline uint object_particle_id(KernelGlobals *kg, int object)
{
if(object == OBJECT_NONE)
@@ -210,6 +250,8 @@ ccl_device_inline uint object_particle_id(KernelGlobals *kg, int object)
return __float_as_uint(f.w);
}
+/* Generated texture coordinate on surface from where object was instanced */
+
ccl_device_inline float3 object_dupli_generated(KernelGlobals *kg, int object)
{
if(object == OBJECT_NONE)
@@ -220,6 +262,8 @@ ccl_device_inline float3 object_dupli_generated(KernelGlobals *kg, int object)
return make_float3(f.x, f.y, f.z);
}
+/* UV texture coordinate on surface from where object was instanced */
+
ccl_device_inline float3 object_dupli_uv(KernelGlobals *kg, int object)
{
if(object == OBJECT_NONE)
@@ -230,6 +274,8 @@ ccl_device_inline float3 object_dupli_uv(KernelGlobals *kg, int object)
return make_float3(f.x, f.y, 0.0f);
}
+/* Information about mesh for motion blurred triangles and curves */
+
ccl_device_inline void object_motion_info(KernelGlobals *kg, int object, int *numsteps, int *numverts, int *numkeys)
{
int offset = object*OBJECT_SIZE + OBJECT_DUPLI;
@@ -246,11 +292,15 @@ ccl_device_inline void object_motion_info(KernelGlobals *kg, int object, int *nu
*numverts = __float_as_int(f.w);
}
-ccl_device int shader_pass_id(KernelGlobals *kg, ShaderData *sd)
+/* Pass ID for shader */
+
+ccl_device int shader_pass_id(KernelGlobals *kg, const ShaderData *sd)
{
return kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2 + 1);
}
+/* Particle data from which object was instanced */
+
ccl_device_inline float particle_index(KernelGlobals *kg, int particle)
{
int offset = particle*PARTICLE_SIZE;
@@ -309,7 +359,7 @@ ccl_device float3 particle_angular_velocity(KernelGlobals *kg, int particle)
return make_float3(f3.z, f3.w, f4.x);
}
-/* BVH */
+/* Object intersection in BVH */
ccl_device_inline float3 bvh_inverse_direction(float3 dir)
{
@@ -324,6 +374,8 @@ ccl_device_inline float3 bvh_inverse_direction(float3 dir)
return idir;
}
+/* Transform ray into object space to enter static object in BVH */
+
ccl_device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax)
{
Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
@@ -341,6 +393,8 @@ ccl_device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ra
*t *= len;
}
+/* Transorm ray to exit static object in BVH */
+
ccl_device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax)
{
if(*t != FLT_MAX) {
@@ -353,6 +407,8 @@ ccl_device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray
}
#ifdef __OBJECT_MOTION__
+/* Transform ray into object space to enter motion blurred object in BVH */
+
ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, Transform *tfm, const float tmax)
{
Transform itfm;
@@ -371,6 +427,8 @@ ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, c
*t *= len;
}
+/* Transorm ray to exit motion blurred object in BVH */
+
ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, Transform *tfm, const float tmax)
{
if(*t != FLT_MAX)
diff --git a/intern/cycles/kernel/kernel_primitive.h b/intern/cycles/kernel/geom/geom_primitive.h
index 11f6231afac..d90cc108492 100644
--- a/intern/cycles/kernel/kernel_primitive.h
+++ b/intern/cycles/kernel/geom/geom_primitive.h
@@ -14,46 +14,14 @@
* limitations under the License
*/
-#ifndef __KERNEL_ATTRIBUTE_CL__
-#define __KERNEL_ATTRIBUTE_CL__
+/* Primitive Utilities
+ *
+ * Generic functions to look up mesh, curve and volume primitive attributes for
+ * shading and render passes. */
CCL_NAMESPACE_BEGIN
-/* attribute lookup */
-
-ccl_device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id, AttributeElement *elem)
-{
- if(sd->object == PRIM_NONE)
- return (int)ATTR_STD_NOT_FOUND;
-
-#ifdef __OSL__
- if (kg->osl) {
- return OSLShader::find_attribute(kg, sd, id, elem);
- }
- else
-#endif
- {
- /* for SVM, find attribute by unique id */
- uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
-#ifdef __HAIR__
- attr_offset = (sd->type & PRIMITIVE_ALL_CURVE)? attr_offset + ATTR_PRIM_CURVE: attr_offset;
-#endif
- uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
-
- while(attr_map.x != id) {
- attr_offset += ATTR_PRIM_TYPES;
- attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
- }
-
- *elem = (AttributeElement)attr_map.y;
-
- if(sd->prim == PRIM_NONE && (AttributeElement)attr_map.y != ATTR_ELEMENT_MESH)
- return ATTR_STD_NOT_FOUND;
-
- /* return result */
- return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
- }
-}
+/* Generic primitive attribute reading functions */
ccl_device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
{
@@ -79,17 +47,7 @@ ccl_device float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData
#endif
}
-ccl_device Transform primitive_attribute_matrix(KernelGlobals *kg, const ShaderData *sd, int offset)
-{
- Transform tfm;
-
- tfm.x = kernel_tex_fetch(__attributes_float3, offset + 0);
- tfm.y = kernel_tex_fetch(__attributes_float3, offset + 1);
- tfm.z = kernel_tex_fetch(__attributes_float3, offset + 2);
- tfm.w = kernel_tex_fetch(__attributes_float3, offset + 3);
-
- return tfm;
-}
+/* Default UV coordinate */
ccl_device float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
{
@@ -104,6 +62,8 @@ ccl_device float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
return uv;
}
+/* Ptex coordinates */
+
ccl_device bool primitive_ptex(KernelGlobals *kg, ShaderData *sd, float2 *uv, int *face_id)
{
/* storing ptex data as attributes is not memory efficient but simple for tests */
@@ -123,6 +83,8 @@ ccl_device bool primitive_ptex(KernelGlobals *kg, ShaderData *sd, float2 *uv, in
return true;
}
+/* Surface tangent */
+
ccl_device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
{
#ifdef __HAIR__
@@ -154,7 +116,7 @@ ccl_device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
}
}
-/* motion */
+/* Motion vector for motion pass */
ccl_device float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd)
{
@@ -228,4 +190,3 @@ ccl_device float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd)
CCL_NAMESPACE_END
-#endif /* __KERNEL_ATTRIBUTE_CL__ */
diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h
index ab59524f7c9..3fdf9e8a7cc 100644
--- a/intern/cycles/kernel/geom/geom_triangle.h
+++ b/intern/cycles/kernel/geom/geom_triangle.h
@@ -15,6 +15,12 @@
* limitations under the License.
*/
+/* Triangle Primitive
+ *
+ * Basic triangle with 3 vertices is used to represent mesh surfaces. For BVH
+ * ray intersection we use a precomputed triangle storage to accelarate
+ * intersection at the cost of more memory usage */
+
CCL_NAMESPACE_BEGIN
/* Refine triangle intersection to more precise hit point. For rays that travel
@@ -129,10 +135,10 @@ ccl_device_inline void triangle_point_normal(KernelGlobals *kg, int prim, float
*shader = __float_as_int(Nm.w);
}
-/* Return 3 triangle vertex locations */
+/* Triangle vertex locations */
+
ccl_device_inline void triangle_vertices(KernelGlobals *kg, int prim, float3 P[3])
{
- /* load triangle vertices */
float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, prim));
P[0] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x)));
@@ -140,6 +146,8 @@ ccl_device_inline void triangle_vertices(KernelGlobals *kg, int prim, float3 P[3
P[2] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z)));
}
+/* Interpolate smooth vertex normal from vertices */
+
ccl_device_inline float3 triangle_smooth_normal(KernelGlobals *kg, int prim, float u, float v)
{
/* load triangle vertices */
@@ -152,6 +160,8 @@ ccl_device_inline float3 triangle_smooth_normal(KernelGlobals *kg, int prim, flo
return normalize((1.0f - u - v)*n2 + u*n0 + v*n1);
}
+/* Ray differentials on triangle */
+
ccl_device_inline void triangle_dPdudv(KernelGlobals *kg, int prim, float3 *dPdu, float3 *dPdv)
{
/* fetch triangle vertex coordinates */
@@ -166,7 +176,7 @@ ccl_device_inline void triangle_dPdudv(KernelGlobals *kg, int prim, float3 *dPdu
*dPdv = (p1 - p2);
}
-/* attributes */
+/* Reading attributes on various triangle elements */
ccl_device float triangle_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
{
@@ -254,7 +264,10 @@ ccl_device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData
}
}
-/* Sven Woop's algorithm */
+/* Ray-Triangle intersection for BVH traversal
+ *
+ * Based on Sven Woop's algorithm with precomputed triangle storage */
+
ccl_device_inline bool triangle_intersect(KernelGlobals *kg, Intersection *isect,
float3 P, float3 idir, uint visibility, int object, int triAddr)
{
@@ -303,11 +316,11 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, Intersection *isect
return false;
}
-#ifdef __SUBSURFACE__
/* Special ray intersection routines for subsurface scattering. 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(KernelGlobals *kg, Intersection *isect_array,
float3 P, float3 idir, int object, int triAddr, float tmax, uint *num_hits, uint *lcg_state, int max_hits)
{
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 4ee3eea03a7..a4a7a2db6f5 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -19,16 +19,14 @@
#endif
#include "kernel_random.h"
+#include "kernel_projection.h"
+#include "kernel_montecarlo.h"
+#include "kernel_differential.h"
+#include "kernel_camera.h"
-#include "geom/geom_bvh.h"
+#include "geom/geom.h"
-#include "kernel_differential.h"
-#include "kernel_montecarlo.h"
-#include "kernel_projection.h"
-#include "kernel_primitive.h"
-#include "kernel_projection.h"
#include "kernel_accumulate.h"
-#include "kernel_camera.h"
#include "kernel_shader.h"
#include "kernel_light.h"
#include "kernel_emission.h"
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 8ef160663a3..65548d65308 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -31,16 +31,15 @@
#include "kernel_compat_cpu.h"
#include "kernel_globals.h"
#include "kernel_random.h"
-
-#include "geom/geom_bvh.h"
-
-#include "kernel_montecarlo.h"
#include "kernel_projection.h"
#include "kernel_differential.h"
-#include "kernel_primitive.h"
+#include "kernel_montecarlo.h"
+#include "kernel_camera.h"
+
+#include "geom/geom.h"
+
#include "kernel_projection.h"
#include "kernel_accumulate.h"
-#include "kernel_camera.h"
#include "kernel_shader.h"
#ifdef WITH_PTEX