Blender  V2.93
bvh_shadow_all.h
Go to the documentation of this file.
1 /*
2  * Adapted from code Copyright 2009-2010 NVIDIA Corporation,
3  * and code copyright 2009-2012 Intel Corporation
4  *
5  * Modifications Copyright 2011-2013, Blender Foundation.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #if BVH_FEATURE(BVH_HAIR)
21 # define NODE_INTERSECT bvh_node_intersect
22 #else
23 # define NODE_INTERSECT bvh_aligned_node_intersect
24 #endif
25 
26 /* This is a template BVH traversal function, where various features can be
27  * enabled/disabled. This way we can compile optimized versions for each case
28  * without new features slowing things down.
29  *
30  * BVH_HAIR: hair curve rendering
31  * BVH_MOTION: motion blur rendering
32  */
33 
34 #ifndef __KERNEL_GPU__
36 #else
38 #endif
39  bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
40  const Ray *ray,
41  Intersection *isect_array,
42  const uint visibility,
43  const uint max_hits,
44  uint *num_hits)
45 {
46  /* todo:
47  * - likely and unlikely for if() statements
48  * - test restrict attribute for pointers
49  */
50 
51  /* traversal stack in CUDA thread-local memory */
54 
55  /* traversal variables in registers */
56  int stack_ptr = 0;
57  int node_addr = kernel_data.bvh.root;
58 
59  /* ray parameters in registers */
60  const float tmax = ray->t;
61  float3 P = ray->P;
62  float3 dir = bvh_clamp_direction(ray->D);
63  float3 idir = bvh_inverse_direction(dir);
64  int object = OBJECT_NONE;
65  float isect_t = tmax;
66 
67 #if BVH_FEATURE(BVH_MOTION)
68  Transform ob_itfm;
69 #endif
70 
71  int num_hits_in_instance = 0;
72 
73  *num_hits = 0;
74  isect_array->t = tmax;
75 
76  /* traversal loop */
77  do {
78  do {
79  /* traverse internal nodes */
80  while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
81  int node_addr_child1, traverse_mask;
82  float dist[2];
83  float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
84 
85  traverse_mask = NODE_INTERSECT(kg,
86  P,
88  dir,
89 #endif
90  idir,
91  isect_t,
92  node_addr,
93  visibility,
94  dist);
95 
96  node_addr = __float_as_int(cnodes.z);
97  node_addr_child1 = __float_as_int(cnodes.w);
98 
99  if (traverse_mask == 3) {
100  /* Both children were intersected, push the farther one. */
101  bool is_closest_child1 = (dist[1] < dist[0]);
102  if (is_closest_child1) {
103  int tmp = node_addr;
104  node_addr = node_addr_child1;
105  node_addr_child1 = tmp;
106  }
107 
108  ++stack_ptr;
109  kernel_assert(stack_ptr < BVH_STACK_SIZE);
110  traversal_stack[stack_ptr] = node_addr_child1;
111  }
112  else {
113  /* One child was intersected. */
114  if (traverse_mask == 2) {
115  node_addr = node_addr_child1;
116  }
117  else if (traverse_mask == 0) {
118  /* Neither child was intersected. */
119  node_addr = traversal_stack[stack_ptr];
120  --stack_ptr;
121  }
122  }
123  }
124 
125  /* if node is leaf, fetch triangle list */
126  if (node_addr < 0) {
127  float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
128  int prim_addr = __float_as_int(leaf.x);
129 
130  if (prim_addr >= 0) {
131  const int prim_addr2 = __float_as_int(leaf.y);
132  const uint type = __float_as_int(leaf.w);
133  const uint p_type = type & PRIMITIVE_ALL;
134 
135  /* pop */
136  node_addr = traversal_stack[stack_ptr];
137  --stack_ptr;
138 
139  /* primitive intersection */
140  while (prim_addr < prim_addr2) {
141  kernel_assert((kernel_tex_fetch(__prim_type, prim_addr) & PRIMITIVE_ALL) == p_type);
142  bool hit;
143 
144  /* todo: specialized intersect functions which don't fill in
145  * isect unless needed and check SD_HAS_TRANSPARENT_SHADOW?
146  * might give a few % performance improvement */
147 
148  switch (p_type) {
149  case PRIMITIVE_TRIANGLE: {
150  hit = triangle_intersect(kg, isect_array, P, dir, visibility, object, prim_addr);
151  break;
152  }
153 #if BVH_FEATURE(BVH_MOTION)
156  kg, isect_array, P, dir, ray->time, visibility, object, prim_addr);
157  break;
158  }
159 #endif
160 #if BVH_FEATURE(BVH_HAIR)
165  const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr);
166  hit = curve_intersect(
167  kg, isect_array, P, dir, visibility, object, prim_addr, ray->time, curve_type);
168  break;
169  }
170 #endif
171  default: {
172  hit = false;
173  break;
174  }
175  }
176 
177  /* shadow ray early termination */
178  if (hit) {
179  /* detect if this surface has a shader with transparent shadows */
180 
181  /* todo: optimize so primitive visibility flag indicates if
182  * the primitive has a transparent shadow shader? */
183  int prim = kernel_tex_fetch(__prim_index, isect_array->prim);
184  int shader = 0;
185 
186 #ifdef __HAIR__
187  if (kernel_tex_fetch(__prim_type, isect_array->prim) & PRIMITIVE_ALL_TRIANGLE)
188 #endif
189  {
190  shader = kernel_tex_fetch(__tri_shader, prim);
191  }
192 #ifdef __HAIR__
193  else {
194  float4 str = kernel_tex_fetch(__curves, prim);
196  }
197 #endif
198  int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
199 
200  /* if no transparent shadows, all light is blocked */
201  if (!(flag & SD_HAS_TRANSPARENT_SHADOW)) {
202  return true;
203  }
204  /* if maximum number of hits reached, block all light */
205  else if (*num_hits == max_hits) {
206  return true;
207  }
208 
209  /* move on to next entry in intersections array */
210  isect_array++;
211  (*num_hits)++;
212  num_hits_in_instance++;
213 
214  isect_array->t = isect_t;
215  }
216 
217  prim_addr++;
218  }
219  }
220  else {
221  /* instance push */
222  object = kernel_tex_fetch(__prim_object, -prim_addr - 1);
223 
224 #if BVH_FEATURE(BVH_MOTION)
225  isect_t = bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, isect_t, &ob_itfm);
226 #else
227  isect_t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect_t);
228 #endif
229 
230  num_hits_in_instance = 0;
231  isect_array->t = isect_t;
232 
233  ++stack_ptr;
234  kernel_assert(stack_ptr < BVH_STACK_SIZE);
236 
237  node_addr = kernel_tex_fetch(__object_node, object);
238  }
239  }
240  } while (node_addr != ENTRYPOINT_SENTINEL);
241 
242  if (stack_ptr >= 0) {
243  kernel_assert(object != OBJECT_NONE);
244 
245  /* Instance pop. */
246  if (num_hits_in_instance) {
247  float t_fac;
248 
249 #if BVH_FEATURE(BVH_MOTION)
250  bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm);
251 #else
252  bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
253 #endif
254 
255  /* scale isect->t to adjust for instancing */
256  for (int i = 0; i < num_hits_in_instance; i++) {
257  (isect_array - i - 1)->t *= t_fac;
258  }
259  }
260  else {
261 #if BVH_FEATURE(BVH_MOTION)
262  bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX, &ob_itfm);
263 #else
264  bvh_instance_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX);
265 #endif
266  }
267 
268  isect_t = tmax;
269  isect_array->t = isect_t;
270 
271  object = OBJECT_NONE;
272  node_addr = traversal_stack[stack_ptr];
273  --stack_ptr;
274  }
275  } while (node_addr != ENTRYPOINT_SENTINEL);
276 
277  return false;
278 }
279 
281  const Ray *ray,
282  Intersection *isect_array,
283  const uint visibility,
284  const uint max_hits,
285  uint *num_hits)
286 {
287  return BVH_FUNCTION_FULL_NAME(BVH)(kg, ray, isect_array, visibility, max_hits, num_hits);
288 }
289 
290 #undef BVH_FUNCTION_NAME
291 #undef BVH_FUNCTION_FEATURES
292 #undef NODE_INTERSECT
unsigned int uint
Definition: BLI_sys_types.h:83
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersection *isect_array, const uint visibility, const uint max_hits, uint *num_hits)
#define NODE_INTERSECT
#define BVH_STACK_SIZE
Definition: bvh_types.h:33
#define BVH_FEATURE(f)
Definition: bvh_types.h:43
#define ENTRYPOINT_SENTINEL
Definition: bvh_types.h:30
#define BVH_HAIR
Definition: bvh_types.h:37
#define BVH_FUNCTION_FULL_NAME(prefix)
Definition: bvh_types.h:41
Definition: bvh/bvh.h:80
BLI_Stack * traversal_stack
#define str(s)
ccl_device_inline bool motion_triangle_intersect(KernelGlobals *kg, Intersection *isect, float3 P, float3 dir, float time, uint visibility, int object, int prim_addr)
ccl_device_inline float3 bvh_clamp_direction(float3 dir)
Definition: geom_object.h:405
ccl_device_inline float3 bvh_inverse_direction(float3 dir)
Definition: geom_object.h:413
ccl_device_inline float bvh_instance_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float t)
Definition: geom_object.h:420
ccl_device_inline float bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float t)
Definition: geom_object.h:440
ccl_device_inline void bvh_instance_pop_factor(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t_fac)
Definition: geom_object.h:457
CCL_NAMESPACE_BEGIN ccl_device_inline bool triangle_intersect(KernelGlobals *kg, Intersection *isect, float3 P, float3 dir, uint visibility, int object, int prim_addr)
#define kernel_data
#define kernel_assert(cond)
#define kernel_tex_fetch(tex, index)
#define ccl_device
#define ccl_device_inline
void KERNEL_FUNCTION_FULL_NAME() shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int filter, int i, int offset, int sample)
@ SD_HAS_TRANSPARENT_SHADOW
Definition: kernel_types.h:871
@ PRIMITIVE_MOTION_CURVE_RIBBON
Definition: kernel_types.h:691
@ PRIMITIVE_ALL
Definition: kernel_types.h:702
@ PRIMITIVE_MOTION_TRIANGLE
Definition: kernel_types.h:687
@ PRIMITIVE_CURVE_RIBBON
Definition: kernel_types.h:690
@ PRIMITIVE_MOTION_CURVE_THICK
Definition: kernel_types.h:689
@ PRIMITIVE_CURVE_THICK
Definition: kernel_types.h:688
@ PRIMITIVE_ALL_TRIANGLE
Definition: kernel_types.h:697
@ PRIMITIVE_TRIANGLE
Definition: kernel_types.h:686
#define OBJECT_NONE
Definition: kernel_types.h:59
@ SHADER_MASK
Definition: kernel_types.h:593
static float P(float k)
Definition: math_interp.c:41
ccl_device_inline int __float_as_int(float f)
Definition: util_math.h:202