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