88 #define TACHYON_INTERNAL 1 90 #include <optix_stubs.h> 91 #include <optix_function_table_definition.h> 100 #define DBG() if (verbose == RT_VERB_DEBUG) { printf("TachyonOptiX) %s\n", __func__); } 103 #define CUERR { cudaError_t err; \ 104 if ((err = cudaGetLastError()) != cudaSuccess) { \ 105 printf("CUDA error: %s, %s line %d\n", cudaGetErrorString(err), __FILE__, __LINE__); \ 113 #if defined(TACHYON_OPTIXDENOISER) 115 __global__
static void post_denoise_rgba4u(uchar4 *rgba4u,
118 float tonemap_exposure,
120 int xres,
int yres) {
121 unsigned int imgsz = xres * yres;
122 unsigned int idx = blockIdx.x * blockDim.x + threadIdx.x;
134 float4 sRGB_approx20 = rgba4f[idx];
148 tonedcol = tonemap_color(lin, tonemap_mode, tonemap_exposure, colorspace);
157 rgba4u[idx] = make_color_rgb4u(outcol);
176 lasterr = OPTIX_SUCCESS;
183 general_module =
nullptr;
184 curve_module =
nullptr;
188 strcpy(shaderpath,
"TachyonOptiXShaders.ptx");
191 time_ctx_setup = 0.0;
192 time_ctx_validate = 0.0;
193 time_ctx_AS_build = 0.0;
194 time_ray_tracing = 0.0;
197 memset((
void *) &sbt, 0,
sizeof(sbt));
204 memset(scene_bg_color, 0,
sizeof(scene_bg_color));
205 memset(scene_bg_grad_top, 0,
sizeof(scene_bg_grad_top));
206 memset(scene_bg_grad_bot, 0,
sizeof(scene_bg_grad_bot));
207 memset(scene_bg_grad_updir, 0,
sizeof(scene_bg_grad_updir));
208 scene_bg_grad_topval = 1.0f;
209 scene_bg_grad_botval = -scene_bg_grad_topval;
211 scene_bg_grad_invrange = 1.0f / (scene_bg_grad_topval - scene_bg_grad_botval);
214 float tmp_pos[3] = { 0.0f, 0.0f, -1.0f };
215 float tmp_U[3] = { 1.0f, 0.0f, 0.0f };
216 float tmp_V[3] = { 0.0f, 1.0f, 0.0f };
217 float tmp_W[3] = { 0.0f, 0.0f, 1.0f };
218 memcpy(cam_pos, tmp_pos,
sizeof(cam_pos));
219 memcpy(cam_U, tmp_U,
sizeof(cam_U));
220 memcpy(cam_V, tmp_V,
sizeof(cam_V));
221 memcpy(cam_W, tmp_W,
sizeof(cam_W));
225 cam_dof_focal_dist = 2.0f;
226 cam_dof_fnumber = 64.0f;
228 cam_stereo_enabled = 0;
229 cam_stereo_eyesep = 0.06f;
230 cam_stereo_convergence_dist = 2.0f;
233 clipview_start = 1.0f;
253 scene_max_depth = 21;
254 scene_max_trans = scene_max_depth;
255 scene_epsilon = 5.e-5f * 50;
257 lasterr = OPTIX_SUCCESS;
264 regen_optix_pipeline=1;
266 regen_optix_lights=1;
280 cudaDeviceSynchronize();
CUERR;
282 if (context_created) {
302 if (cbdata != NULL) {
310 const char *tag,
const char *msg) {
317 printf(
"TachyonOptiX) [%s]: %s\n", tag, msg);
324 char *verbstr = getenv(
"TACHYONOPTIXVERBOSE");
325 if (verbstr != NULL) {
327 if (!strcasecmp(verbstr,
"MIN")) {
330 printf(
"TachyonOptiX) verbose setting: minimum\n");
331 }
else if (!strcasecmp(verbstr,
"TIMING")) {
334 printf(
"TachyonOptiX) verbose setting: timing data\n");
335 }
else if (!strcasecmp(verbstr,
"DEBUG")) {
338 printf(
"TachyonOptiX) verbose setting: full debugging data\n");
348 printf(
"TachyonOptiX::device_list()\n");
351 cudaGetDeviceCount(&devcount);
359 printf(
"TachyonOptiX::device_count()\n");
368 printf(
"TachyonOptiX::optix_version()\n");
375 unsigned int version=OPTIX_VERSION;
381 void TachyonOptiX::check_verbose_env() {
386 void TachyonOptiX::create_context() {
394 double starttime = wkf_timer_timenow(
rt_timer);
397 printf(
"TachyonOptiX) creating context...\n");
399 if (lasterr == OPTIX_SUCCESS) {
400 rt_ptx_code_string = NULL;
403 printf(
"TachyonOptiX) Loading PTX src from compilation...\n");
405 rt_ptx_code_string = internal_compiled_ptx_src();
406 if (!rt_ptx_code_string) {
408 printf(
"TachyonOptiX) Loading PTX src from disk\n");
410 if (read_ptx_src(shaderpath, &rt_ptx_code_string) != 0) {
411 printf(
"TachyonOptiX) Failed to load PTX shaders: '%s'\n", shaderpath);
425 lasterr = optixInit();
426 if (lasterr == OPTIX_ERROR_UNSUPPORTED_ABI_VERSION) {
432 printf(
"TachyonOptiX) OptiX initialization failed driver is too old.\n");
433 printf(
"TachyonOptiX) Driver does not support ABI version %d\n",
438 cudaStreamCreate(&stream);
440 OptixDeviceContextOptions options = {};
441 optixDeviceContextCreate(cuda_ctx, &options, &optix_ctx);
443 lasterr = optixDeviceContextSetLogCallback(optix_ctx,
449 if (lasterr == OPTIX_SUCCESS)
450 context_create_module();
452 double time_ptxsrc = wkf_timer_timenow(
rt_timer);
454 printf(
"TachyonOptiX) load PTX shader src %.1f secs\n", time_ptxsrc - starttime);
457 if (lasterr == OPTIX_SUCCESS)
458 context_create_pipeline();
471 compactedSizeBuffer.
set_size(
sizeof(uint64_t));
475 IASBuffer.
set_size(8L * 1024L * 1024L);
480 #if defined(TACHYON_OPTIXDENOISER) 482 context_create_denoiser();
485 double time_pipeline = wkf_timer_timenow(
rt_timer);
487 printf(
"TachyonOptiX) create RT pipeline %.1f secs\n", time_pipeline - time_ptxsrc);
490 time_ctx_create = wkf_timer_timenow(
rt_timer) - starttime;
493 printf(
"TachyonOptiX) context creation time: %.2f\n", time_ctx_create);
503 if (!context_created)
513 int TachyonOptiX::read_ptx_src(
const char *ptxfilename,
char **ptxstring) {
515 FILE *ptxfp = fopen(ptxfilename,
"r");
521 fseek(ptxfp, 0, SEEK_END);
522 long ptxsize = ftell(ptxfp);
523 fseek(ptxfp, 0, SEEK_SET);
524 *ptxstring = (
char *) calloc(1, ptxsize + 1);
525 if (fread(*ptxstring, ptxsize, 1, ptxfp) != 1) {
534 void TachyonOptiX::context_create_denoiser() {
535 #if defined(TACHYON_OPTIXDENOISER) 536 denoiser_ctx =
nullptr;
537 memset(&denoiser_options, 0,
sizeof(denoiser_options));
538 optixDenoiserCreate(optix_ctx, OPTIX_DENOISER_MODEL_KIND_LDR,
539 &denoiser_options, &denoiser_ctx);
541 denoiser_resize_update();
546 void TachyonOptiX::context_destroy_denoiser() {
547 #if defined(TACHYON_OPTIXDENOISER) 549 optixDenoiserDestroy(denoiser_ctx);
550 denoiser_ctx =
nullptr;
552 denoiser_scratch.free();
553 denoiser_state.free();
554 denoiser_colorbuffer.free();
555 denoiser_denoisedbuffer.free();
561 void TachyonOptiX::denoiser_resize_update() {
562 #if defined(TACHYON_OPTIXDENOISER) 564 optixDenoiserComputeMemoryResources(denoiser_ctx, width, height,
567 long newsz = max(denoiser_sizes.withOverlapScratchSizeInBytes,
568 denoiser_sizes.withoutOverlapScratchSizeInBytes);
569 denoiser_scratch.set_size(newsz);
571 denoiser_state.set_size(denoiser_sizes.stateSizeInBytes);
573 optixDenoiserSetup(denoiser_ctx, stream, width, height,
574 denoiser_state.cu_dptr(), denoiser_state.get_size(),
575 denoiser_scratch.cu_dptr(), denoiser_scratch.get_size());
577 int fbsz = width * height *
sizeof(float4);
578 denoiser_colorbuffer.set_size(fbsz, stream);
579 denoiser_denoisedbuffer.set_size(fbsz, stream);
585 void TachyonOptiX::denoiser_launch() {
586 #if defined(TACHYON_OPTIXDENOISER) 588 if (denoiser_ctx && denoiser_enabled) {
589 OptixDenoiserParams denoiser_params = {};
590 denoiser_params.denoiseAlpha = 1;
591 denoiser_params.hdrIntensity = (CUdeviceptr)0;
598 denoiser_params.blendFactor =
602 printf(
"TachyonOptiX) Accum. Buf AI Denoising Blend Factor: %.2f\n",
603 denoiser_params.blendFactor);
606 OptixImage2D input_layer = {};
607 input_layer.data = denoiser_colorbuffer.cu_dptr();
608 input_layer.width = width;
609 input_layer.height = height;
610 input_layer.rowStrideInBytes = width *
sizeof(float4);
611 input_layer.pixelStrideInBytes =
sizeof(float4);
612 input_layer.format = OPTIX_PIXEL_FORMAT_FLOAT4;
614 OptixImage2D output_layer = {};
615 output_layer.data = denoiser_denoisedbuffer.cu_dptr();
616 output_layer.width = width;
617 output_layer.height = height;
618 output_layer.rowStrideInBytes = width *
sizeof(float4);
619 output_layer.pixelStrideInBytes =
sizeof(float4);
620 output_layer.format = OPTIX_PIXEL_FORMAT_FLOAT4;
622 OptixDenoiserGuideLayer denoiser_guidelayer = {};
623 OptixDenoiserLayer denoiser_layer = {};
624 denoiser_layer.input = input_layer;
625 denoiser_layer.output = output_layer;
627 optixDenoiserInvoke(denoiser_ctx, stream, &denoiser_params,
628 denoiser_state.cu_dptr(), denoiser_state.get_size(),
629 &denoiser_guidelayer, &denoiser_layer,
632 denoiser_scratch.cu_dptr(), denoiser_scratch.get_size());
636 dim3 Gsz((width*height + Bsz.x - 1)/Bsz.x, 1, 1);
637 post_denoise_rgba4u<<<Gsz, Bsz, 0, stream>>>(
638 (uchar4 *) framebuffer.
cu_dptr(),
639 (float4 *) denoiser_denoisedbuffer.cu_dptr(),
652 void TachyonOptiX::context_create_exception_pgms() {
654 exceptionPGs.resize(1);
656 OptixProgramGroupOptions pgOpts = {};
657 OptixProgramGroupDesc pgDesc = {};
658 pgDesc.kind = OPTIX_PROGRAM_GROUP_KIND_EXCEPTION;
659 pgDesc.raygen.module = general_module;
661 pgDesc.raygen.entryFunctionName=
"__exception__all";
664 size_t sizeof_log =
sizeof(log);
665 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
666 log, &sizeof_log, &exceptionPGs[0]);
669 printf(
"TachyonOptiX) exception construction log:\n %s\n", log);
674 void TachyonOptiX::context_destroy_exception_pgms() {
676 for (
auto &pg : exceptionPGs)
677 optixProgramGroupDestroy(pg);
678 exceptionPGs.clear();
682 void TachyonOptiX::context_create_raygen_pgms() {
688 OptixProgramGroupOptions pgOpts = {};
689 OptixProgramGroupDesc pgDesc = {};
690 pgDesc.kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
691 pgDesc.raygen.module = general_module;
694 const char *raygenfctn=
nullptr;
695 switch (camera_type) {
697 if (cam_dof_enabled) {
698 if (cam_stereo_enabled)
699 raygenfctn =
"__raygen__camera_perspective_stereo_dof";
701 raygenfctn =
"__raygen__camera_perspective_dof";
703 if (cam_stereo_enabled)
704 raygenfctn =
"__raygen__camera_perspective_stereo";
706 raygenfctn =
"__raygen__camera_perspective";
711 if (cam_dof_enabled) {
712 if (cam_stereo_enabled)
713 raygenfctn =
"__raygen__camera_orthographic_stereo_dof";
715 raygenfctn =
"__raygen__camera_orthographic_dof";
717 if (cam_stereo_enabled)
718 raygenfctn =
"__raygen__camera_orthographic_stereo";
720 raygenfctn =
"__raygen__camera_orthographic";
725 if (cam_dof_enabled) {
726 if (cam_stereo_enabled)
727 raygenfctn =
"__raygen__camera_cubemap_stereo_dof";
729 raygenfctn =
"__raygen__camera_cubemap_dof";
731 if (cam_stereo_enabled)
732 raygenfctn =
"__raygen__camera_cubemap_stereo";
734 raygenfctn =
"__raygen__camera_cubemap";
739 if (cam_dof_enabled) {
740 if (cam_stereo_enabled)
741 raygenfctn =
"__raygen__camera_dome_master_stereo_dof";
743 raygenfctn =
"__raygen__camera_dome_master_dof";
745 if (cam_stereo_enabled)
746 raygenfctn =
"__raygen__camera_dome_master_stereo";
748 raygenfctn =
"__raygen__camera_dome_master";
753 if (cam_dof_enabled) {
754 if (cam_stereo_enabled)
755 raygenfctn =
"__raygen__camera_equirectangular_stereo_dof";
757 raygenfctn =
"__raygen__camera_equirectangular_dof";
759 if (cam_stereo_enabled)
760 raygenfctn =
"__raygen__camera_equirectangular_stereo";
762 raygenfctn =
"__raygen__camera_equirectangular";
767 if (cam_dof_enabled) {
768 if (cam_stereo_enabled)
769 raygenfctn =
"__raygen__camera_octahedral_stereo_dof";
771 raygenfctn =
"__raygen__camera_octahedral_dof";
773 if (cam_stereo_enabled)
774 raygenfctn =
"__raygen__camera_octahedral_stereo";
776 raygenfctn =
"__raygen__camera_octahedral";
781 if (cam_dof_enabled) {
782 if (cam_stereo_enabled)
783 raygenfctn =
"__raygen__camera_oculus_rift_stereo_dof";
785 raygenfctn =
"__raygen__camera_oculus_rift_dof";
787 if (cam_stereo_enabled)
788 raygenfctn =
"__raygen__camera_oculus_rift_stereo";
790 raygenfctn =
"__raygen__camera_oculus_rift";
794 pgDesc.raygen.entryFunctionName=raygenfctn;
796 printf(
"TachyonOptiX) raygen: '%s'\n", raygenfctn);
799 size_t sizeof_log =
sizeof(log);
800 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
801 log, &sizeof_log, &raygenPGs[0]);
804 printf(
"TachyonOptiX) raygen construction log:\n %s\n", log);
811 void TachyonOptiX::context_destroy_raygen_pgms() {
813 for (
auto &pg : raygenPGs)
814 optixProgramGroupDestroy(pg);
819 void TachyonOptiX::context_create_miss_pgms() {
824 size_t sizeof_log =
sizeof(log);
826 OptixProgramGroupOptions pgOpts = {};
827 OptixProgramGroupDesc pgDesc = {};
828 pgDesc.kind = OPTIX_PROGRAM_GROUP_KIND_MISS;
829 pgDesc.miss.module = general_module;
836 const char *missfctn=
nullptr;
837 switch (scene_background_mode) {
839 missfctn =
"__miss__radiance_gradient_bg_sky_sphere";
843 missfctn =
"__miss__radiance_gradient_bg_sky_plane";
848 missfctn =
"__miss__radiance_solid_bg";
851 pgDesc.miss.entryFunctionName=missfctn;
853 printf(
"TachyonOptiX) miss: '%s'\n", missfctn);
855 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
859 printf(
"TachyonOptiX) miss radiance construction log:\n %s\n", log);
863 pgDesc.miss.entryFunctionName =
"__miss__shadow_nop";
864 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
868 printf(
"TachyonOptiX) miss shadow construction log:\n %s\n", log);
873 void TachyonOptiX::context_destroy_miss_pgms() {
875 for (
auto &pg : missPGs)
876 optixProgramGroupDestroy(pg);
881 void TachyonOptiX::context_create_curve_hitgroup_pgms() {
886 size_t sizeof_log =
sizeof( log );
888 OptixProgramGroupOptions pgOpts = {};
889 OptixProgramGroupDesc pgDesc = {};
890 pgDesc.kind = OPTIX_PROGRAM_GROUP_KIND_HITGROUP;
891 auto &hg = pgDesc.hitgroup;
893 hg.moduleCH = general_module;
894 hg.moduleAH = general_module;
897 hg.moduleIS = curve_module;
898 hg.entryFunctionNameIS = 0;
901 hg.entryFunctionNameCH =
"__closesthit__radiance_general";
902 hg.entryFunctionNameAH =
"__anyhit__radiance_nop";
904 printf(
"TachyonOptiX) curve anyhit: %s\n", hg.entryFunctionNameAH);
905 printf(
"TachyonOptiX) curve closesthit: %s\n", hg.entryFunctionNameCH);
907 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
911 printf(
"TachyonOptiX) curve hitgroup radiance construction log:\n" 916 hg.entryFunctionNameCH =
"__closesthit__shadow_nop";
917 hg.entryFunctionNameAH =
"__anyhit__shadow_transmission";
923 printf(
"TachyonOptiX) curve anyhit: %s\n", hg.entryFunctionNameAH);
924 printf(
"TachyonOptiX) curve closesthit: %s\n", hg.entryFunctionNameCH);
926 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
930 printf(
"TachyonOptiX) curve hitgroup shadow construction log:\n %s\n", log);
935 void TachyonOptiX::context_destroy_curve_hitgroup_pgms() {
937 for (
auto &pg : curvePGs)
938 optixProgramGroupDestroy(pg);
943 void TachyonOptiX::context_create_hwtri_hitgroup_pgms() {
948 size_t sizeof_log =
sizeof( log );
950 OptixProgramGroupOptions pgOpts = {};
951 OptixProgramGroupDesc pgDesc = {};
952 pgDesc.kind = OPTIX_PROGRAM_GROUP_KIND_HITGROUP;
953 auto &hg = pgDesc.hitgroup;
955 hg.moduleCH = general_module;
956 hg.moduleAH = general_module;
959 hg.entryFunctionNameCH =
"__closesthit__radiance_general";
960 hg.entryFunctionNameAH =
"__anyhit__radiance_nop";
962 printf(
"TachyonOptiX) triangle anyhit: %s\n", hg.entryFunctionNameAH);
963 printf(
"TachyonOptiX) triangle closesthit: %s\n", hg.entryFunctionNameCH);
965 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
969 printf(
"TachyonOptiX) triangle hitgroup radiance construction log:\n" 974 hg.entryFunctionNameCH =
"__closesthit__shadow_nop";
975 hg.entryFunctionNameAH =
"__anyhit__shadow_transmission";
981 printf(
"TachyonOptiX) triangle anyhit: %s\n", hg.entryFunctionNameAH);
982 printf(
"TachyonOptiX) triangle closesthit: %s\n", hg.entryFunctionNameCH);
984 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
988 printf(
"TachyonOptiX) triangle hitgroup shadow construction log:\n" 994 void TachyonOptiX::context_destroy_hwtri_hitgroup_pgms() {
996 for (
auto &pg : trimeshPGs)
997 optixProgramGroupDestroy(pg);
1002 void TachyonOptiX::context_create_intersection_pgms() {
1007 size_t sizeof_log =
sizeof(log);
1009 OptixProgramGroupOptions pgOpts = {};
1010 OptixProgramGroupDesc pgDesc = {};
1011 pgDesc.kind = OPTIX_PROGRAM_GROUP_KIND_HITGROUP;
1012 auto &hg = pgDesc.hitgroup;
1013 hg.moduleIS = general_module;
1014 hg.moduleCH = general_module;
1015 hg.moduleAH = general_module;
1023 hg.entryFunctionNameIS =
"__intersection__cone_array_color";
1024 hg.entryFunctionNameCH =
"__closesthit__radiance_general";
1025 hg.entryFunctionNameAH =
"__anyhit__radiance_nop";
1027 printf(
"TachyonOptiX) anyhit: %s\n", hg.entryFunctionNameAH);
1028 printf(
"TachyonOptiX) closesthit: %s\n", hg.entryFunctionNameCH);
1029 printf(
"TachyonOptiX) intersection: %s\n", hg.entryFunctionNameIS);
1031 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
1035 printf(
"TachyonOptiX) cone radiance intersection construction log:\n" 1040 hg.entryFunctionNameIS =
"__intersection__cone_array_color";
1041 hg.entryFunctionNameCH =
"__closesthit__shadow_nop";
1042 hg.entryFunctionNameAH =
"__anyhit__shadow_transmission";
1044 printf(
"TachyonOptiX) anyhit: %s\n", hg.entryFunctionNameAH);
1045 printf(
"TachyonOptiX) closesthit: %s\n", hg.entryFunctionNameCH);
1046 printf(
"TachyonOptiX) intersection: %s\n", hg.entryFunctionNameIS);
1048 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
1052 printf(
"TachyonOptiX) cone shadow intersection construction log:\n" 1063 hg.entryFunctionNameIS =
"__intersection__cylinder_array_color";
1064 hg.entryFunctionNameCH =
"__closesthit__radiance_general";
1065 hg.entryFunctionNameAH =
"__anyhit__radiance_nop";
1067 printf(
"TachyonOptiX) anyhit: %s\n", hg.entryFunctionNameAH);
1068 printf(
"TachyonOptiX) closesthit: %s\n", hg.entryFunctionNameCH);
1069 printf(
"TachyonOptiX) intersection: %s\n", hg.entryFunctionNameIS);
1071 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
1075 printf(
"TachyonOptiX) cylinder radiance intersection construction log:\n" 1080 hg.entryFunctionNameIS =
"__intersection__cylinder_array_color";
1081 hg.entryFunctionNameCH =
"__closesthit__shadow_nop";
1082 hg.entryFunctionNameAH =
"__anyhit__shadow_transmission";
1084 printf(
"TachyonOptiX) anyhit: %s\n", hg.entryFunctionNameAH);
1085 printf(
"TachyonOptiX) closesthit: %s\n", hg.entryFunctionNameCH);
1086 printf(
"TachyonOptiX) intersection: %s\n", hg.entryFunctionNameIS);
1088 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
1092 printf(
"TachyonOptiX) cylinder shadow intersection construction log:\n" 1103 hg.entryFunctionNameIS =
"__intersection__quadmesh";
1104 hg.entryFunctionNameCH =
"__closesthit__radiance_general";
1105 hg.entryFunctionNameAH =
"__anyhit__radiance_nop";
1107 printf(
"TachyonOptiX) anyhit: %s\n", hg.entryFunctionNameAH);
1108 printf(
"TachyonOptiX) closesthit: %s\n", hg.entryFunctionNameCH);
1109 printf(
"TachyonOptiX) intersection: %s\n", hg.entryFunctionNameIS);
1111 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
1115 printf(
"TachyonOptiX) quad radiance intersection construction log:\n" 1120 hg.entryFunctionNameIS =
"__intersection__quadmesh";
1121 hg.entryFunctionNameCH =
"__closesthit__shadow_nop";
1122 hg.entryFunctionNameAH =
"__anyhit__shadow_transmission";
1124 printf(
"TachyonOptiX) anyhit: %s\n", hg.entryFunctionNameAH);
1125 printf(
"TachyonOptiX) closesthit: %s\n", hg.entryFunctionNameCH);
1126 printf(
"TachyonOptiX) intersection: %s\n", hg.entryFunctionNameIS);
1128 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
1132 printf(
"TachyonOptiX) quad shadow intersection construction log:\n" 1143 hg.entryFunctionNameIS =
"__intersection__ring_array";
1144 hg.entryFunctionNameCH =
"__closesthit__radiance_general";
1145 hg.entryFunctionNameAH =
"__anyhit__radiance_nop";
1147 printf(
"TachyonOptiX) anyhit: %s\n", hg.entryFunctionNameAH);
1148 printf(
"TachyonOptiX) closesthit: %s\n", hg.entryFunctionNameCH);
1149 printf(
"TachyonOptiX) intersection: %s\n", hg.entryFunctionNameIS);
1151 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
1155 printf(
"TachyonOptiX) ring radiance intersection construction log:\n" 1160 hg.entryFunctionNameIS =
"__intersection__ring_array";
1161 hg.entryFunctionNameCH =
"__closesthit__shadow_nop";
1162 hg.entryFunctionNameAH =
"__anyhit__shadow_transmission";
1164 printf(
"TachyonOptiX) anyhit: %s\n", hg.entryFunctionNameAH);
1165 printf(
"TachyonOptiX) closesthit: %s\n", hg.entryFunctionNameCH);
1166 printf(
"TachyonOptiX) intersection: %s\n", hg.entryFunctionNameIS);
1168 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
1172 printf(
"TachyonOptiX) ring shadow intersection construction log:\n" 1183 hg.entryFunctionNameIS =
"__intersection__sphere_array";
1184 hg.entryFunctionNameCH =
"__closesthit__radiance_general";
1185 hg.entryFunctionNameAH =
"__anyhit__radiance_nop";
1187 printf(
"TachyonOptiX) anyhit: %s\n", hg.entryFunctionNameAH);
1188 printf(
"TachyonOptiX) closesthit: %s\n", hg.entryFunctionNameCH);
1189 printf(
"TachyonOptiX) intersection: %s\n", hg.entryFunctionNameIS);
1191 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
1195 printf(
"TachyonOptiX) sphere radiance intersection construction log:\n" 1200 hg.entryFunctionNameIS =
"__intersection__sphere_array";
1201 hg.entryFunctionNameCH =
"__closesthit__shadow_nop";
1202 hg.entryFunctionNameAH =
"__anyhit__shadow_transmission";
1204 printf(
"TachyonOptiX) anyhit: %s\n", hg.entryFunctionNameAH);
1205 printf(
"TachyonOptiX) closesthit: %s\n", hg.entryFunctionNameCH);
1206 printf(
"TachyonOptiX) intersection: %s\n", hg.entryFunctionNameIS);
1208 lasterr = optixProgramGroupCreate(optix_ctx, &pgDesc, 1, &pgOpts,
1212 printf(
"TachyonOptiX) sphere shadow intersection construction log:\n" 1218 void TachyonOptiX::context_destroy_intersection_pgms() {
1220 for (
auto &pg : custprimPGs)
1221 optixProgramGroupDestroy(pg);
1222 custprimPGs.clear();
1226 void TachyonOptiX::context_create_module() {
1229 OptixModuleCompileOptions moduleCompOpts = {};
1231 moduleCompOpts.maxRegisterCount = OPTIX_COMPILE_DEFAULT_MAX_REGISTER_COUNT;
1232 moduleCompOpts.optLevel = OPTIX_COMPILE_OPTIMIZATION_DEFAULT;
1236 #if OPTIX_VERSION >= 70400 1239 moduleCompOpts.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_MINIMAL;
1241 moduleCompOpts.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_LINEINFO;
1244 pipeCompOpts.traversableGraphFlags = OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_ANY;
1245 pipeCompOpts.usesMotionBlur =
false;
1256 pipeCompOpts.numPayloadValues = 3;
1257 pipeCompOpts.numAttributeValues = 2;
1260 if ((getenv(
"TACHYONOPTIXDEBUG") != NULL)) {
1261 pipeCompOpts.exceptionFlags = OPTIX_EXCEPTION_FLAG_DEBUG |
1262 OPTIX_EXCEPTION_FLAG_TRACE_DEPTH |
1263 OPTIX_EXCEPTION_FLAG_STACK_OVERFLOW;
1265 pipeCompOpts.exceptionFlags = OPTIX_EXCEPTION_FLAG_NONE;
1267 pipeCompOpts.pipelineLaunchParamsVariableName =
"rtLaunch";
1269 #if (OPTIX_VERSION >= 70100) 1270 pipeCompOpts.usesPrimitiveTypeFlags =
1271 OPTIX_PRIMITIVE_TYPE_FLAGS_CUSTOM | OPTIX_PRIMITIVE_TYPE_FLAGS_TRIANGLE |
1272 OPTIX_PRIMITIVE_TYPE_FLAGS_ROUND_LINEAR;
1278 size_t sizeof_log =
sizeof(log);
1279 lasterr = optixModuleCreateFromPTX(optix_ctx, &moduleCompOpts, &pipeCompOpts,
1281 strlen(rt_ptx_code_string),
1282 log, &sizeof_log, &general_module);
1285 printf(
"TachyonOptiX) general_module construction log:\n %s\n", log);
1288 #if OPTIX_VERSION >= 70100 1292 OptixBuiltinISOptions ISopts = {};
1293 ISopts.builtinISModuleType = OPTIX_PRIMITIVE_TYPE_ROUND_LINEAR;
1296 #if OPTIX_VERSION >= 70400 1297 ISopts.buildFlags = OPTIX_BUILD_FLAG_PREFER_FAST_TRACE;
1298 ISopts.curveEndcapFlags = OPTIX_CURVE_ENDCAP_DEFAULT;
1300 ISopts.usesMotionBlur =
false;
1301 optixBuiltinISModuleGet(optix_ctx, &moduleCompOpts, &pipeCompOpts,
1302 &ISopts, &curve_module);
1309 void TachyonOptiX::context_destroy_module() {
1313 optixModuleDestroy(general_module);
1316 optixModuleDestroy(curve_module);
1320 void TachyonOptiX::context_create_pipeline() {
1324 if (lasterr == OPTIX_SUCCESS)
1325 context_create_exception_pgms();
1327 if (lasterr == OPTIX_SUCCESS)
1328 context_create_raygen_pgms();
1329 if (lasterr == OPTIX_SUCCESS)
1330 context_create_miss_pgms();
1331 if (lasterr == OPTIX_SUCCESS)
1332 context_create_curve_hitgroup_pgms();
1333 if (lasterr == OPTIX_SUCCESS)
1334 context_create_hwtri_hitgroup_pgms();
1335 if (lasterr == OPTIX_SUCCESS)
1336 context_create_intersection_pgms();
1338 std::vector<OptixProgramGroup> programGroups;
1339 for (
auto &pg : exceptionPGs)
1340 programGroups.push_back(pg);
1341 for (
auto &pg : raygenPGs)
1342 programGroups.push_back(pg);
1343 for (
auto &pg : missPGs)
1344 programGroups.push_back(pg);
1345 for (
auto &pg : curvePGs)
1346 programGroups.push_back(pg);
1347 for (
auto &pg : trimeshPGs)
1348 programGroups.push_back(pg);
1349 for (
auto &pg : custprimPGs)
1350 programGroups.push_back(pg);
1353 printf(
"TachyonOptiX) creating complete pipeline...\n");
1357 size_t sizeof_log =
sizeof(log);
1358 OptixPipelineLinkOptions pipeLinkOpts = {};
1359 pipeLinkOpts.maxTraceDepth = 21;
1360 lasterr = optixPipelineCreate(optix_ctx, &pipeCompOpts, &pipeLinkOpts,
1361 programGroups.data(), (int)programGroups.size(),
1362 log, &sizeof_log, &pipe);
1364 printf(
"TachyonOptiX) pipeline construction log:\n %s\n", log);
1368 optixPipelineSetStackSize(pipe,
1374 regen_optix_pipeline=0;
1381 void TachyonOptiX::context_destroy_pipeline() {
1383 cudaDeviceSynchronize();
CUERR;
1387 custprimsGASBuffer.
free();
1388 #if OPTIX_VERSION >= 70100 1389 curvesGASBuffer.
free();
1391 trimeshesGASBuffer.
free();
1393 if (pipe !=
nullptr) {
1395 printf(
"TachyonOptiX) destroying existing pipeline...\n");
1397 optixPipelineDestroy(pipe);
1401 context_destroy_raygen_pgms();
1402 context_destroy_miss_pgms();
1403 context_destroy_curve_hitgroup_pgms();
1404 context_destroy_hwtri_hitgroup_pgms();
1405 context_destroy_intersection_pgms();
1406 context_destroy_exception_pgms();
1408 regen_optix_pipeline=1;
1414 void TachyonOptiX::SBT_create_programs() {
1421 std::vector<ExceptionRecord> exceptionRecords;
1422 for (
int i=0; i<exceptionPGs.size(); i++) {
1423 ExceptionRecord rec = {};
1424 optixSbtRecordPackHeader(exceptionPGs[i], &rec);
1426 exceptionRecords.push_back(rec);
1428 exceptionRecordsBuffer.
resize_upload(exceptionRecords, stream);
1429 sbt.exceptionRecord = exceptionRecordsBuffer.
cu_dptr();
1432 std::vector<RaygenRecord> raygenRecords;
1433 for (
int i=0; i<raygenPGs.size(); i++) {
1434 RaygenRecord rec = {};
1435 optixSbtRecordPackHeader(raygenPGs[i], &rec);
1437 raygenRecords.push_back(rec);
1440 sbt.raygenRecord = raygenRecordsBuffer.
cu_dptr();
1443 std::vector<MissRecord> missRecords;
1444 for (
int i=0; i<missPGs.size(); i++) {
1445 MissRecord rec = {};
1446 optixSbtRecordPackHeader(missPGs[i], &rec);
1448 missRecords.push_back(rec);
1451 sbt.missRecordBase = missRecordsBuffer.
cu_dptr();
1452 sbt.missRecordStrideInBytes =
sizeof(MissRecord);
1453 sbt.missRecordCount = (int) missRecords.size();
1459 void TachyonOptiX::SBT_create_hitgroups() {
1469 std::vector<HGRecordGroup> HGRecGroups;
1473 int numCones = (int) conearrays.size();
1474 for (
int objID=0; objID<numCones; objID++) {
1479 p.cone.base = (float3 *) coneBaseBuffers[objID].cu_dptr();
1480 p.cone.apex = (float3 *) coneApexBuffers[objID].cu_dptr();
1481 p.cone.baserad = (
float *) coneBaseRadBuffers[objID].cu_dptr();
1482 p.cone.apexrad = (
float *) coneApexRadBuffers[objID].cu_dptr();
1485 p.prim_color = (float3 *) conePrimColorBuffers[objID].cu_dptr();
1486 p.uniform_color = conearrays[objID].uniform_color;
1487 p.materialindex = conearrays[objID].materialindex;
1496 HGRecGroups.push_back(rec);
1502 int numCyls = (int) cyarrays.size();
1503 for (
int objID=0; objID<numCyls; objID++) {
1508 p.cyl.start = (float3 *) cyStartBuffers[objID].cu_dptr();
1509 p.cyl.end = (float3 *) cyEndBuffers[objID].cu_dptr();
1510 p.cyl.radius = (
float *) cyRadiusBuffers[objID].cu_dptr();
1513 p.prim_color = (float3 *) cyPrimColorBuffers[objID].cu_dptr();
1514 p.uniform_color = cyarrays[objID].uniform_color;
1515 p.materialindex = cyarrays[objID].materialindex;
1524 HGRecGroups.push_back(rec);
1530 int numQuads = (int) quadmeshes.size();
1531 for (
int objID=0; objID<numQuads; objID++) {
1535 auto &q = rec.
radiance.data.quadmesh;
1536 q.vertices = (float3 *) quadMeshVertBuffers[objID].cu_dptr();
1537 q.indices = (int4 *) quadMeshIdxBuffers[objID].cu_dptr();
1538 q.normals = (float3 *) quadMeshVertNormalBuffers[objID].cu_dptr();
1539 q.packednormals = (uint4 *) quadMeshVertPackedNormalBuffers[objID].cu_dptr();
1540 q.vertcolors3f = (float3 *) quadMeshVertColor3fBuffers[objID].cu_dptr();
1541 q.vertcolors4u = (uchar4 *) quadMeshVertColor4uBuffers[objID].cu_dptr();
1545 p.prim_color = (float3 *) quadMeshPrimColorBuffers[objID].cu_dptr();
1546 p.uniform_color = quadmeshes[objID].uniform_color;
1547 p.materialindex = quadmeshes[objID].materialindex;
1556 HGRecGroups.push_back(rec);
1562 int numRings = (int) riarrays.size();
1563 for (
int objID=0; objID<numRings; objID++) {
1568 p.ring.center = (float3 *) riCenterBuffers[objID].cu_dptr();
1569 p.ring.norm = (float3 *) riNormalBuffers[objID].cu_dptr();
1570 p.ring.inrad = (
float *) riInRadiusBuffers[objID].cu_dptr();
1571 p.ring.outrad = (
float *) riOutRadiusBuffers[objID].cu_dptr();
1574 p.prim_color = (float3 *) riPrimColorBuffers[objID].cu_dptr();
1575 p.uniform_color = riarrays[objID].uniform_color;
1576 p.materialindex = riarrays[objID].materialindex;
1585 HGRecGroups.push_back(rec);
1591 int numSpheres = (int) sparrays.size();
1592 for (
int objID=0; objID<numSpheres; objID++) {
1597 p.sphere.PosRadius = (float4 *) spPosRadiusBuffers[objID].cu_dptr();
1600 p.prim_color = (float3 *) spPrimColorBuffers[objID].cu_dptr();
1601 p.uniform_color = sparrays[objID].uniform_color;
1602 p.materialindex = sparrays[objID].materialindex;
1611 HGRecGroups.push_back(rec);
1615 #if OPTIX_VERSION >= 70100 1617 int numCurves = (int) curvearrays.size();
1618 for (
int objID=0; objID<numCurves; objID++) {
1623 p.curve.vertices = (float3 *) curveVertBuffers[objID].cu_dptr();
1624 p.curve.vertradii = (
float *) curveVertRadBuffers[objID].cu_dptr();
1625 p.curve.segindices = (
int *) curveSegIdxBuffers[objID].cu_dptr();
1628 p.prim_color = (float3 *) curvePrimColorBuffers[objID].cu_dptr();
1629 p.uniform_color = curvearrays[objID].uniform_color;
1630 p.materialindex = curvearrays[objID].materialindex;
1639 HGRecGroups.push_back(rec);
1645 int numTrimeshes = (int) trimeshes.size();
1646 for (
int objID=0; objID<numTrimeshes; objID++) {
1650 auto &t = rec.
radiance.data.trimesh;
1651 t.vertices = (float3 *) triMeshVertBuffers[objID].cu_dptr();
1652 t.indices = (int3 *) triMeshIdxBuffers[objID].cu_dptr();
1653 t.normals = (float3 *) triMeshVertNormalBuffers[objID].cu_dptr();
1654 t.packednormals = (uint4 *) triMeshVertPackedNormalBuffers[objID].cu_dptr();
1655 t.vertcolors3f = (float3 *) triMeshVertColor3fBuffers[objID].cu_dptr();
1656 t.vertcolors4u = (uchar4 *) triMeshVertColor4uBuffers[objID].cu_dptr();
1657 t.tex2d = (float2 *) triMeshTex2dBuffers[objID].cu_dptr();
1658 t.tex3d = (float3 *) triMeshTex3dBuffers[objID].cu_dptr();
1662 p.prim_color = (float3 *) triMeshPrimColorBuffers[objID].cu_dptr();
1663 p.uniform_color = trimeshes[objID].uniform_color;
1664 p.materialindex = trimeshes[objID].materialindex;
1673 HGRecGroups.push_back(rec);
1684 int hgsz = hitgroupRecordGroups.size();
1685 int hgrgsz = HGRecGroups.size();
1690 if (hitgroupRecordGroups.capacity() < (hgsz+hgrgsz))
1691 hitgroupRecordGroups.reserve(hgsz+hgrgsz);
1694 for (
auto &r: HGRecGroups) {
1695 hitgroupRecordGroups.push_back(r);
1700 SBT_update_hitgroup_geomflags();
1702 hitgroupRecordsBuffer.
resize_upload(hitgroupRecordGroups, stream);
1703 sync_hitgroupRecordGroups = 0;
1705 sbt.hitgroupRecordBase = hitgroupRecordsBuffer.
cu_dptr();
1706 sbt.hitgroupRecordStrideInBytes =
sizeof(HGRecord);
1714 hitgroupRecordGroups.erase(hitgroupRecordGroups.begin()+hgsz,
1715 hitgroupRecordGroups.end());
1718 cudaStreamSynchronize(stream);
1726 void TachyonOptiX::SBT_clear() {
1747 void TachyonOptiX::SBT_destroy() {
1752 exceptionRecordsBuffer.
free(stream);
1753 raygenRecordsBuffer.
free(stream);
1754 missRecordsBuffer.
free(stream);
1755 hitgroupRecordsBuffer.
free(stream);
1758 memset((
void *) &sbt, 0,
sizeof(sbt));
1767 void TachyonOptiX::SBT_update_hitgroup_geomflags() {
1771 #if defined(TACHYON_USE_GEOMFLAGS) 1774 for (
auto &g: hitgroupRecordGroups) {
1776 int matidx = g.radiance.data.materialindex;
1777 int matflags = materialcache[matidx].matflags;
1778 g.radiance.data.geomflags = matflags;
1779 g.shadow.data.geomflags = matflags;
1782 sync_hitgroupRecordGroups = 1;
1790 void TachyonOptiX::AABB_cone_array(
CUMemBuf &aabbBuffer,
1791 const float3 *base,
const float3 *apex,
1792 const float *brad,
const float *arad,
1795 std::vector<OptixAabb> hostAabb(primcnt);
1796 for (
int i=0; i<primcnt; i++) {
1799 float baserad = brad[i];
1800 float apexrad = arad[i];
1802 hostAabb[i].minX = fminf(b.x - baserad, a.x - apexrad);
1803 hostAabb[i].minY = fminf(b.y - baserad, a.y - apexrad);
1804 hostAabb[i].minZ = fminf(b.z - baserad, a.z - apexrad);
1805 hostAabb[i].maxX =
fmaxf(b.x + baserad, a.x + apexrad);
1806 hostAabb[i].maxY =
fmaxf(b.y + baserad, a.y + apexrad);
1807 hostAabb[i].maxZ =
fmaxf(b.z + baserad, a.z + apexrad);
1814 void TachyonOptiX::AABB_cylinder_array(
CUMemBuf &aabbBuffer,
1815 const float3 *base,
const float3 *apex,
1816 const float *rads,
int primcnt) {
1818 std::vector<OptixAabb> hostAabb(primcnt);
1819 for (
int i=0; i<primcnt; i++) {
1822 float rad = rads[i];
1824 hostAabb[i].minX = fminf(b.x - rad, a.x - rad);
1825 hostAabb[i].minY = fminf(b.y - rad, a.y - rad);
1826 hostAabb[i].minZ = fminf(b.z - rad, a.z - rad);
1827 hostAabb[i].maxX =
fmaxf(b.x + rad, a.x + rad);
1828 hostAabb[i].maxY =
fmaxf(b.y + rad, a.y + rad);
1829 hostAabb[i].maxZ =
fmaxf(b.z + rad, a.z + rad);
1836 void TachyonOptiX::AABB_quadmesh(
CUMemBuf &aabbBuffer,
const float3 *verts,
1837 const int4 *indices,
int primcnt) {
1839 std::vector<OptixAabb> hostAabb(primcnt);
1840 if (indices == NULL) {
1841 for (
int i=0; i<primcnt; i++) {
1844 float3 tmp = verts[idx4];
1852 tmp = verts[idx4+1];
1853 bbox.minX = fminf(bbox.minX, tmp.x);
1854 bbox.minY = fminf(bbox.minY, tmp.y);
1855 bbox.minZ = fminf(bbox.minZ, tmp.z);
1856 bbox.maxX =
fmaxf(bbox.maxX, tmp.x);
1857 bbox.maxY =
fmaxf(bbox.maxY, tmp.y);
1858 bbox.maxZ =
fmaxf(bbox.maxZ, tmp.z);
1860 tmp = verts[idx4+2];
1861 bbox.minX = fminf(bbox.minX, tmp.x);
1862 bbox.minY = fminf(bbox.minY, tmp.y);
1863 bbox.minZ = fminf(bbox.minZ, tmp.z);
1864 bbox.maxX =
fmaxf(bbox.maxX, tmp.x);
1865 bbox.maxY =
fmaxf(bbox.maxY, tmp.y);
1866 bbox.maxZ =
fmaxf(bbox.maxZ, tmp.z);
1868 tmp = verts[idx4+3];
1869 bbox.minX = fminf(bbox.minX, tmp.x);
1870 bbox.minY = fminf(bbox.minY, tmp.y);
1871 bbox.minZ = fminf(bbox.minZ, tmp.z);
1872 bbox.maxX =
fmaxf(bbox.maxX, tmp.x);
1873 bbox.maxY =
fmaxf(bbox.maxY, tmp.y);
1874 bbox.maxZ =
fmaxf(bbox.maxZ, tmp.z);
1879 for (
int i=0; i<primcnt; i++) {
1880 int4 index = indices[i];
1882 float3 tmp = verts[index.x];
1890 tmp = verts[index.y];
1891 bbox.minX = fminf(bbox.minX, tmp.x);
1892 bbox.minY = fminf(bbox.minY, tmp.y);
1893 bbox.minZ = fminf(bbox.minZ, tmp.z);
1894 bbox.maxX =
fmaxf(bbox.maxX, tmp.x);
1895 bbox.maxY =
fmaxf(bbox.maxY, tmp.y);
1896 bbox.maxZ =
fmaxf(bbox.maxZ, tmp.z);
1898 tmp = verts[index.z];
1899 bbox.minX = fminf(bbox.minX, tmp.x);
1900 bbox.minY = fminf(bbox.minY, tmp.y);
1901 bbox.minZ = fminf(bbox.minZ, tmp.z);
1902 bbox.maxX =
fmaxf(bbox.maxX, tmp.x);
1903 bbox.maxY =
fmaxf(bbox.maxY, tmp.y);
1904 bbox.maxZ =
fmaxf(bbox.maxZ, tmp.z);
1906 tmp = verts[index.w];
1907 bbox.minX = fminf(bbox.minX, tmp.x);
1908 bbox.minY = fminf(bbox.minY, tmp.y);
1909 bbox.minZ = fminf(bbox.minZ, tmp.z);
1910 bbox.maxX =
fmaxf(bbox.maxX, tmp.x);
1911 bbox.maxY =
fmaxf(bbox.maxY, tmp.y);
1912 bbox.maxZ =
fmaxf(bbox.maxZ, tmp.z);
1922 void TachyonOptiX::AABB_ring_array(
CUMemBuf &aabbBuffer,
1923 const float3 *pos,
const float *rads,
1926 std::vector<OptixAabb> hostAabb(primcnt);
1927 for (
int i=0; i<primcnt; i++) {
1928 float rad = rads[i];
1929 hostAabb[i].minX = pos[i].x - rad;
1930 hostAabb[i].minY = pos[i].y - rad;
1931 hostAabb[i].minZ = pos[i].z - rad;
1932 hostAabb[i].maxX = pos[i].x + rad;
1933 hostAabb[i].maxY = pos[i].y + rad;
1934 hostAabb[i].maxZ = pos[i].z + rad;
1941 void TachyonOptiX::AABB_sphere_array(
CUMemBuf &aabbBuffer,
1942 const float3 *pos,
const float *rads,
1945 std::vector<OptixAabb> hostAabb(primcnt);
1946 for (
int i=0; i<primcnt; i++) {
1947 float rad = rads[i];
1948 hostAabb[i].minX = pos[i].x - rad;
1949 hostAabb[i].minY = pos[i].y - rad;
1950 hostAabb[i].minZ = pos[i].z - rad;
1951 hostAabb[i].maxX = pos[i].x + rad;
1952 hostAabb[i].maxY = pos[i].y + rad;
1953 hostAabb[i].maxZ = pos[i].z + rad;
1961 void TachyonOptiX::AS_buildinp_AABB(OptixBuildInput &asInp,
1962 CUdeviceptr *aabbptr,
1963 uint32_t *flagptr,
int primcnt) {
1965 asInp.type = OPTIX_BUILD_INPUT_TYPE_CUSTOM_PRIMITIVES;
1968 #if (OPTIX_VERSION >= 70100) 1969 auto &primArray = asInp.customPrimitiveArray;
1971 auto &primArray = asInp.aabbArray;
1974 primArray.aabbBuffers = aabbptr;
1975 primArray.numPrimitives = primcnt;
1976 primArray.strideInBytes = 0;
1979 *flagptr = OPTIX_GEOMETRY_FLAG_REQUIRE_SINGLE_ANYHIT_CALL;
1980 primArray.flags = flagptr;
1982 primArray.numSbtRecords = 1;
1983 primArray.sbtIndexOffsetBuffer = 0;
1984 primArray.sbtIndexOffsetSizeInBytes = 0;
1985 primArray.sbtIndexOffsetStrideInBytes = 0;
1986 primArray.primitiveIndexOffset = 0;
1990 int TachyonOptiX::build_GAS(std::vector<OptixBuildInput> asInp,
1993 uint64_t *d_ASCompactedSize,
1994 OptixTraversableHandle &tvh,
1995 cudaStream_t GASstream) {
1997 const int arrayCount = asInp.size();
2000 OptixAccelBuildOptions asOpts = {};
2001 asOpts.motionOptions.numKeys = 1;
2002 asOpts.buildFlags = OPTIX_BUILD_FLAG_NONE |
2003 OPTIX_BUILD_FLAG_ALLOW_COMPACTION;
2004 asOpts.operation = OPTIX_BUILD_OPERATION_BUILD;
2006 OptixAccelBufferSizes blasBufSizes = {};
2007 optixAccelComputeMemoryUsage(optix_ctx, &asOpts, asInp.data(),
2008 arrayCount, &blasBufSizes);
2011 OptixAccelEmitDesc emitDesc = {};
2012 emitDesc.type = OPTIX_PROPERTY_TYPE_COMPACTED_SIZE;
2013 emitDesc.result = (CUdeviceptr) d_ASCompactedSize;
2021 if (ASTmpBuf.
get_size() < blasBufSizes.tempSizeInBytes)
2022 ASTmpBuf.
set_size(blasBufSizes.tempSizeInBytes, GASstream);
2025 outputBuffer.
set_size(blasBufSizes.outputSizeInBytes, GASstream);
2028 printf(
"TachyonOptiX) GAS/BLAS buffer sizes: temp %d output %d\n",
2029 blasBufSizes.tempSizeInBytes, blasBufSizes.outputSizeInBytes);
2033 optixAccelBuild(optix_ctx, GASstream, &asOpts, asInp.data(), arrayCount,
2036 &tvh, &emitDesc, 1);
2038 cudaStreamSynchronize(GASstream);
2046 uint64_t compactedSize = 0;
2047 cudaMemcpyAsync(&compactedSize, d_ASCompactedSize,
sizeof(uint64_t),
2048 cudaMemcpyDeviceToHost, GASstream);
2050 cudaStreamSynchronize(GASstream);
2051 printf(
"TachyonOptiX) GAS/BLAS compacted size: %ld\n", compactedSize);
2055 GASbuffer.
set_size(compactedSize, GASstream);
2056 optixAccelCompact(optix_ctx, GASstream, tvh,
2061 outputBuffer.
free(GASstream);
2063 cudaStreamSynchronize(GASstream);
2071 int TachyonOptiX::build_IAS(std::vector<OptixBuildInput> asInp,
2074 OptixTraversableHandle &tvh,
2075 cudaStream_t IASstream) {
2076 const int arrayCount = asInp.size();
2080 OptixAccelBuildOptions asOpts = {};
2081 asOpts.buildFlags = OPTIX_BUILD_FLAG_NONE;
2082 asOpts.operation = OPTIX_BUILD_OPERATION_BUILD;
2084 OptixAccelBufferSizes tlasBufSizes = {};
2085 optixAccelComputeMemoryUsage(optix_ctx, &asOpts, asInp.data(),
2086 arrayCount, &tlasBufSizes);
2092 if (ASTmpBuf.
get_size() < tlasBufSizes.tempSizeInBytes)
2093 ASTmpBuf.
set_size(tlasBufSizes.tempSizeInBytes, IASstream);
2097 if (IASbuf.
get_size() < tlasBufSizes.outputSizeInBytes)
2098 IASbuf.
set_size(tlasBufSizes.outputSizeInBytes, IASstream);
2101 printf(
"TachyonOptiX) IAS/TLAS buffer sizes: temp %d output %d\n",
2102 tlasBufSizes.tempSizeInBytes, tlasBufSizes.outputSizeInBytes);
2106 optixAccelBuild(optix_ctx, IASstream, &asOpts, asInp.data(), arrayCount,
2111 cudaStreamSynchronize(IASstream);
2119 OptixTraversableHandle TachyonOptiX::build_curves_GAS() {
2123 OptixTraversableHandle asHandle { 0 };
2125 #if OPTIX_VERSION >= 70100 2126 const int arrayCount = curvearrays.size();
2131 curveVertBuffers.resize(arrayCount);
2132 curveVertRadBuffers.resize(arrayCount);
2133 curveSegIdxBuffers.resize(arrayCount);
2136 curvePrimColorBuffers.resize(arrayCount);
2140 std::vector<OptixBuildInput> asCurveInp(arrayCount);
2141 std::vector<CUdeviceptr> d_vertices(arrayCount);
2142 std::vector<CUdeviceptr> d_vertrads(arrayCount);
2143 std::vector<uint32_t> asCurveInpFlags(arrayCount);
2150 for (
int i=0; i<arrayCount; i++) {
2152 curveVertBuffers[i].resize_upload(model.
vertices);
2153 curveVertRadBuffers[i].resize_upload(model.
vertradii);
2154 curveSegIdxBuffers[i].resize_upload(model.
segindices);
2159 curvePrimColorBuffers[i].resize_upload(model.
primcolors3f);
2162 asCurveInp[i].type = OPTIX_BUILD_INPUT_TYPE_CURVES;
2164 d_vertices[i] = curveVertBuffers[i].cu_dptr();
2165 d_vertrads[i] = curveVertRadBuffers[i].cu_dptr();
2168 auto &curveArray = asCurveInp[i].curveArray;
2169 curveArray.curveType = OPTIX_PRIMITIVE_TYPE_ROUND_LINEAR;
2170 #if OPTIX_VERSION >= 70400 2176 curveArray.numPrimitives = 1;
2177 curveArray.vertexBuffers = &d_vertices[i];
2178 curveArray.numVertices = 2;
2179 curveArray.vertexStrideInBytes =
sizeof(float3);
2182 curveArray.widthBuffers = &d_vertrads[i];
2183 curveArray.widthStrideInBytes =
sizeof(float);
2187 curveArray.normalBuffers = NULL;
2188 curveArray.normalStrideInBytes = 0;
2191 curveArray.indexBuffer = curveSegIdxBuffers[i].cu_dptr();
2192 curveArray.indexStrideInBytes =
sizeof(int);
2195 asCurveInpFlags[i] = OPTIX_GEOMETRY_FLAG_REQUIRE_SINGLE_ANYHIT_CALL;
2196 curveArray.flag = asCurveInpFlags[i];
2197 curveArray.primitiveIndexOffset = 0;
2199 #if OPTIX_VERSION >= 70400 2200 curveArray.endcapFlags = OPTIX_CURVE_ENDCAP_DEFAULT;
2205 build_GAS(asCurveInp, ASTempBuffer, curvesGASBuffer,
2206 (uint64_t *) compactedSizeBuffer.
cu_dptr(), asHandle, stream);
2214 OptixTraversableHandle TachyonOptiX::build_trimeshes_GAS() {
2219 const int arrayCount = trimeshes.size();
2224 triMeshVertBuffers.resize(arrayCount);
2225 triMeshIdxBuffers.resize(arrayCount);
2226 triMeshVertNormalBuffers.resize(arrayCount);
2227 triMeshVertPackedNormalBuffers.resize(arrayCount);
2228 triMeshVertColor3fBuffers.resize(arrayCount);
2229 triMeshVertColor4uBuffers.resize(arrayCount);
2230 triMeshPrimColorBuffers.resize(arrayCount);
2231 triMeshTex2dBuffers.resize(arrayCount);
2232 triMeshTex3dBuffers.resize(arrayCount);
2234 std::vector<OptixBuildInput> asTriInp(arrayCount);
2235 std::vector<CUdeviceptr> d_vertices(arrayCount);
2236 std::vector<uint32_t> asTriInpFlags(arrayCount);
2243 for (
int i=0; i<arrayCount; i++) {
2245 triMeshVertBuffers[i].resize_upload(model.
vertices, stream);
2246 triMeshIdxBuffers[i].resize_upload(model.
indices, stream);
2249 triMeshVertNormalBuffers[i].resize_upload(model.
normals, stream);
2250 triMeshVertPackedNormalBuffers[i].resize_upload(model.
packednormals, stream);
2251 triMeshVertColor3fBuffers[i].resize_upload(model.
vertcolors3f, stream);
2252 triMeshVertColor4uBuffers[i].resize_upload(model.
vertcolors4u, stream);
2253 triMeshPrimColorBuffers[i].resize_upload(model.
primcolors3f, stream);
2254 triMeshTex2dBuffers[i].resize_upload(model.
tex2d, stream);
2255 triMeshTex3dBuffers[i].resize_upload(model.
tex3d, stream);
2256 cudaStreamSynchronize(stream);
2259 asTriInp[i].type = OPTIX_BUILD_INPUT_TYPE_TRIANGLES;
2261 d_vertices[i] = triMeshVertBuffers[i].cu_dptr();
2264 auto &triArray = asTriInp[i].triangleArray;
2267 triArray.vertexBuffers = &d_vertices[i];
2268 triArray.numVertices = (int)model.
vertices.size();
2269 triArray.vertexFormat = OPTIX_VERTEX_FORMAT_FLOAT3;
2270 triArray.vertexStrideInBytes =
sizeof(float3);
2273 if (model.
indices.size() > 0) {
2274 triArray.indexBuffer = triMeshIdxBuffers[i].cu_dptr();
2275 triArray.numIndexTriplets = (int)model.
indices.size();
2276 triArray.indexFormat = OPTIX_INDICES_FORMAT_UNSIGNED_INT3;
2277 triArray.indexStrideInBytes =
sizeof(int3);
2279 triArray.indexBuffer = 0;
2280 triArray.numIndexTriplets = 0;
2281 #if OPTIX_VERSION >= 70100 2282 triArray.indexFormat = OPTIX_INDICES_FORMAT_NONE;
2284 triArray.indexStrideInBytes = 0;
2286 triArray.preTransform = 0;
2289 asTriInpFlags[i] = OPTIX_GEOMETRY_FLAG_REQUIRE_SINGLE_ANYHIT_CALL;
2290 triArray.flags = &asTriInpFlags[i];
2292 triArray.numSbtRecords = 1;
2293 triArray.sbtIndexOffsetBuffer = 0;
2294 triArray.sbtIndexOffsetSizeInBytes = 0;
2295 triArray.sbtIndexOffsetStrideInBytes = 0;
2296 triArray.primitiveIndexOffset = 0;
2301 OptixTraversableHandle asHandle;
2302 build_GAS(asTriInp, ASTempBuffer, trimeshesGASBuffer,
2303 (uint64_t *) compactedSizeBuffer.
cu_dptr(), asHandle, stream);
2310 OptixTraversableHandle TachyonOptiX::build_custprims_GAS() {
2318 const int coneCount = conearrays.size();
2319 coneBaseBuffers.resize(coneCount);
2320 coneApexBuffers.resize(coneCount);
2321 coneBaseRadBuffers.resize(coneCount);
2322 coneApexRadBuffers.resize(coneCount);
2323 conePrimColorBuffers.resize(coneCount);
2324 coneAabbBuffers.resize(coneCount);
2326 const int cyCount = cyarrays.size();
2327 cyStartBuffers.resize(cyCount);
2328 cyEndBuffers.resize(cyCount);
2329 cyRadiusBuffers.resize(cyCount);
2330 cyPrimColorBuffers.resize(cyCount);
2331 cyAabbBuffers.resize(cyCount);
2333 const int quadCount = quadmeshes.size();
2334 quadMeshVertBuffers.resize(quadCount);
2335 quadMeshIdxBuffers.resize(quadCount);
2336 quadMeshVertNormalBuffers.resize(quadCount);
2337 quadMeshVertPackedNormalBuffers.resize(quadCount);
2338 quadMeshVertColor3fBuffers.resize(quadCount);
2339 quadMeshVertColor4uBuffers.resize(quadCount);
2340 quadMeshPrimColorBuffers.resize(quadCount);
2341 quadMeshAabbBuffers.resize(quadCount);
2343 const int riCount = riarrays.size();
2344 riCenterBuffers.resize(riCount);
2345 riNormalBuffers.resize(riCount);
2346 riInRadiusBuffers.resize(riCount);
2347 riOutRadiusBuffers.resize(riCount);
2348 riPrimColorBuffers.resize(riCount);
2349 riAabbBuffers.resize(riCount);
2351 const int spCount = sparrays.size();
2352 spPosRadiusBuffers.resize(spCount);
2353 spPrimColorBuffers.resize(spCount);
2354 spAabbBuffers.resize(spCount);
2356 const int arrayCount = coneCount + cyCount + quadCount + riCount + spCount;
2358 std::vector<OptixBuildInput> asInp(arrayCount);
2359 std::vector<CUdeviceptr> d_aabb(arrayCount);
2360 std::vector<uint32_t> asInpFlags(arrayCount);
2370 for (
int i=0; i<coneCount; i++) {
2372 coneBaseBuffers[i].resize_upload(m.
base);
2373 coneApexBuffers[i].resize_upload(m.
apex);
2374 coneBaseRadBuffers[i].resize_upload(m.
baserad);
2375 coneApexRadBuffers[i].resize_upload(m.
apexrad);
2378 int primcnt = m.
base.size();
2379 AABB_cone_array(coneAabbBuffers[i], m.
base.data(), m.
apex.data(),
2381 int bidx = bufIdx + i;
2382 d_aabb[bidx] = coneAabbBuffers[i].cu_dptr();
2383 AS_buildinp_AABB(asInp[bidx], &d_aabb[bidx], &asInpFlags[bidx], primcnt);
2385 bufIdx += coneCount;
2388 for (
int i=0; i<cyCount; i++) {
2390 cyStartBuffers[i].resize_upload(m.
start);
2391 cyEndBuffers[i].resize_upload(m.
end);
2392 cyRadiusBuffers[i].resize_upload(m.
radius);
2395 int primcnt = m.
radius.size();
2396 AABB_cylinder_array(cyAabbBuffers[i], m.
start.data(), m.
end.data(),
2397 m.
radius.data(), primcnt);
2398 int bidx = bufIdx + i;
2399 d_aabb[bidx] = cyAabbBuffers[i].cu_dptr();
2400 AS_buildinp_AABB(asInp[bidx], &d_aabb[bidx], &asInpFlags[bidx], primcnt);
2405 for (
int i=0; i<quadCount; i++) {
2407 quadMeshVertBuffers[i].resize_upload(m.
vertices);
2408 quadMeshIdxBuffers[i].resize_upload(m.
indices);
2409 quadMeshVertNormalBuffers[i].resize_upload(m.
normals);
2410 quadMeshVertPackedNormalBuffers[i].resize_upload(m.
packednormals);
2411 quadMeshVertColor3fBuffers[i].resize_upload(m.
vertcolors3f);
2412 quadMeshVertColor4uBuffers[i].resize_upload(m.
vertcolors4u);
2413 quadMeshPrimColorBuffers[i].resize_upload(m.
primcolors3f);
2416 AABB_quadmesh(quadMeshAabbBuffers[i], m.
vertices.data(), m.
indices.data(), primcnt);
2417 int bidx = bufIdx + i;
2418 d_aabb[bidx] = quadMeshAabbBuffers[i].cu_dptr();
2419 AS_buildinp_AABB(asInp[bidx], &d_aabb[bidx], &asInpFlags[bidx], primcnt);
2421 bufIdx += quadCount;
2424 for (
int i=0; i<riCount; i++) {
2426 riCenterBuffers[i].resize_upload(m.
center);
2427 riNormalBuffers[i].resize_upload(m.
normal);
2428 riInRadiusBuffers[i].resize_upload(m.
inrad);
2429 riOutRadiusBuffers[i].resize_upload(m.
outrad);
2432 int primcnt = m.
outrad.size();
2433 AABB_ring_array(riAabbBuffers[i], m.
center.data(),
2434 m.
outrad.data(), primcnt);
2435 int bidx = bufIdx + i;
2436 d_aabb[bidx] = riAabbBuffers[i].cu_dptr();
2437 AS_buildinp_AABB(asInp[bidx], &d_aabb[bidx], &asInpFlags[bidx], primcnt);
2442 for (
int i=0; i<spCount; i++) {
2444 int sz = m.
radius.size();
2445 std::vector<float4 PINALLOCS(float4)> tmp(sz);
2446 for (
int j=0; j<sz; j++) {
2449 spPosRadiusBuffers[i].resize_upload(tmp);
2452 int primcnt = m.
radius.size();
2453 AABB_sphere_array(spAabbBuffers[i], m.
center.data(), m.
radius.data(), primcnt);
2454 int bidx = bufIdx + i;
2455 d_aabb[bidx] = spAabbBuffers[i].cu_dptr();
2456 AS_buildinp_AABB(asInp[bidx], &d_aabb[bidx], &asInpFlags[bidx], primcnt);
2460 OptixTraversableHandle asHandle;
2461 build_GAS(asInp, ASTempBuffer, custprimsGASBuffer,
2462 (uint64_t *) compactedSizeBuffer.
cu_dptr(), asHandle, stream);
2469 void TachyonOptiX::build_scene_IAS() {
2473 OptixTraversableHandle trimeshesGAS = {};
2474 OptixTraversableHandle curvesGAS = {};
2475 OptixTraversableHandle custprimsGAS = {};
2480 #if OPTIX_VERSION >= 70100 2488 int custprimcount = (conearrays.size() + cyarrays.size() +
2489 quadmeshes.size() + riarrays.size() +
2491 if (custprimcount > 0) {
2492 custprimsGAS = build_custprims_GAS();
2495 if (curvearrays.size() > 0) {
2496 curvesGAS = build_curves_GAS();
2499 if (trimeshes.size() > 0) {
2500 trimeshesGAS = build_trimeshes_GAS();
2504 std::vector<OptixInstance> instances;
2506 OptixInstance tmpInst = {};
2508 float identity_xform3x4[12] = {
2509 1.0f, 0.0f, 0.0f, 0.0f,
2510 0.0f, 1.0f, 0.0f, 0.0f,
2511 0.0f, 0.0f, 1.0f, 0.0f
2515 memcpy(i.transform, identity_xform3x4,
sizeof(identity_xform3x4));
2518 i.visibilityMask = 0xFF;
2519 i.flags = OPTIX_INSTANCE_FLAG_NONE;
2522 i.traversableHandle = custprimsGAS;
2523 i.sbtOffset = sbtOffset;
2524 instances.push_back(i);
2530 i.traversableHandle = curvesGAS;
2531 i.sbtOffset = sbtOffset;
2532 instances.push_back(i);
2538 i.traversableHandle = trimeshesGAS;
2539 i.sbtOffset = sbtOffset;
2540 instances.push_back(i);
2546 printf(
"TachyonOptiX) custprimsGAS: %p\n", custprimsGAS);
2547 printf(
"TachyonOptiX) curvesGAS: %p\n", curvesGAS);
2548 printf(
"TachyonOptiX) trimeshesGAS: %p\n", trimeshesGAS);
2549 printf(
"TachyonOptiX) i.traversable: %p\n", i.traversableHandle);
2550 printf(
"TachyonOptiX) instance[0].traversable: %p\n", instances[0].traversableHandle);
2556 std::vector<OptixBuildInput> asInstInp(1);
2558 asInstInp[0].type = OPTIX_BUILD_INPUT_TYPE_INSTANCES;
2559 asInstInp[0].instanceArray.instances = devinstances.
cu_dptr();
2560 asInstInp[0].instanceArray.numInstances = (int) instances.size();
2562 OptixTraversableHandle asHandle { 0 };
2563 build_IAS(asInstInp, ASTempBuffer, IASBuffer, asHandle, stream);
2566 devinstances.
free(stream);
2574 void TachyonOptiX::destroy_context() {
2576 if (!context_created)
2583 ASTempBuffer.
free();
2584 compactedSizeBuffer.
free();
2587 context_destroy_pipeline();
2588 context_destroy_module();
2590 #if defined(TACHYON_OPTIXDENOISER) 2591 context_destroy_denoiser();
2596 launchParamsBuffer.
free();
2597 materialsBuffer.
free();
2598 directionalLightsBuffer.
free();
2599 positionalLightsBuffer.
free();
2601 optixDeviceContextDestroy(optix_ctx);
2603 regen_optix_pipeline=1;
2605 regen_optix_lights=1;
2621 int texflags,
int userindex) {
2624 int oldtexcount = texturecache.size();
2625 if (oldtexcount <= userindex) {
2629 memset(&t, 0,
sizeof(t));
2632 texturecache.resize(userindex+1);
2633 for (
int i=oldtexcount; i<=userindex; i++) {
2638 if (texturecache[userindex].userindex > 0) {
2641 if (verbose ==
RT_VERB_DEBUG) printf(
"TachyonOptiX) Adding texture[%d]\n", userindex);
2643 cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<uchar4>();
2644 cudaArray_t texArray;
2645 cudaMallocArray(&texArray, &channelDesc, xres, yres);
2649 const size_t spitch = xres *
sizeof(float);
2650 cudaMemcpy2DToArray(texArray, 0, 0, img, spitch, xres *
sizeof(
float),
2651 yres, cudaMemcpyHostToDevice);
2653 cudaResourceDesc resDesc;
2654 memset(&resDesc, 0,
sizeof(resDesc));
2655 resDesc.resType = cudaResourceTypeArray;
2656 resDesc.res.array.array = texArray;
2658 cudaTextureDesc texDesc;
2659 memset(&texDesc, 0,
sizeof(texDesc));
2660 texDesc.addressMode[0] = cudaAddressModeWrap;
2661 texDesc.addressMode[1] = cudaAddressModeWrap;
2662 texDesc.filterMode = cudaFilterModeLinear;
2663 texDesc.readMode = cudaReadModeNormalizedFloat;
2664 texDesc.normalizedCoords = 1;
2672 cudaTextureObject_t texObj = 0;
2673 cudaCreateTextureObject(&texObj, &resDesc, &texDesc, NULL);
2675 texturecache[userindex].texflags = texflags;
2676 texturecache[userindex].d_img = texArray;
2677 texturecache[userindex].tex = texObj;
2678 texturecache[userindex].userindex=userindex;
2686 int xres,
int yres,
int zres,
2687 int texflags,
int userindex) {
2690 int oldtexcount = texturecache.size();
2691 if (oldtexcount <= userindex) {
2695 memset(&t, 0,
sizeof(t));
2698 texturecache.resize(userindex+1);
2699 for (
int i=oldtexcount; i<=userindex; i++) {
2704 if (texturecache[userindex].userindex > 0) {
2707 if (verbose ==
RT_VERB_DEBUG) printf(
"TachyonOptiX) Adding texture[%d]\n", userindex);
2710 cudaExtent gridExtent = make_cudaExtent(xres, yres, zres);
2711 cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<uchar4>();
2713 cudaArray_t texArray;
2714 cudaMalloc3DArray(&texArray, &channelDesc, gridExtent);
2716 cudaMemcpy3DParms copyParams = {0};
2717 copyParams.srcPtr = make_cudaPitchedPtr((
void*)img,
2718 gridExtent.width*
sizeof(uchar4),
2721 copyParams.dstArray = texArray;
2722 copyParams.extent = gridExtent;
2723 copyParams.kind = cudaMemcpyHostToDevice;
2724 cudaMemcpy3D(©Params);
2726 cudaResourceDesc resDesc;
2727 memset(&resDesc, 0,
sizeof(resDesc));
2728 resDesc.resType = cudaResourceTypeArray;
2729 resDesc.res.array.array = texArray;
2731 cudaTextureDesc texDesc;
2732 memset(&texDesc, 0,
sizeof(texDesc));
2733 texDesc.addressMode[0] = cudaAddressModeClamp;
2734 texDesc.addressMode[1] = cudaAddressModeClamp;
2735 texDesc.addressMode[2] = cudaAddressModeClamp;
2736 texDesc.filterMode = cudaFilterModeLinear;
2737 texDesc.readMode = cudaReadModeNormalizedFloat;
2738 texDesc.normalizedCoords = 1;
2745 cudaTextureObject_t texObj = 0;
2746 cudaCreateTextureObject(&texObj, &resDesc, &texDesc, NULL);
2748 texturecache[userindex].texflags = texflags;
2749 texturecache[userindex].d_img = texArray;
2750 texturecache[userindex].tex = texObj;
2751 texturecache[userindex].userindex=userindex;
2763 float shininess,
float reflectivity,
2764 float opacity,
float outline,
float outlinewidth,
2765 int transmode,
int userindex) {
2767 reflectivity, opacity, outline, outlinewidth,
2768 transmode, -1, userindex);
2772 float specular,
float shininess,
2773 float reflectivity,
float opacity,
2774 float outline,
float outlinewidth,
2776 int texindex,
int userindex) {
2779 int oldmatcount = materialcache.size();
2780 if (oldmatcount <= userindex) {
2795 materialcache.resize(userindex+1);
2796 for (
int i=oldmatcount; i<=userindex; i++) {
2801 if (materialcache[userindex].userindex > 0) {
2804 if (verbose ==
RT_VERB_DEBUG) printf(
"TachyonOptiX) Adding material[%d]\n", userindex);
2806 materialcache[userindex].ambient = ambient;
2807 materialcache[userindex].diffuse = diffuse;
2808 materialcache[userindex].specular = specular;
2809 materialcache[userindex].shininess = shininess;
2810 materialcache[userindex].reflectivity = reflectivity;
2811 materialcache[userindex].opacity = opacity;
2812 materialcache[userindex].outline = outline;
2813 materialcache[userindex].outlinewidth = outlinewidth;
2814 materialcache[userindex].transmode = transmode;
2815 materialcache[userindex].tex = 0;
2816 materialcache[userindex].matflags = 0;
2817 materialcache[userindex].userindex=userindex;
2819 if (opacity < 1.0f) {
2824 if (texindex >= 0) {
2825 materialcache[userindex].tex = texturecache[texindex].tex;
2827 printf(
"mat[%d] texid: %llu\n", userindex, texturecache[texindex].tex);
2834 printf(
"mat[%d] uses cutout alpha texture, matflags: %08x\n",
2835 userindex, materialcache[userindex].matflags);
2840 regen_optix_materials=1;
2848 if (verbose ==
RT_VERB_DEBUG) printf(
"TachyonOptiX) init_materials()\n");
2850 materialcache.clear();
2851 regen_optix_materials=1;
2859 directional_lights.push_back(l);
2860 regen_optix_lights=1;
2868 positional_lights.push_back(l);
2869 regen_optix_lights=1;
2875 double starttime = wkf_timer_timenow(
rt_timer);
2876 time_ctx_destroy_scene = 0;
2879 cylinder_array_cnt = 0;
2880 cylinder_array_color_cnt = 0;
2881 ring_array_color_cnt = 0;
2882 sphere_array_cnt = 0;
2883 sphere_array_color_cnt = 0;
2885 trimesh_c4u_n3b_v3f_cnt = 0;
2886 trimesh_n3b_v3f_cnt = 0;
2887 trimesh_n3f_v3f_cnt = 0;
2888 trimesh_v3f_cnt = 0;
2890 if (!context_created)
2895 if (scene_created) {
2899 for (
auto &&buf : coneAabbBuffers) buf.free();
2900 coneAabbBuffers.clear();
2901 for (
auto &&buf : coneBaseBuffers) buf.free();
2902 coneBaseBuffers.clear();
2903 for (
auto &&buf : coneApexBuffers) buf.free();
2904 coneApexBuffers.clear();
2905 for (
auto &&buf : coneBaseRadBuffers) buf.free();
2906 coneBaseRadBuffers.clear();
2907 for (
auto &&buf : coneApexRadBuffers) buf.free();
2908 coneApexRadBuffers.clear();
2909 for (
auto &&buf : conePrimColorBuffers) buf.free();
2910 conePrimColorBuffers.clear();
2913 for (
auto &&buf : curveVertBuffers) buf.free();
2914 curveVertBuffers.clear();
2915 for (
auto &&buf : curveVertRadBuffers) buf.free();
2916 curveVertRadBuffers.clear();
2917 for (
auto &&buf : curveSegIdxBuffers) buf.free();
2918 curveSegIdxBuffers.clear();
2919 for (
auto &&buf : curvePrimColorBuffers) buf.free();
2920 curvePrimColorBuffers.clear();
2921 curvearrays.clear();
2923 for (
auto &&buf : cyAabbBuffers) buf.free();
2924 cyAabbBuffers.clear();
2925 for (
auto &&buf : cyStartBuffers) buf.free();
2926 cyStartBuffers.clear();
2927 for (
auto &&buf : cyEndBuffers) buf.free();
2928 cyEndBuffers.clear();
2929 for (
auto &&buf : cyRadiusBuffers) buf.free();
2930 cyRadiusBuffers.clear();
2931 for (
auto &&buf : cyPrimColorBuffers) buf.free();
2932 cyPrimColorBuffers.clear();
2935 for (
auto &&buf : quadMeshAabbBuffers) buf.free();
2936 quadMeshAabbBuffers.clear();
2937 for (
auto &&buf : quadMeshVertBuffers) buf.free();
2938 quadMeshVertBuffers.clear();
2939 for (
auto &&buf : quadMeshIdxBuffers) buf.free();
2940 quadMeshIdxBuffers.clear();
2941 for (
auto &&buf : quadMeshVertNormalBuffers) buf.free();
2942 quadMeshVertNormalBuffers.clear();
2943 for (
auto &&buf : quadMeshVertPackedNormalBuffers) buf.free();
2944 quadMeshVertPackedNormalBuffers.clear();
2945 for (
auto &&buf : quadMeshVertColor3fBuffers) buf.free();
2946 quadMeshVertColor3fBuffers.clear();
2947 for (
auto &&buf : quadMeshVertColor4uBuffers) buf.free();
2948 quadMeshVertColor4uBuffers.clear();
2949 for (
auto &&buf : quadMeshPrimColorBuffers) buf.free();
2950 quadMeshPrimColorBuffers.clear();
2953 for (
auto &&buf : riAabbBuffers) buf.free();
2954 riAabbBuffers.clear();
2955 for (
auto &&buf : riCenterBuffers) buf.free();
2956 riCenterBuffers.clear();
2957 for (
auto &&buf : riNormalBuffers) buf.free();
2958 riNormalBuffers.clear();
2959 for (
auto &&buf : riInRadiusBuffers) buf.free();
2960 riInRadiusBuffers.clear();
2961 for (
auto &&buf : riOutRadiusBuffers) buf.free();
2962 riOutRadiusBuffers.clear();
2963 for (
auto &&buf : riPrimColorBuffers) buf.free();
2964 riPrimColorBuffers.clear();
2967 for (
auto &&buf : spAabbBuffers) buf.free();
2968 spAabbBuffers.clear();
2969 for (
auto &&buf : spPosRadiusBuffers) buf.free();
2970 spPosRadiusBuffers.clear();
2971 for (
auto &&buf : spPrimColorBuffers) buf.free();
2972 spPrimColorBuffers.clear();
2975 for (
auto &&buf : triMeshVertBuffers) buf.free();
2976 triMeshVertBuffers.clear();
2977 for (
auto &&buf : triMeshIdxBuffers) buf.free();
2978 triMeshIdxBuffers.clear();
2979 for (
auto &&buf : triMeshVertNormalBuffers) buf.free();
2980 triMeshVertNormalBuffers.clear();
2981 for (
auto &&buf : triMeshVertPackedNormalBuffers) buf.free();
2982 triMeshVertPackedNormalBuffers.clear();
2983 for (
auto &&buf : triMeshVertColor3fBuffers) buf.free();
2984 triMeshVertColor3fBuffers.clear();
2985 for (
auto &&buf : triMeshVertColor4uBuffers) buf.free();
2986 triMeshVertColor4uBuffers.clear();
2987 for (
auto &&buf : triMeshPrimColorBuffers) buf.free();
2988 triMeshPrimColorBuffers.clear();
2989 for (
auto &&buf : triMeshTex2dBuffers) buf.free();
2990 triMeshTex2dBuffers.clear();
2991 for (
auto &&buf : triMeshTex3dBuffers) buf.free();
2992 triMeshTex3dBuffers.clear();
3000 #if OPTIX_VERSION >= 70100 3006 double endtime = wkf_timer_timenow(
rt_timer);
3007 time_ctx_destroy_scene = endtime - starttime;
3040 if (!context_created)
3049 colorspace=colspace;
3054 if (!context_created)
3061 int fbsz = width * height *
sizeof(uchar4);
3062 framebuffer.
set_size(fbsz, stream);
3064 int acsz = width * height *
sizeof(float4);
3065 accumulation_buffer.
set_size(acsz, stream);
3067 #if defined(TACHYON_OPTIXDENOISER) 3068 denoiser_resize_update();
3071 #if defined(TACHYON_RAYSTATS) 3072 int assz = width * height *
sizeof(uint4);
3073 raystats1_buffer.set_size(assz, stream);
3074 raystats2_buffer.set_size(assz, stream);
3080 printf(
"TachyonOptiX) framebuffer_resize(%d x %d)\n", width, height);
3099 auto fbsz = framebuffer.
get_size();
3100 cudaMemsetAsync(framebuffer.
dptr(), 0, fbsz, stream);
3102 auto acsz = accumulation_buffer.
get_size();
3103 cudaMemsetAsync(accumulation_buffer.
dptr(), 0, acsz, stream);
3105 #if defined(TACHYON_RAYSTATS) 3107 auto assz = raystats1_buffer.get_size();
3108 cudaMemsetAsync(raystats1_buffer.dptr(), 0, assz, stream);
3109 cudaMemsetAsync(raystats2_buffer.dptr(), 0, assz, stream);
3112 cudaStreamSynchronize(stream);
3116 printf(
"TachyonOptiX) framebuffer_clear(%d x %d)\n", width, height);
3122 framebuffer.
download(imgrgb4u, width * height *
sizeof(
int));
3128 if (!context_created)
3132 accumulation_buffer.
free();
3133 #if defined(TACHYON_RAYSTATS) 3134 raystats1_buffer.free();
3135 raystats2_buffer.free();
3140 void TachyonOptiX::render_compile_and_validate(
void) {
3142 if (!context_created)
3148 double startctxtime = wkf_timer_timenow(
rt_timer);
3153 if (regen_optix_pipeline) {
3154 if (pipe !=
nullptr)
3155 context_destroy_pipeline();
3156 context_create_pipeline();
3158 if ((lasterr != OPTIX_SUCCESS) )
3159 printf(
"TachyonOptiX) An error occured during pipeline regen!\n");
3162 double start_AS_build = wkf_timer_timenow(
rt_timer);
3166 if ((lasterr != OPTIX_SUCCESS) )
3167 printf(
"TachyonOptiX) An error occured during AS regen!\n");
3170 if (regen_optix_sbt) {
3172 SBT_create_programs();
3173 SBT_create_hitgroups();
3175 }
else if (regen_optix_materials) {
3180 SBT_update_hitgroup_geomflags();
3186 if ((lasterr != OPTIX_SUCCESS) )
3187 printf(
"TachyonOptiX) An error occured during SBT regen!\n");
3189 time_ctx_AS_build = wkf_timer_timenow(
rt_timer) - start_AS_build;
3192 if (regen_optix_materials) {
3194 regen_optix_materials=0;
3198 if (regen_optix_lights) {
3201 regen_optix_lights=0;
3204 if ((lasterr != OPTIX_SUCCESS) )
3205 printf(
"TachyonOptiX) An error occured during materials/lights regen!\n");
3220 #if defined(TACHYON_OPTIXDENOISER) 3221 rtLaunch.
frame.denoiser_colorbuffer = (float4*) denoiser_colorbuffer.cu_dptr();
3225 #if defined(TACHYON_RAYSTATS) 3226 rtLaunch.
frame.raystats1_buffer = (uint4*) raystats1_buffer.cu_dptr();
3227 rtLaunch.
frame.raystats2_buffer = (uint4*) raystats2_buffer.cu_dptr();
3254 scene_bg_grad_top[1],
3255 scene_bg_grad_top[2]);
3257 scene_bg_grad_bot[1],
3258 scene_bg_grad_bot[2]);
3260 scene_bg_grad_updir[1],
3261 scene_bg_grad_updir[2]);
3266 scene_bg_grad_invrange = 1.0f / (scene_bg_grad_topval - scene_bg_grad_botval);
3309 time_ctx_validate = wkf_timer_timenow(
rt_timer) - startctxtime;
3312 printf(
"TachyonOptiX) launching render: %d x %d\n", width, height);
3321 if (!context_created)
3328 if (!context_created)
3332 double rendstarttime = wkf_timer_timenow(
rt_timer);
3337 render_compile_and_validate();
3338 double starttime = wkf_timer_timenow(
rt_timer);
3343 if (lasterr == OPTIX_SUCCESS) {
3348 int samples_per_pass = 1;
3352 for (
int p=0; p<aa_samples; p+=samples_per_pass) {
3365 if (p >= (aa_samples - samples_per_pass)) {
3375 lasterr = optixLaunch(pipe, stream,
3383 cudaStreamSynchronize(stream);
3390 if (lasterr != OPTIX_SUCCESS) {
3391 printf(
"TachyonOptiX) Error during rendering. Rendering aborted.\n");
3394 double rtendtime = wkf_timer_timenow(
rt_timer);
3395 time_ray_tracing = rtendtime - starttime;
3396 double totalrendertime = rtendtime - rendstarttime;
3403 cudaStreamSynchronize(stream);
3404 double denoiseendtime = wkf_timer_timenow(
rt_timer);
3405 double denoise_time = denoiseendtime - rtendtime;
3408 if (lasterr != OPTIX_SUCCESS) {
3409 printf(
"TachyonOptiX) Error during denoising. Rendering aborted.\n");
3413 printf(
"TachyonOptiX) Render Time: %.2fms, %.1fFPS\n",
3414 totalrendertime * 1.0e3, 1.0 / totalrendertime);
3415 printf(
"TachyonOptiX) (AS %.2fms, RT %.2fms, DN %.2fms, io %.2fms)\n",
3416 time_ctx_AS_build * 1.0e3, time_ray_tracing * 1.0e3,
3417 denoise_time * 1.0e3, time_image_io * 1.0e3);
3420 printf(
"TachyonOptiX) An error occured prior to rendering. Rendering aborted.\n");
3433 #if defined(TACHYON_RAYSTATS) 3436 printf(
"TachyonOptiX) No data in ray stats buffers!\n");
3442 size_t bufsz = framesz *
sizeof(uint4);
3443 uint4 *raystats1 = (uint4 *) calloc(1, bufsz);
3444 uint4 *raystats2 = (uint4 *) calloc(1, bufsz);
3445 raystats1_buffer.download(raystats1, framesz);
3446 raystats2_buffer.download(raystats2, framesz);
3451 printf(
"TachyonOptiX) No data in ray stats buffers!\n");
3456 unsigned long misses=0, transkips=0, primaryrays=0, shadowlights=0,
3457 shadowao=0, transrays=0, reflrays=0;
3460 for (
int i=0; i<framesz; i++) {
3461 primaryrays += raystats1[i].x;
3462 shadowlights += raystats1[i].y;
3463 shadowao += raystats1[i].z;
3464 misses += raystats1[i].w;
3465 transrays += raystats2[i].x;
3466 transkips += raystats2[i].y;
3468 reflrays += raystats2[i].w;
3470 unsigned long totalrays = primaryrays + shadowlights + shadowao
3471 + transrays + reflrays;
3473 printf(
"TachyonOptiX)\n");
3474 printf(
"TachyonOptiX) TachyonOptiX Scene Ray Tracing Statistics:\n");
3475 printf(
"TachyonOptiX) ----------------------------------------\n");
3476 printf(
"TachyonOptiX) Image resolution: %d x %d \n",
3478 printf(
"TachyonOptiX) Pixel count: %d\n", framesz);
3479 printf(
"TachyonOptiX) ----------------------------------------\n");
3480 printf(
"TachyonOptiX) Misses: %lu\n", misses);
3481 printf(
"TachyonOptiX) Transmission Any-Hit Skips: %lu\n", transkips);
3482 printf(
"TachyonOptiX) ----------------------------------------\n");
3483 printf(
"TachyonOptiX) Primary Rays: %lu\n", primaryrays);
3484 printf(
"TachyonOptiX) Dir-Light Shadow Rays: %lu\n", shadowlights);
3485 printf(
"TachyonOptiX) AO Shadow Rays: %lu\n", shadowao);
3486 printf(
"TachyonOptiX) Transmission Rays: %lu\n", transrays);
3487 printf(
"TachyonOptiX) Reflection Rays: %lu\n", reflrays);
3488 printf(
"TachyonOptiX) ----------------------------------------\n");
3489 printf(
"TachyonOptiX) Total Rays: %lu\n", totalrays);
3490 printf(
"TachyonOptiX) Total Rays: %g\n", totalrays * 1.0);
3491 if (time_ray_tracing > 0.0) {
3492 printf(
"TachyonOptiX) Pure ray tracing rays/sec: %g\n", totalrays / time_ray_tracing);
3494 double totalruntime = time_ray_tracing + time_ctx_AS_build;
3495 if (totalruntime > 0.0) {
3496 printf(
"TachyonOptiX) Overall effective rays/sec: %g\n", totalrays / totalruntime);
3498 printf(
"TachyonOptiX)\n");
3503 printf(
"TachyonOptiX) Compiled without ray stats buffers!\n");
3514 printf(
"TachyonOptiX) internal data structure information\n");
3516 printf(
"TachyonOptiX) Hitgroup SBT record info:\n");
3517 printf(
" SBT rec align size: %d b\n", OPTIX_SBT_RECORD_ALIGNMENT);
3518 printf(
" total size: %d b\n",
sizeof(HGRecord));
3519 printf(
" header size: %d b\n",
sizeof(((HGRecord*)0)->header));
3520 printf(
" data offset: %d b\n", offsetof(HGRecord, data));
3521 printf(
" data size: %d b\n",
sizeof(((HGRecord*)0)->data));
3522 printf(
" material size: %d b\n", offsetof(HGRecord, data.cone) - offsetof(HGRecord, data.prim_color));
3523 printf(
" geometry size: %d b\n",
sizeof(HGRecord) - offsetof(HGRecord, data.trimesh));
3525 printf(
" prim_color offset: %d b\n", offsetof(HGRecord, data.prim_color));
3526 printf(
" uniform_color offset: %d b\n", offsetof(HGRecord, data.uniform_color));
3527 printf(
" materialindex offset: %d b\n", offsetof(HGRecord, data.materialindex));
3528 printf(
" geometry offset: %d b\n", offsetof(HGRecord, data.cone));
3531 printf(
" geometry union size: %d b\n",
sizeof(HGRecord) - offsetof(HGRecord, data.trimesh));
3532 printf(
" cone sz: %d b\n",
sizeof(((HGRecord*)0)->data.cone ));
3533 printf(
" cyl sz: %d b\n",
sizeof(((HGRecord*)0)->data.cyl ));
3534 printf(
" ring sz: %d b\n",
sizeof(((HGRecord*)0)->data.ring ));
3535 printf(
" sphere sz: %d b\n",
sizeof(((HGRecord*)0)->data.sphere ));
3536 printf(
" trimesh sz: %d b\n",
sizeof(((HGRecord*)0)->data.trimesh));
3537 printf(
" WASTED hitgroup sz: %d b\n",
sizeof(HGRecord) - (
sizeof(((HGRecord*)0)->header) +
sizeof(((HGRecord*)0)->data)));
3548 sceneinstancegroups.push_back(g);
3549 return int(sceneinstancegroups.size()) - 1;
3564 int TachyonOptiX::set_geom_instance_group_xforms(
int idx,
int n,
float [][16]) {
3574 if (!context_created)
3579 conearrays.push_back(newmodel);
3584 if (!context_created)
3589 curvearrays.push_back(newmodel);
3594 if (!context_created)
3599 cyarrays.push_back(newmodel);
3605 if (!context_created)
3610 quadmeshes.push_back(newmodel);
3616 if (!context_created)
3621 riarrays.push_back(newmodel);
3627 if (!context_created)
3632 sparrays.push_back(newmodel);
3638 if (!context_created)
3643 trimeshes.push_back(newmodel);
3651 char *TachyonOptiX::internal_compiled_ptx_src(
void) {
3652 #if 1 && defined(TACHYON_INTERNAL_COMPILED_SRC) 3653 const char *ptxsrc =
3654 #include "TachyonOptiXShaders.ptxinc" 3657 int len = strlen(ptxsrc);
3658 char *ptxstring = (
char *) calloc(1, len + 1);
3659 strcpy(ptxstring, ptxsrc);
__host__ __device__ float3 normalize(const float3 &v)
Normalize input vector to unit length.
float3 U
camera orthonormal U (right) axis
Several OptiX APIs make use of CUDA driver API pointer types (CUdevicepointer) so it becomes worthwhi...
void minimize_memory_use(void)
reduce active memory footprint without destroying the scene by freeing internal temporary buffers use...
std::vector< float3 PINALLOCS(float3)> center
std::vector< float3 PINALLOCS(float3)> primcolors3f
omnidirectional octahedral
std::vector< uint4 PINALLOCS(uint4) > packednormals
std::vector< float3 PINALLOCS(float3)> center
uchar4 * framebuffer
8-bit unorm RGBA framebuffer
float accum_normalize
precalc 1.0f / subframe_index
std::vector< float3 PINALLOCS(float3)> vertcolors3f
int matflags
alpha/cutout transparency flags
int headlight_mode
Extra VR camera-located headlight.
void free()
free allocated memory
int add_tex3d_rgba4u(const unsigned char *img, int xres, int yres, int zres, int texflags, int userindex)
define image to be used in a texture map
float bg_grad_invrange
miss background gradient inverse range
float3 bg_grad_updir
miss background gradient up direction
int create_geom_instance_group()
Create geometry instance group.
std::vector< float PINALLOCS(float)> radius
__constant__ tachyonLaunchParams rtLaunch
launch parameters in constant memory, filled by optixLaunch)
int update_colorbuffer
accumulation copyout flag
int add_tex2d_rgba4u(const unsigned char *img, int xres, int yres, int texflags, int userindex)
define image to be used in a texture map
cudaTextureObject_t tex
texture, non-zero if valid
static TachyonOptiX::Verbosity get_verbose_flag(int inform=0)
int tonemap_mode
output tone mapping mode
int add_material_textured(float ambient, float diffuse, float specular, float shininess, float reflectivity, float opacity, float outline, float outlinewidth, int transmode, int textureindex, int userindex)
float ao_lightscale
2.0f/float(ao_samples)
std::vector< int PINALLOCS(int)> segindices
float dof_aperture_rad
DoF (defocus blur) aperture radius.
std::vector< float3 PINALLOCS(float3)> apex
float reflectivity
mirror reflectance coefficient
float shininess
specular highlight size (exponential)
void print_internal_struct_info(void)
diagnostic info routines
float ao_maxdist
AO maximum occlusion distance.
__host__ __device__ float4 make_float4(const float3 &a, const float &b)
size_t get_size(void)
query current buffer size in bytes
ring SBT index multiplier
__host__ __device__ float3 make_float3(const float s)
void add_directional_light(const float *dir, const float *color)
float3 W
camera orthonormal W (view) axis
__host__ __device__ float3 fmaxf(const float3 &a, const float3 &b)
float3 pos
camera position
std::vector< float3 PINALLOCS(float3)> base
std::vector< float3 PINALLOCS(float3)> primcolors3f
int max_trans
max transparent surface crossing count
float tonemap_exposure
tone mapping exposure gain parameter
cylinder SBT index multiplier
std::vector< float3 PINALLOCS(float3) > tex3d
int userindex
material user index, positive if valid
float ao_direct
AO direct lighting scaling factor.
int add_material(float ambient, float diffuse, float specular, float shininess, float reflectivity, float opacity, float outline, float outlinewidth, int transmode, int userindex)
add a material with an associated user-provided index
std::vector< float PINALLOCS(float)> apexrad
void add_curvearray(CurveArray &model, int matidx)
CPU and GPU profiling utility macros/routines.
int fb_clearall
clear/overwrite all FB components
struct tachyonLaunchParams::@4 lights
__host__ __device__ float3 fabsf(const float3 &a)
#define PROFILE_PUSH_RANGE(name, cid)
Pushes a time range annotation onto the profiler's trace stack, beginning at the time of submission...
std::vector< float PINALLOCS(float)> radius
int fog_mode
fog type (or off)
void framebuffer_resize(int fbwidth, int fbheight)
std::vector< float3 PINALLOCS(float3) > normals
std::vector< float3 PINALLOCS(float3)> primcolors3f
float3 pos
point light position
static int device_count(void)
static GPU device query
void set_camera_lookat(const float *at, const float *V)
set camera orientation to look "at" a point in space, with a given "up" direction (camera ONB "V" vec...
CUdeviceptr cu_dptr() const
int destroy_geom_instance_group(int idx)
void print_raystats_info(void)
report performance statistics
float bg_grad_topval
miss background gradient top value
std::vector< float3 PINALLOCS(float3) > vertices
float dof_focal_dist
DoF focal plane distance.
void framebuffer_destroy(void)
enable cutout/transparency
static int device_list(int **, char ***)
static methods for querying OptiX-supported GPU hardware independent of whether we actually have an a...
std::vector< float3 PINALLOCS(float3)> start
#define RTPROF_RENDER
trace color for overall rendering
structure containing Tachyon texture (only used on host side)
Output timing/perf data only.
float3 dir
directional light direction
conventional orthographic
float fog_end
radial/linear fog end/max distance
#define RTPROF_GEOM
trace color for geometry processing
void framebuffer_clear(void)
int shadows_enabled
global shadow flag
int transmode
transparency behavior
int stereo_enabled
stereo rendering on/off
void add_spherearray(SphereArray &model, int matidx)
float3 * dir_lights
list of directional light directions
void update_rendering_state(int interactive)
float bg_grad_botval
miss background gradient bottom value
void add_ringarray(RingArray &model, int matidx)
struct tachyonLaunchParams::@3 scene
float fog_start
radial/linear fog start distance
float specular
specular reflectance coefficient
enable alpha transparency
std::vector< float PINALLOCS(float)> inrad
std::vector< float3 PINALLOCS(float3) > vertcolors3f
void add_conearray(ConeArray &model, int matidx)
#define PROFILE_POP_RANGE()
Pops the innermost time range off of the profiler's trace stack, at the time of execution.
only clamp the color values [0,1]
std::vector< float3 PINALLOCS(float3)> primcolors3f
#define RTPROF_RENDERRT
trace color for specifically for RT
void log_callback(unsigned int level, const char *tag, const char *msg)
console output logging callback
float3 V
camera orthonormal V (up) axis
std::vector< float3 PINALLOCS(float3)> primcolors3f
void set_size(size_t newsize)
(re)allocate buffer of requested size
std::vector< float2 PINALLOCS(float2) > tex2d
std::vector< float3 PINALLOCS(float3)> vertices
std::vector< float3 PINALLOCS(float3)> normal
#define RTPROF_GENERAL
trace color for general operations
std::vector< int4 PINALLOCS(int4)> indices
std::vector< uchar4 PINALLOCS(uchar4)> vertcolors4u
float stereo_convergence_dist
stereo convergence distance (world)
int2 size
framebuffer size
total count of SBT geometric multipliers
float3 bg_color_grad_bot
miss background gradient (bottom)
static void TachyonOptixLogCallback(unsigned int level, const char *tag, const char *message, void *cbdata)
void framebuffer_download_rgb4u(unsigned char *imgrgb4u)
std::vector< float3 PINALLOCS(float3) > primcolors3f
std::vector< float3 PINALLOCS(float3)> normals
int dof_enabled
DoF (defocus blur) on/off.
int ao_samples
number of AO samples per AA ray
int subframe_index
accumulation subframe index
__host__ __device__ float3 cross(const float3 &a, const float3 &b)
calculate the cross product between vectors a and b.
int finalize_geom_instance_group(int idx)
int userindex
material user index, positive if valid
float bg_grad_noisemag
miss background gradient noise magnitude
int aa_samples
AA samples per launch.
void download(T *t, size_t cnt)
Synchronous download from GPU device memory.
cone SBT index multiplier
void framebuffer_config(int fbwidth, int fbheight, int interactive)
std::vector< float3 PINALLOCS(float3)> vertices
OptixTraversableHandle traversable
global OptiX scene traversable handle
float3 bg_color_grad_top
miss background gradient (top)
#define RTPROF_SBT
trace color for SBT construction
quad SBT index multiplier
struct tachyonLaunchParams::@2 frame
std::vector< uint4 PINALLOCS(uint4)> packednormals
void upload(const T *t, size_t cnt)
Synchronous upload to GPU device memory.
Store all hitgroup records for a given geometry together for simpler dynamic updates.
void add_positional_light(const float *pos, const float *color)
float opacity
surface opacity
sphere SBT index multiplier
std::vector< float PINALLOCS(float)> outrad
#define PROFILE_STREAM_SYNC_PRETTY(stream)
Helper macro that can conditionally insert extra calls to cudaStreamSynchronize() into an application...
static unsigned int optix_version(void)
static OptiX version query
int colorspace
output colorspace
std::vector< int3 PINALLOCS(int3) > indices
struct tachyonLaunchParams::@5 cam
int num_dir_lights
directional light count
float3 * pos_lights
list of positional light positions
std::vector< float PINALLOCS(float)> vertradii
Output fully verbose debug info.
void clear_persist_allocation(void)
clear "used" size to zero, but keep existing device allocation
std::vector< float PINALLOCS(float)> baserad
#define RTPROF_TRANSFER
trace color for host-GPU DMA
#define RTPROF_ACCEL
trace color for RT AS builds
static __forceinline__ __device__ float4 sRGB_to_linear_approx_20(const float4 &rgba)
structure containing Tachyon material properties
rt_material * materials
device memory material array
float diffuse
diffuse reflectance coefficient
void framebuffer_colorspace(int colspace)
int material_index_from_user_index(int userindex)
locate material via user index
Tachyon ray tracing host side routines and internal APIs that provide the core ray OptiX-based RTX-ac...
void add_cylarray(CylinderArray &model, int matidx)
float fog_density
exponential fog density
float3 bg_color
miss background color
int num_pos_lights
positional light count
float ambient
constant ambient light factor
float ao_ambient
AO ambient factor.
float4 * accum_buffer
32-bit FP RGBA accumulation buffer
std::vector< float3 PINALLOCS(float3)> primcolors3f
void add_trimesh(TriangleMesh &model, int matidx)
float stereo_eyesep
stereo eye separation, in world coords
std::vector< float3 PINALLOCS(float3)> end
int max_depth
global max ray tracing recursion depth
enable tex cutout transparency
float epsilon
global epsilon value
void add_quadmesh(QuadMesh &model, int matidx)
std::vector< uchar4 PINALLOCS(uchar4) > vertcolors4u
void resize_upload(const std::vector< T > &vecT)
Combination of a buffer resize with synchronous upload to GPU device memory.
static __forceinline__ __device__ float4 linear_to_sRGB(const float4 &lin)
int image_index_from_user_index(int userindex)
locate texture via user index
float zoom
camera zoom factor