Blender V5.0
kernel/device/hiprt/bvh.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#pragma once
6
8
10
12{
13 return isfinite_safe(ray->P.x) && isfinite_safe(ray->D.x) && len_squared(ray->D) != 0.0f;
14}
15
17 const ccl_private Ray *ray,
18 const uint visibility,
20{
21 isect->t = ray->tmax;
22 isect->u = 0.0f;
23 isect->v = 0.0f;
24 isect->prim = PRIM_NONE;
25 isect->object = OBJECT_NONE;
26 isect->type = PRIMITIVE_NONE;
27 if (!scene_intersect_valid(ray)) {
28 isect->t = ray->tmax;
29 isect->type = PRIMITIVE_NONE;
30 return false;
31 }
32
33 if (kernel_data.device_bvh == 0) {
34 return false;
35 }
36
37 hiprtRay ray_hip;
38 SET_HIPRT_RAY(ray_hip, ray)
39
40 RayPayload payload;
41 payload.self = ray->self;
42 payload.kg = kg;
43 payload.visibility = visibility;
44 payload.prim_type = PRIMITIVE_NONE;
45 payload.ray_time = ray->time;
46
47 hiprtHit hit;
48
49 GET_TRAVERSAL_STACK()
50
51 if (visibility & PATH_RAY_SHADOW_OPAQUE) {
52 GET_TRAVERSAL_ANY_HIT(table_closest_intersect, 0, ray->time)
53 hit = traversal.getNextHit();
54 }
55 else {
56 GET_TRAVERSAL_CLOSEST_HIT(table_closest_intersect, 0, ray->time)
57 hit = traversal.getNextHit();
58 }
59
60 if (hit.hasHit()) {
61 set_intersect_point(kg, hit, isect);
62 if (isect->type > 1) { /* Should be applied only for curves. */
63 isect->type = payload.prim_type;
64 isect->prim = hit.primID;
65 }
66 return true;
67 }
68
69 return false;
70}
71
73 const ccl_private Ray *ray,
74 const uint visibility)
75{
76 Intersection isect;
77 return scene_intersect(kg, ray, visibility, &isect);
78}
79
80#ifdef __BVH_LOCAL__
81template<bool single_hit = false>
82ccl_device_intersect bool scene_intersect_local(KernelGlobals kg,
83 const ccl_private Ray *ray,
84 ccl_private LocalIntersection *local_isect,
85 const int local_object,
86 ccl_private uint *lcg_state,
87 const int max_hits)
88{
89 if (local_isect != nullptr) {
90 local_isect->num_hits = 0;
91 }
92
93 if (!scene_intersect_valid(ray)) {
94 return false;
95 }
96
97 const int primitive_type = kernel_data_fetch(objects, local_object).primitive_type;
98 if (!(primitive_type & PRIMITIVE_TRIANGLE)) {
99 /* Local intersection functions are only considering triangle and motion triangle primitives.
100 * If the local intersection is requested from other primitives (curve or point cloud) perform
101 * an early return to avoid tree traversal with no primitive intersection. */
102 return false;
103 }
104
105 float3 P = ray->P;
106 float3 dir = bvh_clamp_direction(ray->D);
107 float3 idir = bvh_inverse_direction(dir);
108
109 const int object_flag = kernel_data_fetch(object_flag, local_object);
110 if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
111# if BVH_FEATURE(BVH_MOTION)
112 bvh_instance_motion_push(kg, local_object, ray, &P, &dir, &idir);
113# else
114 bvh_instance_push(kg, local_object, ray, &P, &dir, &idir);
115# endif
116 }
117
118 hiprtRay ray_hip;
119 ray_hip.origin = P;
120 ray_hip.direction = dir;
121 ray_hip.maxT = ray->tmax;
122 ray_hip.minT = ray->tmin;
123
124 LocalPayload payload = {0};
125 payload.kg = kg;
126 payload.self = ray->self;
127 payload.ray_time = ray->time;
128 payload.local_object = local_object;
129 payload.max_hits = max_hits;
130 payload.lcg_state = lcg_state;
131 payload.local_isect = local_isect;
132
133 GET_TRAVERSAL_STACK()
134
135 void *local_geom = (void *)(kernel_data_fetch(blas_ptr, local_object));
136
137 hiprtHit hit;
138 if (primitive_type == PRIMITIVE_MOTION_TRIANGLE) {
139 /* Motion triangle BVH uses custom primitives which requires custom traversal. */
140 hiprtGeomCustomTraversalAnyHitCustomStack<Stack> traversal((hiprtGeometry)local_geom,
141 ray_hip,
142 stack,
143 hiprtTraversalHintDefault,
144 &payload,
145 kernel_params.table_local_intersect,
146 2);
147 hit = traversal.getNextHit();
148 }
149 else {
150 hiprtGeomTraversalAnyHitCustomStack<Stack> traversal((hiprtGeometry)local_geom,
151 ray_hip,
152 stack,
153 hiprtTraversalHintDefault,
154 &payload,
155 kernel_params.table_local_intersect,
156 2);
157 hit = traversal.getNextHit();
158 }
159
160 return hit.hasHit();
161}
162#endif /*__BVH_LOCAL__ */
163
164#ifdef __SHADOW_RECORD_ALL__
165ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals kg,
167 const ccl_private Ray *ray,
168 const uint visibility,
169 const uint max_transparent_hits,
170 ccl_private uint *num_recorded_hits,
171 ccl_private float *throughput)
172{
173 *throughput = 1.0f;
174 *num_recorded_hits = 0;
175
176 if (!scene_intersect_valid(ray)) {
177 return false;
178 }
179
180 hiprtRay ray_hip;
181 SET_HIPRT_RAY(ray_hip, ray)
182
183 ShadowPayload payload;
184 payload.kg = kg;
185 payload.self = ray->self;
186 payload.visibility = visibility;
187 payload.prim_type = PRIMITIVE_NONE;
188 payload.ray_time = ray->time;
189 payload.in_state = state;
190 payload.max_transparent_hits = max_transparent_hits;
191 payload.num_transparent_hits = 0;
192 payload.r_num_recorded_hits = num_recorded_hits;
193 payload.r_throughput = throughput;
194
195 GET_TRAVERSAL_STACK()
196 GET_TRAVERSAL_ANY_HIT(table_shadow_intersect, 1, ray->time)
197
198 const hiprtHit hit = traversal.getNextHit();
199 return hit.hasHit();
200}
201#endif /* __SHADOW_RECORD_ALL__ */
202
203#ifdef __VOLUME__
204ccl_device_intersect bool scene_intersect_volume(KernelGlobals kg,
205 const ccl_private Ray *ray,
207 const uint visibility)
208{
209 isect->t = ray->tmax;
210 isect->u = 0.0f;
211 isect->v = 0.0f;
212 isect->prim = PRIM_NONE;
213 isect->object = OBJECT_NONE;
214 isect->type = PRIMITIVE_NONE;
215
216 if (!scene_intersect_valid(ray)) {
217 return false;
218 }
219
220 hiprtRay ray_hip;
221
222 SET_HIPRT_RAY(ray_hip, ray)
223
224 RayPayload payload;
225 payload.self = ray->self;
226 payload.kg = kg;
227 payload.visibility = visibility;
228 payload.prim_type = PRIMITIVE_NONE;
229 payload.ray_time = ray->time;
230
231 GET_TRAVERSAL_STACK()
232
233 GET_TRAVERSAL_CLOSEST_HIT(table_volume_intersect, 3, ray->time)
234 const hiprtHit hit = traversal.getNextHit();
235 if (hit.hasHit()) {
236 set_intersect_point(kg, hit, isect);
237 if (isect->type > 1) { /* Should be applied only for curves. */
238 isect->type = payload.prim_type;
239 isect->prim = hit.primID;
240 }
241 return true;
242 }
243
244 return false;
245}
246#endif /* __VOLUME__ */
247
unsigned int uint
#define kernel_data
#define kernel_data_fetch(name, index)
#define PRIM_NONE
#define OBJECT_NONE
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define CCL_NAMESPACE_END
#define ccl_device_intersect
CCL_NAMESPACE_BEGIN ccl_device_inline bool scene_intersect_valid(const ccl_private Ray *ray)
ccl_device_intersect bool scene_intersect(KernelGlobals kg, const ccl_private Ray *ray, const uint visibility, ccl_private Intersection *isect)
ccl_device_intersect bool scene_intersect_shadow(KernelGlobals kg, const ccl_private Ray *ray, const uint visibility)
ccl_device_inline void bvh_instance_push(KernelGlobals kg, const int object, const ccl_private Ray *ray, ccl_private float3 *P, ccl_private float3 *dir, ccl_private float3 *idir)
ccl_device_inline float3 bvh_inverse_direction(const float3 dir)
ccl_device_inline float3 bvh_clamp_direction(const float3 dir)
@ PRIMITIVE_MOTION_TRIANGLE
@ PRIMITIVE_NONE
@ PRIMITIVE_TRIANGLE
@ PATH_RAY_SHADOW_OPAQUE
@ SD_OBJECT_TRANSFORM_APPLIED
ccl_device_inline bool isfinite_safe(const float f)
Definition math_base.h:348
ccl_device_inline float len_squared(const float2 a)
static ulong state[N]
IntegratorShadowStateCPU * IntegratorShadowState
Definition state.h:230