Warning, file /eic-opticks/CSGOptiX/CSGOptiX.cu was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 #include <optix.h>
0046
0047 #include "SRG.h"
0048 #include "scuda.h"
0049 #include "squad.h"
0050 #include "sqat4.h"
0051 #include "sphoton.h"
0052 #include "sphotonlite.h"
0053 #include "scerenkov.h"
0054 #include "sstate.h"
0055
0056 #ifndef PRODUCTION
0057 #include "stag.h"
0058 #include "sseq.h"
0059 #include "srec.h"
0060 #endif
0061
0062 #include "sevent.h"
0063 #include "sctx.h"
0064
0065
0066 #include <curand_kernel.h>
0067
0068 #include "qrng.h"
0069 #include "qsim.h"
0070
0071 #include "csg_intersect_leaf.h"
0072 #include "csg_intersect_node.h"
0073 #include "csg_intersect_tree.h"
0074
0075 #include "Binding.h"
0076 #include "Params.h"
0077 #include "CSGOptiXHelpers.h"
0078
0079 #include "scuda_pointer.h"
0080 #include "SOPTIX_getPRD.h"
0081
0082 extern "C" { __constant__ Params params ; }
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103 template<bool refine>
0104 static __forceinline__ __device__ void trace(
0105 OptixTraversableHandle handle,
0106 float3 ray_origin,
0107 float3 ray_direction,
0108 float tmin,
0109 float tmax,
0110 quad2* prd,
0111 unsigned visibilityMask,
0112 float refine_distance
0113 )
0114 {
0115 const float rayTime = 0.0f ;
0116 OptixRayFlags rayFlags = OPTIX_RAY_FLAG_DISABLE_ANYHIT ;
0117 const unsigned SBToffset = 0u ;
0118 const unsigned SBTstride = 1u ;
0119 const unsigned missSBTIndex = 0u ;
0120 uint32_t p0, p1 ;
0121 packPointer( prd, p0, p1 );
0122
0123 if(!refine)
0124 {
0125 optixTrace(
0126 handle,
0127 ray_origin,
0128 ray_direction,
0129 tmin,
0130 tmax,
0131 rayTime,
0132 visibilityMask,
0133 rayFlags,
0134 SBToffset,
0135 SBTstride,
0136 missSBTIndex,
0137 p0, p1
0138 );
0139 }
0140 else
0141 {
0142 optixTrace(
0143 handle,
0144 ray_origin,
0145 ray_direction,
0146 tmin,
0147 tmax,
0148 rayTime,
0149 visibilityMask,
0150 rayFlags,
0151 SBToffset,
0152 SBTstride,
0153 missSBTIndex,
0154 p0, p1
0155 );
0156
0157 float t_approx = 0.99f*prd->distance() ;
0158
0159
0160 if( t_approx > refine_distance )
0161 {
0162 float3 closer_ray_origin = ray_origin + t_approx*ray_direction ;
0163 optixTrace(
0164 handle,
0165 closer_ray_origin,
0166 ray_direction,
0167 tmin,
0168 tmax,
0169 rayTime,
0170 visibilityMask,
0171 rayFlags,
0172 SBToffset,
0173 SBTstride,
0174 missSBTIndex,
0175 p0, p1
0176 );
0177
0178 prd->distance_add( t_approx );
0179 }
0180 }
0181
0182 }
0183
0184
0185 #if defined(WITH_RENDER)
0186
0187 __forceinline__ __device__ uchar4 make_normal_pixel( const float3& normal, float depth )
0188 {
0189 return make_uchar4(
0190 static_cast<uint8_t>( clamp( normal.x, 0.0f, 1.0f ) *255.0f ),
0191 static_cast<uint8_t>( clamp( normal.y, 0.0f, 1.0f ) *255.0f ),
0192 static_cast<uint8_t>( clamp( normal.z, 0.0f, 1.0f ) *255.0f ),
0193 static_cast<uint8_t>( clamp( depth , 0.0f, 1.0f ) *255.0f )
0194 );
0195 }
0196
0197 __forceinline__ __device__ uchar4 make_zdepth_pixel( float depth )
0198 {
0199 return make_uchar4(
0200 static_cast<uint8_t>( clamp( depth , 0.0f, 1.0f ) *255.0f ),
0201 static_cast<uint8_t>( clamp( depth , 0.0f, 1.0f ) *255.0f ),
0202 static_cast<uint8_t>( clamp( depth , 0.0f, 1.0f ) *255.0f ),
0203 static_cast<uint8_t>( clamp( depth , 0.0f, 1.0f ) *255.0f )
0204 );
0205 }
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 static __forceinline__ __device__ void render( const uint3& idx, const uint3& dim, quad2* prd )
0219 {
0220
0221 #if defined(DEBUG_PIDX)
0222
0223 #endif
0224
0225 float2 d = 2.0f * make_float2(
0226 static_cast<float>(idx.x)/static_cast<float>(dim.x),
0227 static_cast<float>(idx.y)/static_cast<float>(dim.y)
0228 ) - 1.0f;
0229
0230
0231 const unsigned cameratype = params.cameratype ;
0232 const float3 dxyUV = d.x * params.U + params.V * ( params.traceyflip ? -d.y : d.y ) ;
0233 const float3 origin = cameratype == 0u ? params.eye : params.eye + dxyUV ;
0234 const float3 direction = cameratype == 0u ? normalize( dxyUV + params.W ) : normalize( params.W ) ;
0235
0236
0237 trace<false>(
0238 params.handle,
0239 origin,
0240 direction,
0241 params.tmin,
0242 params.tmax,
0243 prd,
0244 params.vizmask,
0245 params.PropagateRefineDistance
0246 );
0247
0248 #if defined(DEBUG_PIDX)
0249
0250 #endif
0251
0252
0253
0254
0255
0256 const float3* normal = prd->normal();
0257
0258 #if defined(DEBUG_PIDX)
0259
0260 #endif
0261
0262 float3 diddled_normal = normalize(*normal)*0.5f + 0.5f ;
0263
0264 float eye_z = -prd->distance()*dot(params.WNORM, direction) ;
0265 const float& A = params.ZPROJ.z ;
0266 const float& B = params.ZPROJ.w ;
0267 float zdepth = cameratype == 0u ? -(A + B/eye_z) : A*eye_z + B ;
0268
0269 if( prd->is_boundary_miss() ) zdepth = 0.999f ;
0270
0271
0272
0273
0274 unsigned index = idx.y * params.width + idx.x ;
0275
0276 if(params.pixels)
0277 {
0278 #if defined(DEBUG_PIDX)
0279
0280 #endif
0281 params.pixels[index] = params.rendertype == 0 ? make_normal_pixel( diddled_normal, zdepth ) : make_zdepth_pixel( zdepth ) ;
0282 }
0283 if(params.isect)
0284 {
0285 float3 position = origin + direction*prd->distance() ;
0286 params.isect[index] = make_float4( position.x, position.y, position.z, __uint_as_float(prd->identity())) ;
0287 }
0288
0289
0290 }
0291 #endif
0292
0293
0294 #if defined(WITH_SIMULATE)
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369 static __forceinline__ __device__ void simulate( const uint3& launch_idx, const uint3& dim, quad2* prd )
0370 {
0371 sevent* evt = params.evt ;
0372 if (launch_idx.x >= evt->num_seed) return;
0373
0374 unsigned idx = launch_idx.x ;
0375 unsigned genstep_idx = evt->seed[idx] ;
0376 const quad6& gs = evt->genstep[genstep_idx] ;
0377
0378
0379 unsigned long long photon_idx = params.photon_slot_offset + idx ;
0380
0381
0382
0383
0384
0385
0386 qsim* sim = params.sim ;
0387
0388 RNG rng ;
0389 sim->rng->init( rng, sim->evt->index, photon_idx );
0390
0391 sctx ctx = {} ;
0392 ctx.evt = evt ;
0393 ctx.prd = prd ;
0394
0395 ctx.idx = idx ;
0396 ctx.pidx = photon_idx ;
0397
0398 #if !defined(PRODUCTION) && defined(DEBUG_PIDX)
0399 ctx.pidx_debug = sim->base->pidx == photon_idx ;
0400 #endif
0401
0402 sim->generate_photon(ctx.p, rng, gs, photon_idx, genstep_idx );
0403
0404
0405
0406 const unsigned gentype = gs.q0.u.x;
0407 const bool carries_matline = CSGOptiX_GenstepCarriesMaterialLine(gentype);
0408 ctx.current_matline = carries_matline ? gs.q0.u.z : 0xFFFFFFFFu;
0409
0410 FlowAction command = FlowAction::Start;
0411 int bounce = 0 ;
0412 if(evt->record) ctx.point(bounce);
0413 while( bounce < evt->max_bounce && ctx.p.time < params.max_time )
0414 {
0415 float tmin = ( ctx.p.orient_boundary_flag & params.PropagateEpsilon0Mask ) ? params.tmin0 : params.tmin ;
0416
0417
0418 #if defined(SIMPHONY_ENABLE_SER)
0419 if (params.SerInterval > 0 && (bounce % params.SerInterval) == 0)
0420 {
0421 switch (params.SerHint)
0422 {
0423 case 0:
0424 optixReorder();
0425 break;
0426 case 1:
0427 optixReorder(bounce / params.SerInterval, 4);
0428 break;
0429 }
0430 }
0431 #endif
0432
0433 #ifdef SIMPHONY_RNG_REBUILD
0434 unsigned rng_p = ( rng.ctr.x << 2 ) | ( rng.STATE & 3u ) ;
0435 #endif
0436
0437
0438 switch(params.PropagateRefine)
0439 {
0440 case 0u: trace<false>( params.handle, ctx.p.pos, ctx.p.mom, tmin, params.tmax, prd, params.vizmask, params.PropagateRefineDistance ); break ;
0441 case 1u: trace<true>( params.handle, ctx.p.pos, ctx.p.mom, tmin, params.tmax, prd, params.vizmask, params.PropagateRefineDistance ); break ;
0442 }
0443
0444 #ifdef SIMPHONY_RNG_REBUILD
0445 sim->rng->init( rng, sim->evt->index, photon_idx );
0446 skipahead( (unsigned long long)( rng_p - ( ( rng.ctr.x << 2 ) | ( rng.STATE & 3u ) ) ), &rng ) ;
0447 #endif
0448
0449 if( prd->boundary() == 0xffffu ) break ;
0450
0451
0452
0453
0454
0455
0456
0457
0458 float3* normal = prd->normal();
0459 *normal = normalize(*normal);
0460
0461 #ifndef PRODUCTION
0462 ctx.trace(bounce);
0463 #endif
0464 command = sim->propagate(bounce, rng, ctx);
0465 bounce++;
0466 if(evt->record) ctx.point(bounce) ;
0467 if(command == FlowAction::Break) break;
0468 }
0469 #ifndef PRODUCTION
0470 ctx.end();
0471 #endif
0472
0473
0474 if( evt->photon )
0475 {
0476 evt->photon[idx] = ctx.p ;
0477 }
0478
0479 if( evt->photonlite )
0480 {
0481 sphotonlite l ;
0482 l.init( ctx.p.identity, ctx.p.time, ctx.p.flagmask );
0483 l.set_lpos(prd->lposcost(), prd->lposfphi() );
0484 evt->photonlite[idx] = l ;
0485 }
0486
0487
0488
0489 }
0490
0491 #endif
0492
0493
0494
0495 #if defined(WITH_SIMTRACE)
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522 static __forceinline__ __device__ void simtrace( const uint3& launch_idx, const uint3& dim, quad2* prd )
0523 {
0524 unsigned idx = launch_idx.x ;
0525 sevent* evt = params.evt ;
0526 if (idx >= evt->num_simtrace) return;
0527
0528 unsigned genstep_idx = evt->seed[idx] ;
0529 unsigned photon_idx = params.photon_slot_offset + idx ;
0530
0531
0532 #if defined(DEBUG_PIDX)
0533 if(photon_idx == 0) printf("//CSGOptiX.cu : simtrace idx %d photon_idx %d genstep_idx %d evt->num_simtrace %ld \n", idx, photon_idx, genstep_idx, evt->num_simtrace );
0534 #endif
0535
0536 const quad6& gs = evt->genstep[genstep_idx] ;
0537
0538 qsim* sim = params.sim ;
0539 RNG rng ;
0540 sim->rng->init(rng, 0, photon_idx) ;
0541
0542 quad4 p ;
0543 sim->generate_photon_simtrace(p, rng, gs, photon_idx, genstep_idx );
0544
0545
0546
0547 const float3& pos = (const float3&)p.q0.f ;
0548 const float3& mom = (const float3&)p.q1.f ;
0549
0550
0551 #if defined(DEBUG_PIDX)
0552 if(photon_idx == 0) printf("//CSGOptiX.cu : simtrace idx %d pos.xyz %7.3f,%7.3f,%7.3f mom.xyz %7.3f,%7.3f,%7.3f \n", idx, pos.x, pos.y, pos.z, mom.x, mom.y, mom.z );
0553 #endif
0554
0555 switch(params.PropagateRefine)
0556 {
0557 case 0u: trace<false>( params.handle, pos, mom, params.tmin, params.tmax, prd, params.vizmask, params.PropagateRefineDistance ); break ;
0558 case 1u: trace<true>( params.handle, pos, mom, params.tmin, params.tmax, prd, params.vizmask, params.PropagateRefineDistance ); break ;
0559 }
0560
0561 evt->add_simtrace( idx, p, prd, params.tmin );
0562
0563 }
0564 #endif
0565
0566
0567
0568
0569
0570 extern "C" __global__ void __raygen__rg_dummy()
0571 {
0572 }
0573
0574 extern "C" __global__ void __raygen__rg()
0575 {
0576 const uint3 idx = optixGetLaunchIndex();
0577 const uint3 dim = optixGetLaunchDimensions();
0578
0579
0580
0581
0582 quad2 prd ;
0583 prd.zero();
0584
0585
0586 switch( params.raygenmode )
0587 {
0588
0589 #ifdef WITH_SIMULATE
0590 case SRG_SIMULATE: simulate( idx, dim, &prd ) ; break ;
0591 #endif
0592 #ifdef WITH_RENDER
0593 case SRG_RENDER: render( idx, dim, &prd ) ; break ;
0594 #endif
0595 #ifdef WITH_SIMTRACE
0596 case SRG_SIMTRACE: simtrace( idx, dim, &prd ) ; break ;
0597 #endif
0598 }
0599
0600 }
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616 extern "C" __global__ void __miss__ms()
0617 {
0618 MissData* ms = reinterpret_cast<MissData*>( optixGetSbtDataPointer() );
0619 const unsigned ii_id = 0xffffffffu ;
0620 const unsigned gp_bd = 0xffffffffu ;
0621 const float lposcost = 0.f ;
0622 const float lposfphi = 0.f ;
0623
0624 quad2* prd = SOPTIX_getPRD<quad2>();
0625
0626 prd->q0.f.x = ms->r ;
0627 prd->q0.f.y = ms->g ;
0628 prd->q0.f.z = ms->b ;
0629 prd->q0.f.w = 1.f ;
0630
0631 prd->q1.u.x = 0u ;
0632 prd->q1.u.y = 0u ;
0633 prd->q1.u.z = 0u ;
0634 prd->q1.u.w = 0u ;
0635
0636 prd->set_iindex_identity_(ii_id);
0637 prd->set_globalPrimIdx_boundary_(gp_bd);
0638 prd->set_lpos(lposcost, lposfphi);
0639 }
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706 extern "C" __global__ void __closesthit__ch()
0707 {
0708 unsigned iindex = optixGetInstanceIndex() ;
0709 unsigned identity = optixGetInstanceId() ;
0710 unsigned iindex_identity = (( iindex & 0xffffu ) << 16 ) | ( identity & 0xffffu ) ;
0711
0712 OptixPrimitiveType type = optixGetPrimitiveType();
0713 const HitGroupData* hg = reinterpret_cast<HitGroupData*>( optixGetSbtDataPointer() );
0714
0715 #if defined(DEBUG_PIDX)
0716
0717
0718
0719 #endif
0720
0721 if(type == OPTIX_PRIMITIVE_TYPE_TRIANGLE || type == 0)
0722 {
0723 const TriMesh& mesh = hg->mesh ;
0724 unsigned globalPrimIdx_boundary = (( mesh.globalPrimIdx & 0xffffu ) << 16 ) | ( mesh.boundary & 0xffffu ) ;
0725 const unsigned prim_idx = optixGetPrimitiveIndex();
0726 const float2 barys = optixGetTriangleBarycentrics();
0727
0728 uint3 tri = mesh.indice[ prim_idx ];
0729 const float3 P0 = mesh.vertex[ tri.x ];
0730 const float3 P1 = mesh.vertex[ tri.y ];
0731 const float3 P2 = mesh.vertex[ tri.z ];
0732 const float3 P = ( 1.0f-barys.x-barys.y)*P0 + barys.x*P1 + barys.y*P2;
0733
0734
0735
0736
0737
0738
0739
0740 const float3 Ng = cross( P1-P0, P2-P0 );
0741
0742
0743 const float3 N = normalize( optixTransformNormalFromObjectToWorldSpace( Ng ) );
0744
0745 float t = optixGetRayTmax() ;
0746
0747
0748
0749
0750
0751
0752
0753 float lposcost = normalize_cost(P);
0754 float lposfphi = normalize_fphi(P);
0755
0756
0757 quad2* prd = SOPTIX_getPRD<quad2>();
0758
0759 prd->q0.f.x = N.x ;
0760 prd->q0.f.y = N.y ;
0761 prd->q0.f.z = N.z ;
0762 prd->q0.f.w = t ;
0763
0764 prd->set_iindex_identity_( iindex_identity ) ;
0765 prd->set_globalPrimIdx_boundary_( globalPrimIdx_boundary ) ;
0766 prd->set_lpos(lposcost, lposfphi);
0767
0768 }
0769 else if(type == OPTIX_PRIMITIVE_TYPE_CUSTOM)
0770 {
0771
0772 quad2* prd = SOPTIX_getPRD<quad2>();
0773
0774 prd->set_iindex_identity_( iindex_identity ) ;
0775
0776 float3* normal = prd->normal();
0777 *normal = optixTransformNormalFromObjectToWorldSpace( *normal ) ;
0778 }
0779 }
0780
0781
0782
0783
0784
0785
0786
0787
0788
0789
0790
0791
0792
0793
0794
0795
0796
0797 extern "C" __global__ void __intersection__is()
0798 {
0799
0800 #if defined(DEBUG_PIDXYZ)
0801 const uint3 idx = optixGetLaunchIndex();
0802 const uint3 dim = optixGetLaunchDimensions();
0803 bool dumpxyz = idx.x == params.pidxyz.x && idx.y == params.pidxyz.y && idx.z == params.pidxyz.z ;
0804
0805 #else
0806 bool dumpxyz = false ;
0807 #endif
0808
0809
0810 HitGroupData* hg = (HitGroupData*)optixGetSbtDataPointer();
0811 int nodeOffset = hg->prim.nodeOffset ;
0812 int globalPrimIdx = hg->prim.globalPrimIdx ;
0813
0814 const CSGNode* node = params.node + nodeOffset ;
0815 const float4* plan = params.plan ;
0816 const qat4* itra = params.itra ;
0817
0818 const float t_min = optixGetRayTmin() ;
0819 const float3 ray_origin = optixGetObjectRayOrigin();
0820 const float3 ray_direction = optixGetObjectRayDirection();
0821
0822 float4 isect ;
0823 isect.x = 0.f ;
0824 isect.y = 0.f ;
0825 isect.z = 0.f ;
0826 isect.w = 0.f ;
0827
0828 bool valid_isect = intersect_prim(isect, node, plan, itra, t_min , ray_origin, ray_direction, dumpxyz );
0829 if(valid_isect)
0830 {
0831 const float3 lpos = ray_origin + isect.w*ray_direction ;
0832 const float lposcost = normalize_cost(lpos);
0833 const float lposfphi = normalize_fphi(lpos);
0834
0835 const unsigned hitKind = 0u ;
0836 const unsigned boundary = node->boundary() ;
0837 const unsigned globalPrimIdx_boundary = (( globalPrimIdx & 0xffffu ) << 16 ) | ( boundary & 0xffffu ) ;
0838
0839
0840
0841
0842
0843
0844 const float cosI = dot(ray_direction, make_float3(isect.x, isect.y, isect.z));
0845 const float t_report = CSGOptiX_ReportedIntersectionDistance(isect.w, params.raygenmode, cosI);
0846
0847 if (optixReportIntersection(t_report, hitKind))
0848 {
0849 quad2* prd = SOPTIX_getPRD<quad2>();
0850 prd->q0.f = isect ;
0851 prd->set_globalPrimIdx_boundary_(globalPrimIdx_boundary) ;
0852 prd->set_lpos(lposcost, lposfphi);
0853 }
0854
0855 }
0856
0857 #if defined(DEBUG_PIDXYZ)
0858
0859 #endif
0860
0861 }
0862