LZ-Opticks-NVIDIA OptiX 6->7 : Notes

PROGRESS : OptiXTest split in two, added Opticks/GGeo conversion

NEXT STEPS:

LONGTERM POSSIBILITY : Populate CSGFoundry model direct from Geant4 geometry ? [Disruptive]

Simon C Blyth, May 4, 2021

CSG : CSGFoundry/CSGSolid/CSGPrim/CSGNode/csg_intersect_tree/..

All solids+constituents created via Foundry (ref by index)

CSGFoundry::upload
all solids in geometry -> only four GPU allocations : d_prim, d_node, d_plan, d_itra

https://github.com/simoncblyth/CSG/blob/main/CSGFoundry.h https://github.com/simoncblyth/CSG/blob/main/qat4.h

OptiX 7 + pre-7 intersecting same CSGFoundry geometry

OptiX7Test.cu

150 extern "C" __global__ void __intersection__is()
151 {
152 HitGroupData* hg  = (HitGroupData*)optixGetSbtDataPointer();
153 int numNode = hg->numNode ;
154 int nodeOffset = hg->nodeOffset ;
155
156 const CSGNode* node = params.node + nodeOffset ;
157 const float4* plan = params.plan ;
158 const qat4*   itra = params.itra ;
159
160 const float  t_min = optixGetRayTmin() ;
161 const float3 ray_origin = optixGetObjectRayOrigin();
162 const float3 ray_direction = optixGetObjectRayDirection();
163
164 float4 isect ;
165 if(intersect_prim(isect, numNode, node, plan, itra,
                     t_min , ray_origin, ray_direction ))
166 {
...
175     optixReportIntersection( isect.w, hitKind, a0, a1, a2, a3 );
176 }
177 }

Minimize code split : 7, pre-7, CPU testing : same intersect_prim

CSGOptiXGGeo : loads Opticks/GGeo, converts to CSG and renders

 06 #include "CSGFoundry.h"
 07 #include "CSGOptiX.h"
 09 #include "Converter.h"
 10
 11 int main(int argc, char** argv)
 12 {
 13     int repeatIdx = argc > 1 ? atoi(argv[1]) : 0 ;
 ..
 19     OPTICKS_LOG(argc, argv);
 20     Opticks ok(argc, argv);
 21     ok.configure();
 22
 24     GGeo* ggeo = GGeo::Load(&ok); 
 26
 27     CSGFoundry foundry ;
 28     Converter conv(&foundry, ggeo, dump) ;
 29     conv.convert(repeatIdx, primIdx, partIdxRel);
 30
 31     CSGOptiX cx(&foundry);
 34     foundry.upload();   // uploads nodes, planes, transforms
 ..
 52     cx.setCE(ce, tmin, tmax);
 53     cx.render( tspec );
 55     return 0 ;
 56 }

CSGOptiXGGeo_0

CSGOptiXGGeo_1

CSGOptiXGGeo_2

Converter debugging

CSGOptiXGGeo_3

CSGOptiXGGeo_4

CSGOptiXGGeo_5

CSGOptiXGGeo_6

CSGOptiXGGeo_7

CSGOptiXGGeo_8

One JUNO solid (fastener) -> blank

CSGOptiXGGeo_9

Proof that relative trans not applied

"Extra" Background Slides Follow

Two-Level Hierarchy : Instance transforms (TLAS) over Geometry (BLAS)

OptiX supports multiple instance levels : IAS->IAS->GAS BUT: Simple two-level is faster : works in hardware RT Cores

AS
Acceleration Structure
TLAS (IAS)
4x4 transforms, refs to BLAS
BLAS (GAS)
triangles : vertices, indices
custom primitives : AABB
AABB
axis-aligned bounding box

SBT : Shader Binding Table

Flexibly binds together:

  1. geometry objects
  2. shader programs
  3. data for shader programs

Hidden in OptiX 1-6 APIs


Optimizing Geometry : Split BLAS to avoid overlapping bbox

/env/presentation/nvidia/optimize/split_blas_half.png

Optimization : deciding where to draw lines between:

  1. structure and solid (IAS and GAS)
  2. solids within GAS (bbox choice to minimize traversal intersection tests)

Where those lines are drawn defines the AS

https://developer.nvidia.com/blog/best-practices-using-nvidia-rtx-ray-tracing/


Optimizing Geometry : Merge BLAS when lots of overlaps

/env/presentation/nvidia/optimize/merge_blas_half.png

https://developer.nvidia.com/blog/best-practices-using-nvidia-rtx-ray-tracing/


