Blender  V3.3
nodes.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation. */
3 
4 // TODO(sergey): Look into avoid use of full Transform and use 3x3 matrix and
5 // 3-vector which might be faster.
7  int node_addr,
8  int child)
9 {
10  Transform space;
11  const int child_addr = node_addr + child * 3;
12  space.x = kernel_data_fetch(bvh_nodes, child_addr + 1);
13  space.y = kernel_data_fetch(bvh_nodes, child_addr + 2);
14  space.z = kernel_data_fetch(bvh_nodes, child_addr + 3);
15  return space;
16 }
17 
19  const float3 P,
20  const float3 idir,
21  const float tmin,
22  const float tmax,
23  const int node_addr,
24  const uint visibility,
25  float dist[2])
26 {
27 
28  /* fetch node data */
29 #ifdef __VISIBILITY_FLAG__
30  float4 cnodes = kernel_data_fetch(bvh_nodes, node_addr + 0);
31 #endif
32  float4 node0 = kernel_data_fetch(bvh_nodes, node_addr + 1);
33  float4 node1 = kernel_data_fetch(bvh_nodes, node_addr + 2);
34  float4 node2 = kernel_data_fetch(bvh_nodes, node_addr + 3);
35 
36  /* intersect ray against child nodes */
37  float c0lox = (node0.x - P.x) * idir.x;
38  float c0hix = (node0.z - P.x) * idir.x;
39  float c0loy = (node1.x - P.y) * idir.y;
40  float c0hiy = (node1.z - P.y) * idir.y;
41  float c0loz = (node2.x - P.z) * idir.z;
42  float c0hiz = (node2.z - P.z) * idir.z;
43  float c0min = max4(tmin, min(c0lox, c0hix), min(c0loy, c0hiy), min(c0loz, c0hiz));
44  float c0max = min4(tmax, max(c0lox, c0hix), max(c0loy, c0hiy), max(c0loz, c0hiz));
45 
46  float c1lox = (node0.y - P.x) * idir.x;
47  float c1hix = (node0.w - P.x) * idir.x;
48  float c1loy = (node1.y - P.y) * idir.y;
49  float c1hiy = (node1.w - P.y) * idir.y;
50  float c1loz = (node2.y - P.z) * idir.z;
51  float c1hiz = (node2.w - P.z) * idir.z;
52  float c1min = max4(tmin, min(c1lox, c1hix), min(c1loy, c1hiy), min(c1loz, c1hiz));
53  float c1max = min4(tmax, max(c1lox, c1hix), max(c1loy, c1hiy), max(c1loz, c1hiz));
54 
55  dist[0] = c0min;
56  dist[1] = c1min;
57 
58 #ifdef __VISIBILITY_FLAG__
59  /* this visibility test gives a 5% performance hit, how to solve? */
60  return (((c0max >= c0min) && (__float_as_uint(cnodes.x) & visibility)) ? 1 : 0) |
61  (((c1max >= c1min) && (__float_as_uint(cnodes.y) & visibility)) ? 2 : 0);
62 #else
63  return ((c0max >= c0min) ? 1 : 0) | ((c1max >= c1min) ? 2 : 0);
64 #endif
65 }
66 
68  const float3 P,
69  const float3 dir,
70  const float tmin,
71  const float tmax,
72  int node_addr,
73  int child,
74  float dist[2])
75 {
76  Transform space = bvh_unaligned_node_fetch_space(kg, node_addr, child);
77  float3 aligned_dir = transform_direction(&space, dir);
78  float3 aligned_P = transform_point(&space, P);
79  float3 nrdir = -bvh_inverse_direction(aligned_dir);
80  float3 lower_xyz = aligned_P * nrdir;
81  float3 upper_xyz = lower_xyz - nrdir;
82  const float near_x = min(lower_xyz.x, upper_xyz.x);
83  const float near_y = min(lower_xyz.y, upper_xyz.y);
84  const float near_z = min(lower_xyz.z, upper_xyz.z);
85  const float far_x = max(lower_xyz.x, upper_xyz.x);
86  const float far_y = max(lower_xyz.y, upper_xyz.y);
87  const float far_z = max(lower_xyz.z, upper_xyz.z);
88  const float tnear = max4(tmin, near_x, near_y, near_z);
89  const float tfar = min4(tmax, far_x, far_y, far_z);
90  *dist = tnear;
91  return tnear <= tfar;
92 }
93 
95  const float3 P,
96  const float3 dir,
97  const float3 idir,
98  const float tmin,
99  const float tmax,
100  const int node_addr,
101  const uint visibility,
102  float dist[2])
103 {
104  int mask = 0;
105 #ifdef __VISIBILITY_FLAG__
106  float4 cnodes = kernel_data_fetch(bvh_nodes, node_addr + 0);
107 #endif
108  if (bvh_unaligned_node_intersect_child(kg, P, dir, tmin, tmax, node_addr, 0, &dist[0])) {
109 #ifdef __VISIBILITY_FLAG__
110  if ((__float_as_uint(cnodes.x) & visibility))
111 #endif
112  {
113  mask |= 1;
114  }
115  }
116  if (bvh_unaligned_node_intersect_child(kg, P, dir, tmin, tmax, node_addr, 1, &dist[1])) {
117 #ifdef __VISIBILITY_FLAG__
118  if ((__float_as_uint(cnodes.y) & visibility))
119 #endif
120  {
121  mask |= 2;
122  }
123  }
124  return mask;
125 }
126 
128  const float3 P,
129  const float3 dir,
130  const float3 idir,
131  const float tmin,
132  const float tmax,
133  const int node_addr,
134  const uint visibility,
135  float dist[2])
136 {
137  float4 node = kernel_data_fetch(bvh_nodes, node_addr);
139  return bvh_unaligned_node_intersect(kg, P, dir, idir, tmin, tmax, node_addr, visibility, dist);
140  }
141  else {
142  return bvh_aligned_node_intersect(kg, P, idir, tmin, tmax, node_addr, visibility, dist);
143  }
144 }
unsigned int uint
Definition: BLI_sys_types.h:67
float float4[4]
#define ccl_device_forceinline
Definition: cuda/compat.h:35
OperationNode * node
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
ccl_device_inline float3 transform_direction(ccl_private const Transform *t, const float3 a)
CCL_NAMESPACE_END CCL_NAMESPACE_BEGIN ccl_device_inline float3 transform_point(ccl_private const Transform *t, const float3 a)
ccl_device_inline float3 bvh_inverse_direction(float3 dir)
@ PATH_RAY_NODE_UNALIGNED
Definition: kernel/types.h:211
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
static float P(float k)
Definition: math_interp.c:25
ccl_device_forceinline int bvh_aligned_node_intersect(KernelGlobals kg, const float3 P, const float3 idir, const float tmin, const float tmax, const int node_addr, const uint visibility, float dist[2])
Definition: nodes.h:18
ccl_device_forceinline int bvh_unaligned_node_intersect(KernelGlobals kg, const float3 P, const float3 dir, const float3 idir, const float tmin, const float tmax, const int node_addr, const uint visibility, float dist[2])
Definition: nodes.h:94
ccl_device_forceinline bool bvh_unaligned_node_intersect_child(KernelGlobals kg, const float3 P, const float3 dir, const float tmin, const float tmax, int node_addr, int child, float dist[2])
Definition: nodes.h:67
ccl_device_forceinline int bvh_node_intersect(KernelGlobals kg, const float3 P, const float3 dir, const float3 idir, const float tmin, const float tmax, const int node_addr, const uint visibility, float dist[2])
Definition: nodes.h:127
ccl_device_forceinline Transform bvh_unaligned_node_fetch_space(KernelGlobals kg, int node_addr, int child)
Definition: nodes.h:6
#define min(a, b)
Definition: sort.c:35
float z
float y
float x
float max
ccl_device_inline uint __float_as_uint(float f)
Definition: util/math.h:263
ccl_device_inline T min4(const T &a, const T &b, const T &c, const T &d)
Definition: util/math.h:188
ccl_device_inline T max4(const T &a, const T &b, const T &c, const T &d)
Definition: util/math.h:193