Cycles code refactor: move more code to geom folder, add some comments.

This commit is contained in:
Brecht Van Lommel
2014-03-29 13:03:48 +01:00
parent 663a750c7f
commit 393216a6df
12 changed files with 296 additions and 124 deletions

View File

@@ -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
)

View 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"

View 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

View File

@@ -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)
{

View File

@@ -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

View File

@@ -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--;

View File

@@ -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)
{

View File

@@ -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)

View File

@@ -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__ */

View File

@@ -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)
{

View File

@@ -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"

View File

@@ -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