Blender  V2.93
bvh_nodes.h
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2016, Blender Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // TODO(sergey): Look into avoid use of full Transform and use 3x3 matrix and
18 // 3-vector which might be faster.
20  int node_addr,
21  int child)
22 {
23  Transform space;
24  const int child_addr = node_addr + child * 3;
25  space.x = kernel_tex_fetch(__bvh_nodes, child_addr + 1);
26  space.y = kernel_tex_fetch(__bvh_nodes, child_addr + 2);
27  space.z = kernel_tex_fetch(__bvh_nodes, child_addr + 3);
28  return space;
29 }
30 
32  const float3 P,
33  const float3 idir,
34  const float t,
35  const int node_addr,
36  const uint visibility,
37  float dist[2])
38 {
39 
40  /* fetch node data */
41 #ifdef __VISIBILITY_FLAG__
42  float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
43 #endif
44  float4 node0 = kernel_tex_fetch(__bvh_nodes, node_addr + 1);
45  float4 node1 = kernel_tex_fetch(__bvh_nodes, node_addr + 2);
46  float4 node2 = kernel_tex_fetch(__bvh_nodes, node_addr + 3);
47 
48  /* intersect ray against child nodes */
49  float c0lox = (node0.x - P.x) * idir.x;
50  float c0hix = (node0.z - P.x) * idir.x;
51  float c0loy = (node1.x - P.y) * idir.y;
52  float c0hiy = (node1.z - P.y) * idir.y;
53  float c0loz = (node2.x - P.z) * idir.z;
54  float c0hiz = (node2.z - P.z) * idir.z;
55  float c0min = max4(0.0f, min(c0lox, c0hix), min(c0loy, c0hiy), min(c0loz, c0hiz));
56  float c0max = min4(t, max(c0lox, c0hix), max(c0loy, c0hiy), max(c0loz, c0hiz));
57 
58  float c1lox = (node0.y - P.x) * idir.x;
59  float c1hix = (node0.w - P.x) * idir.x;
60  float c1loy = (node1.y - P.y) * idir.y;
61  float c1hiy = (node1.w - P.y) * idir.y;
62  float c1loz = (node2.y - P.z) * idir.z;
63  float c1hiz = (node2.w - P.z) * idir.z;
64  float c1min = max4(0.0f, min(c1lox, c1hix), min(c1loy, c1hiy), min(c1loz, c1hiz));
65  float c1max = min4(t, max(c1lox, c1hix), max(c1loy, c1hiy), max(c1loz, c1hiz));
66 
67  dist[0] = c0min;
68  dist[1] = c1min;
69 
70 #ifdef __VISIBILITY_FLAG__
71  /* this visibility test gives a 5% performance hit, how to solve? */
72  return (((c0max >= c0min) && (__float_as_uint(cnodes.x) & visibility)) ? 1 : 0) |
73  (((c1max >= c1min) && (__float_as_uint(cnodes.y) & visibility)) ? 2 : 0);
74 #else
75  return ((c0max >= c0min) ? 1 : 0) | ((c1max >= c1min) ? 2 : 0);
76 #endif
77 }
78 
80  const float3 P,
81  const float3 dir,
82  const float t,
83  int node_addr,
84  int child,
85  float dist[2])
86 {
87  Transform space = bvh_unaligned_node_fetch_space(kg, node_addr, child);
88  float3 aligned_dir = transform_direction(&space, dir);
89  float3 aligned_P = transform_point(&space, P);
90  float3 nrdir = -bvh_inverse_direction(aligned_dir);
91  float3 lower_xyz = aligned_P * nrdir;
92  float3 upper_xyz = lower_xyz - nrdir;
93  const float near_x = min(lower_xyz.x, upper_xyz.x);
94  const float near_y = min(lower_xyz.y, upper_xyz.y);
95  const float near_z = min(lower_xyz.z, upper_xyz.z);
96  const float far_x = max(lower_xyz.x, upper_xyz.x);
97  const float far_y = max(lower_xyz.y, upper_xyz.y);
98  const float far_z = max(lower_xyz.z, upper_xyz.z);
99  const float tnear = max4(0.0f, near_x, near_y, near_z);
100  const float tfar = min4(t, far_x, far_y, far_z);
101  *dist = tnear;
102  return tnear <= tfar;
103 }
104 
106  const float3 P,
107  const float3 dir,
108  const float3 idir,
109  const float t,
110  const int node_addr,
111  const uint visibility,
112  float dist[2])
113 {
114  int mask = 0;
115 #ifdef __VISIBILITY_FLAG__
116  float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
117 #endif
118  if (bvh_unaligned_node_intersect_child(kg, P, dir, t, node_addr, 0, &dist[0])) {
119 #ifdef __VISIBILITY_FLAG__
120  if ((__float_as_uint(cnodes.x) & visibility))
121 #endif
122  {
123  mask |= 1;
124  }
125  }
126  if (bvh_unaligned_node_intersect_child(kg, P, dir, t, node_addr, 1, &dist[1])) {
127 #ifdef __VISIBILITY_FLAG__
128  if ((__float_as_uint(cnodes.y) & visibility))
129 #endif
130  {
131  mask |= 2;
132  }
133  }
134  return mask;
135 }
136 
138  const float3 P,
139  const float3 dir,
140  const float3 idir,
141  const float t,
142  const int node_addr,
143  const uint visibility,
144  float dist[2])
145 {
146  float4 node = kernel_tex_fetch(__bvh_nodes, node_addr);
148  return bvh_unaligned_node_intersect(kg, P, dir, idir, t, node_addr, visibility, dist);
149  }
150  else {
151  return bvh_aligned_node_intersect(kg, P, idir, t, node_addr, visibility, dist);
152  }
153 }
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 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_forceinline int bvh_aligned_node_intersect(KernelGlobals *kg, const float3 P, const float3 idir, const float t, const int node_addr, const uint visibility, float dist[2])
Definition: bvh_nodes.h:31
ccl_device_forceinline bool bvh_unaligned_node_intersect_child(KernelGlobals *kg, const float3 P, const float3 dir, const float t, int node_addr, int child, float dist[2])
Definition: bvh_nodes.h:79
ccl_device_forceinline int bvh_node_intersect(KernelGlobals *kg, const float3 P, const float3 dir, const float3 idir, const float t, const int node_addr, const uint visibility, float dist[2])
Definition: bvh_nodes.h:137
ccl_device_forceinline int bvh_unaligned_node_intersect(KernelGlobals *kg, const float3 P, const float3 dir, const float3 idir, const float t, const int node_addr, const uint visibility, float dist[2])
Definition: bvh_nodes.h:105
ccl_device_forceinline Transform bvh_unaligned_node_fetch_space(KernelGlobals *kg, int node_addr, int child)
Definition: bvh_nodes.h:19
OperationNode * node
ccl_device_inline float3 bvh_inverse_direction(float3 dir)
Definition: geom_object.h:413
#define kernel_tex_fetch(tex, index)
#define ccl_device_forceinline
@ PATH_RAY_NODE_UNALIGNED
Definition: kernel_types.h:293
static float P(float k)
Definition: math_interp.c:41
#define min(a, b)
Definition: sort.c:51
float z
Definition: sky_float3.h:35
float y
Definition: sky_float3.h:35
float x
Definition: sky_float3.h:35
float max
ccl_device_inline uint __float_as_uint(float f)
Definition: util_math.h:222
ccl_device_inline T min4(const T &a, const T &b, const T &c, const T &d)
Definition: util_math.h:148
ccl_device_inline T max4(const T &a, const T &b, const T &c, const T &d)
Definition: util_math.h:153
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
ccl_device_inline float3 transform_direction(const Transform *t, const float3 a)
ccl_device_inline float3 transform_point(const Transform *t, const float3 a)