Cycles code refactor: move more code to geom folder, add some comments.
This commit is contained in:
@@ -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
|
||||
)
|
||||
|
||||
|
43
intern/cycles/kernel/geom/geom.h
Normal file
43
intern/cycles/kernel/geom/geom.h
Normal file
@@ -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"
|
||||
|
77
intern/cycles/kernel/geom/geom_attribute.h
Normal file
77
intern/cycles/kernel/geom/geom_attribute.h
Normal file
@@ -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
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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
|
||||
|
@@ -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--;
|
||||
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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)
|
||||
|
@@ -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__ */
|
@@ -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)
|
||||
{
|
||||
|
@@ -19,16 +19,14 @@
|
||||
#endif
|
||||
|
||||
#include "kernel_random.h"
|
||||
|
||||
#include "geom/geom_bvh.h"
|
||||
|
||||
#include "kernel_differential.h"
|
||||
#include "kernel_projection.h"
|
||||
#include "kernel_montecarlo.h"
|
||||
#include "kernel_projection.h"
|
||||
#include "kernel_primitive.h"
|
||||
#include "kernel_projection.h"
|
||||
#include "kernel_accumulate.h"
|
||||
#include "kernel_differential.h"
|
||||
#include "kernel_camera.h"
|
||||
|
||||
#include "geom/geom.h"
|
||||
|
||||
#include "kernel_accumulate.h"
|
||||
#include "kernel_shader.h"
|
||||
#include "kernel_light.h"
|
||||
#include "kernel_emission.h"
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user