diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2014-03-29 16:03:48 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2014-03-29 16:03:48 +0400 |
commit | 393216a6df934a78f541d98def7a948a89f9b5c8 (patch) | |
tree | 4dacc87743cf976dccada7a175477385e95fbee0 /intern | |
parent | 663a750c7fe3fdba0830e3054e98f8d3959f9ea3 (diff) |
Cycles code refactor: move more code to geom folder, add some comments.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/kernel/CMakeLists.txt | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom.h | 43 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_attribute.h | 77 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_bvh.h | 43 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_curve.h | 19 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_motion_curve.h | 13 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_motion_triangle.h | 36 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_object.h | 76 | ||||
-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.h | 23 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_path.h | 12 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_services.cpp | 11 |
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 |