Ray Intersection with Transformed Object -> Geometry Instancing

/env/presentation/instancing/ray_intersection_in_two_spaces_p308_shirley_ch13_half.png

Fig 13.5 "Realistic Ray Tracing", Peter Shirley

Advantages apply equally to acceleration structures

Equivalent Intersects -> same t

  1. ray with ellipsoid : M*p
  2. M-1 ray with sphere : p

Local Frame Advantages

  1. simpler intersect (sphere vs ellipsoid)
  2. closer to origin -> better precision

Geometry Instancing Advantages

Requirements


G4Boolean -> CUDA/OptiX Intersection Program Implementing CSG

Complete Binary Tree, pick between pairs of nearest intersects:

UNION tA < tB Enter B Exit B Miss B
Enter A ReturnA LoopA ReturnA
Exit A ReturnA ReturnB ReturnA
Miss A ReturnB ReturnB ReturnMiss
[1] Ray Tracing CSG Objects Using Single Hit Intersections, Andrew Kensler (2006)
with corrections by author of XRT Raytracer http://xrt.wikidot.com/doc:csg
[2] https://bitbucket.org/simoncblyth/opticks/src/tip/optixrap/cu/csg_intersect_boolean.h
Similar to binary expression tree evaluation using postorder traverse.

Constructive Solid Geometry (CSG) : Shapes defined "by construction"

Simple by construction definition, implicit geometry.

CSG expressions

3D Parametric Ray : ray(t) = r0 + t rDir

Ray Geometry Intersection

How to pick exactly ?


CSG : Which primitive intersect to pick ?

Classical Roth diagram approach

Computational requirements:

BUT : High performance on GPU requires:

Classical approach not appropriate on GPU


CSG Complete Binary Tree Serialization -> simplifies GPU side

Geant4 solid -> CSG binary tree (leaf primitives, non-leaf operators, 4x4 transforms on any node)

Serialize to complete binary tree buffer:

Height 3 complete binary tree with level order indices:

                                                   depth     elevation

                     1                               0           3

          10                   11                    1           2

     100       101        110        111             2           1

 1000 1001  1010 1011  1100 1101  1110  1111         3           0

postorder_next(i,elevation) = i & 1 ? i >> 1 : (i << elevation) + (1 << elevation) ; // from pattern of bits

Postorder tree traverse visits all nodes, starting from leftmost, such that children are visited prior to their parents.


Evaluative CSG intersection Pseudocode : recursion emulated

fullTree = PACK( 1 << height, 1 >> 1 )  // leftmost, parent_of_root(=0)
tranche.push(fullTree, ray.tmin)

while (!tranche.empty)         // stack of begin/end indices 
{
    begin, end, tmin <- tranche.pop  ; node <- begin ;
    while( node != end )                   // over tranche of postorder traversal 
    {
        elevation = height - TREE_DEPTH(node) ;
        if(is_primitive(node)){ isect <- intersect_primitive(node, tmin) ;  csg.push(isect) }
        else{
            i_left, i_right = csg.pop, csg.pop            // csg stack of intersect normals, t 
            l_state = CLASSIFY(i_left, ray.direction, tmin)
            r_state = CLASSIFY(i_right, ray.direction, tmin)
            action = LUT(operator(node), leftIsCloser)(l_state, r_state)

            if(      action is ReturnLeft/Right)     csg.push(i_left or i_right)
            else if( action is LoopLeft/Right)
            {
                left = 2*node ; right = 2*node + 1 ;
                endTranche = PACK( node,  end );
                leftTranche = PACK(  left << (elevation-1), right << (elevation-1) )
                rightTranche = PACK(  right << (elevation-1),  node  )
                loopTranche = action ? leftTranche : rightTranche

                tranche.push(endTranche, tmin)
                tranche.push(loopTranche, tminAdvanced )  // subtree re-traversal with changed tmin 
                break ; // to next tranche
            }
        }
        node <- postorder_next(node, elevation)         // bit twiddling postorder 
    }
}
isect = csg.pop();         // winning intersect  

https://bitbucket.org/simoncblyth/opticks/src/tip/optixrap/cu/csg_intersect_boolean.h


CSG Deep Tree : Positivize tree using De Morgan's laws

1st step to allow balancing : Positivize : remove CSG difference di operators

                                                     ...    ...

                                               un          cy

                                       un          cy

                               un          cy

                       un          cy

               un          cy

       di          cy

   cy      cy

                                                     ...    ...

                                               un          cy

                                       un          cy

                               un          cy

                       un          cy

               un          cy

       in          cy

   cy      !cy


CSG Examples