@@ -327,4 +327,115 @@ void intersect_main()
327
327
328
328
void occluded_main()
329
329
{
330
+ uint index = gl_GlobalInvocationID.x;
331
+ uint local_index = gl_LocalInvocationID.x;
332
+
333
+ // Handle only working subset
334
+ if (index >= Numrays) return;
335
+
336
+ ray myRay = Rays[index];
337
+ vec3 invDir = safe_invdir(myRay.d.xyz);
338
+ vec3 oxInvDir = -myRay.o.xyz * invDir;
339
+
340
+ // Intersection parametric distance
341
+ float closest_t = myRay.o.w;
342
+
343
+ // Current node address
344
+ uint addr = 0;
345
+ // Current closest address
346
+ uint closest_addr = INVALID_ADDR;
347
+
348
+ uint stack_bottom = STACK_SIZE * index;
349
+ uint sptr = stack_bottom;
350
+ uint lds_stack_bottom = local_index * LDS_STACK_SIZE;
351
+ uint lds_sptr = lds_stack_bottom;
352
+
353
+ lds_stack[lds_sptr++] = INVALID_ADDR;
354
+
355
+ while (addr != INVALID_ADDR)
356
+ {
357
+ BvhNode node = Nodes[addr];
358
+
359
+ if (INTERNAL_NODE(node))
360
+ {
361
+ vec2 s0 = fast_intersect_aabb(
362
+ node.aabb_left_min_or_v0,
363
+ node.aabb_left_max_or_v1,
364
+ invDir, oxInvDir, closest_t);
365
+ vec2 s1 = fast_intersect_aabb(
366
+ node.aabb_right_min_or_v2,
367
+ node.aabb_right_max,
368
+ invDir, oxInvDir, closest_t);
369
+
370
+ bool traverse_c0 = (s0.x <= s0.y);
371
+ bool traverse_c1 = (s1.x <= s1.y);
372
+ bool c1first = traverse_c1 && (s0.x > s1.x);
373
+
374
+ if (traverse_c0 || traverse_c1)
375
+ {
376
+ uint deferred = INVALID_ADDR;
377
+
378
+ if (c1first || !traverse_c0)
379
+ {
380
+ addr = node.addr_right;
381
+ deferred = node.addr_left;
382
+ }
383
+ else
384
+ {
385
+ addr = node.addr_left;
386
+ deferred = node.addr_right;
387
+ }
388
+
389
+ if (traverse_c0 && traverse_c1)
390
+ {
391
+ if (lds_sptr - lds_stack_bottom >= LDS_STACK_SIZE)
392
+ {
393
+ for (int i = 1; i < LDS_STACK_SIZE; ++i)
394
+ {
395
+ Stack[sptr + i] = lds_stack[lds_stack_bottom + i];
396
+ }
397
+
398
+ sptr += LDS_STACK_SIZE;
399
+ lds_sptr = lds_stack_bottom + 1;
400
+ }
401
+
402
+ lds_stack[lds_sptr++] = deferred;
403
+ }
404
+
405
+ continue;
406
+ }
407
+ }
408
+ else
409
+ {
410
+ float t = fast_intersect_triangle(
411
+ myRay,
412
+ node.aabb_left_min_or_v0,
413
+ node.aabb_left_max_or_v1,
414
+ node.aabb_right_min_or_v2,
415
+ closest_t);
416
+
417
+ if (t < closest_t)
418
+ {
419
+ Hitresults[index] = HIT_MARKER;
420
+ return;
421
+ }
422
+ }
423
+
424
+ addr = lds_stack[--lds_sptr];
425
+
426
+ if (addr == INVALID_ADDR && sptr > stack_bottom)
427
+ {
428
+ sptr -= LDS_STACK_SIZE;
429
+ for (int i = 1; i < LDS_STACK_SIZE; ++i)
430
+ {
431
+ lds_stack[lds_stack_bottom + i] = Stack[sptr + i];
432
+ }
433
+
434
+ lds_sptr = lds_stack_bottom + LDS_STACK_SIZE - 1;
435
+ addr = lds_stack[lds_sptr];
436
+ }
437
+ }
438
+
439
+ // Finished traversal, but no intersection found
440
+ Hitresults[index] = MISS_MARKER;
330
441
}
0 commit comments