24 SLOptixRaytracer::SLOptixRaytracer()
27 name(
"OptiX ray tracer");
29 _paramsBuffer.alloc(
sizeof(ortParams));
33 SLOptixRaytracer::~SLOptixRaytracer()
35 SL_LOG(
"Destructor : ~SLOptixRaytracer");
39 void SLOptixRaytracer::destroy()
43 OPTIX_CHECK(optixPipelineDestroy(_pipeline));
44 OPTIX_CHECK(optixProgramGroupDestroy(_radiance_hit_group));
45 OPTIX_CHECK(optixProgramGroupDestroy(_occlusion_hit_group));
46 OPTIX_CHECK(optixProgramGroupDestroy(_radiance_miss_group));
47 OPTIX_CHECK(optixProgramGroupDestroy(_occlusion_miss_group));
48 OPTIX_CHECK(optixProgramGroupDestroy(_pinhole_raygen_prog_group));
49 OPTIX_CHECK(optixModuleDestroy(_cameraModule));
50 OPTIX_CHECK(optixModuleDestroy(_shadingModule));
55 "Exception in SLOptixRaytracer::destroy: %s",
60 void SLOptixRaytracer::initCompileOptions()
63 _module_compile_options = {};
64 _module_compile_options.maxRegisterCount = OPTIX_COMPILE_DEFAULT_MAX_REGISTER_COUNT;
67 _module_compile_options.optLevel = OPTIX_COMPILE_OPTIMIZATION_DEFAULT;
68 _module_compile_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_NONE;
69 _pipeline_compile_options.exceptionFlags = OPTIX_EXCEPTION_FLAG_NONE;
71 _module_compile_options.optLevel = OPTIX_COMPILE_OPTIMIZATION_LEVEL_0;
73 _module_compile_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_LINEINFO;
74 _pipeline_compile_options.exceptionFlags = OPTIX_EXCEPTION_FLAG_DEBUG | OPTIX_EXCEPTION_FLAG_USER;
77 _pipeline_compile_options.usesMotionBlur =
false;
78 _pipeline_compile_options.traversableGraphFlags = OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_LEVEL_INSTANCING;
79 _pipeline_compile_options.numPayloadValues = 7;
80 _pipeline_compile_options.numAttributeValues = 2;
81 _pipeline_compile_options.pipelineLaunchParamsVariableName =
"params";
84 void SLOptixRaytracer::setupOptix()
86 _cameraModule = createModule(
"SLOptixRaytracerCamera.cu");
87 _shadingModule = createModule(
"SLOptixRaytracerShading.cu");
89 OptixProgramGroupDesc pinhole_raygen_desc = {};
90 pinhole_raygen_desc.kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
91 pinhole_raygen_desc.raygen.module = _cameraModule;
92 pinhole_raygen_desc.raygen.entryFunctionName =
"__raygen__pinhole_camera";
93 _pinhole_raygen_prog_group = createProgram(pinhole_raygen_desc);
95 OptixProgramGroupDesc lens_raygen_desc = {};
96 lens_raygen_desc.kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
97 lens_raygen_desc.raygen.module = _cameraModule;
98 lens_raygen_desc.raygen.entryFunctionName =
"__raygen__lens_camera";
99 _lens_raygen_prog_group = createProgram(lens_raygen_desc);
101 OptixProgramGroupDesc orthographic_raygen_desc = {};
102 orthographic_raygen_desc.kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
103 orthographic_raygen_desc.raygen.module = _cameraModule;
104 orthographic_raygen_desc.raygen.entryFunctionName =
"__raygen__orthographic_camera";
105 _orthographic_raygen_prog_group = createProgram(orthographic_raygen_desc);
107 OptixProgramGroupDesc radiance_miss_desc = {};
108 radiance_miss_desc.kind = OPTIX_PROGRAM_GROUP_KIND_MISS;
109 radiance_miss_desc.miss.module = _shadingModule;
110 radiance_miss_desc.miss.entryFunctionName =
"__miss__radiance";
111 _radiance_miss_group = createProgram(radiance_miss_desc);
113 OptixProgramGroupDesc occlusion_miss_desc = {};
114 occlusion_miss_desc.kind = OPTIX_PROGRAM_GROUP_KIND_MISS;
115 occlusion_miss_desc.miss.module = _shadingModule;
116 occlusion_miss_desc.miss.entryFunctionName =
"__miss__occlusion";
117 _occlusion_miss_group = createProgram(occlusion_miss_desc);
119 OptixProgramGroupDesc radiance_hitgroup_desc = {};
120 radiance_hitgroup_desc.kind = OPTIX_PROGRAM_GROUP_KIND_HITGROUP;
121 radiance_hitgroup_desc.hitgroup.moduleAH = _shadingModule;
122 radiance_hitgroup_desc.hitgroup.entryFunctionNameAH =
"__anyhit__radiance";
123 radiance_hitgroup_desc.hitgroup.moduleCH = _shadingModule;
124 radiance_hitgroup_desc.hitgroup.entryFunctionNameCH =
"__closesthit__radiance";
125 _radiance_hit_group = createProgram(radiance_hitgroup_desc);
127 OptixProgramGroupDesc occlusion_hitgroup_desc = {};
128 occlusion_hitgroup_desc.kind = OPTIX_PROGRAM_GROUP_KIND_HITGROUP;
129 occlusion_hitgroup_desc.hitgroup.moduleAH = _shadingModule;
130 occlusion_hitgroup_desc.hitgroup.entryFunctionNameAH =
"__anyhit__occlusion";
131 occlusion_hitgroup_desc.hitgroup.moduleCH =
nullptr;
132 occlusion_hitgroup_desc.hitgroup.entryFunctionNameCH =
nullptr;
133 _occlusion_hit_group = createProgram(occlusion_hitgroup_desc);
135 OptixProgramGroup program_groups[] = {
136 _pinhole_raygen_prog_group,
137 _radiance_miss_group,
138 _occlusion_miss_group,
140 _occlusion_hit_group,
142 _pipeline = createPipeline(program_groups, 5);
145 OptixModule SLOptixRaytracer::createModule(
string filename)
147 OptixModule module =
nullptr;
149 const string ptx = getPtxStringFromFile(std::move(filename));
151 size_t sizeof_log =
sizeof(
log);
153 OPTIX_CHECK_LOG(optixModuleCreateFromPTX(
155 &_module_compile_options,
156 &_pipeline_compile_options,
166 OptixProgramGroup SLOptixRaytracer::createProgram(OptixProgramGroupDesc desc)
168 OptixProgramGroup program_group = {};
169 OptixProgramGroupOptions program_group_options = {};
172 size_t sizeof_log =
sizeof(
log);
174 OPTIX_CHECK_LOG(optixProgramGroupCreate(
178 &program_group_options,
183 return program_group;
186 OptixPipeline SLOptixRaytracer::createPipeline(OptixProgramGroup* program_groups,
187 unsigned int numProgramGroups)
189 OptixPipeline pipeline;
190 OptixPipelineLinkOptions pipeline_link_options = {};
191 pipeline_link_options.maxTraceDepth = _maxDepth;
192 pipeline_link_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_FULL;
193 pipeline_link_options.overrideUsesMotionBlur =
false;
196 size_t sizeof_log =
sizeof(
log);
202 &_pipeline_compile_options,
203 &pipeline_link_options,
214 OptixShaderBindingTable SLOptixRaytracer::createShaderBindingTable(
const SLVMesh& meshes,
215 const bool doDistributed)
219 OptixShaderBindingTable sbt = {};
224 RayGenDistributedSbtRecord rg_sbt;
225 _rayGenDistributedBuffer.alloc_and_upload(&rg_sbt, 1);
229 RayGenClassicSbtRecord rg_sbt;
230 _rayGenClassicBuffer.alloc_and_upload(&rg_sbt, 1);
234 vector<MissSbtRecord> missRecords;
236 MissSbtRecord radiance_ms_sbt;
237 OPTIX_CHECK(optixSbtRecordPackHeader(_radiance_miss_group, &radiance_ms_sbt));
238 radiance_ms_sbt.data.bg_color = make_float4(camera->
background().
colors()[0]);
239 missRecords.push_back(radiance_ms_sbt);
241 MissSbtRecord occlusion_ms_sbt;
242 OPTIX_CHECK(optixSbtRecordPackHeader(_occlusion_miss_group, &occlusion_ms_sbt));
243 missRecords.push_back(occlusion_ms_sbt);
245 _missBuffer.alloc_and_upload(missRecords);
248 vector<HitSbtRecord> hitRecords;
250 for (
auto mesh : meshes)
252 OptixProgramGroup hitgroup_radicance = _radiance_hit_group;
253 OptixProgramGroup hitgroup_occlusion = _occlusion_hit_group;
255 HitSbtRecord radiance_hg_sbt;
256 OPTIX_CHECK(optixSbtRecordPackHeader(hitgroup_radicance, &radiance_hg_sbt));
257 radiance_hg_sbt.data = mesh->createHitData();
258 hitRecords.push_back(radiance_hg_sbt);
260 HitSbtRecord occlusion_hg_sbt;
261 OPTIX_CHECK(optixSbtRecordPackHeader(hitgroup_occlusion, &occlusion_hg_sbt));
262 occlusion_hg_sbt.data.material.kt = mesh->mat()->kt();
263 occlusion_hg_sbt.data.material.emissive_color = make_float4(mesh->mat()->emissive());
264 hitRecords.push_back(occlusion_hg_sbt);
266 _hitBuffer.alloc_and_upload(hitRecords);
269 sbt.raygenRecord = _rayGenDistributedBuffer.devicePointer();
271 sbt.raygenRecord = _rayGenClassicBuffer.devicePointer();
273 sbt.missRecordBase = _missBuffer.devicePointer();
274 sbt.missRecordStrideInBytes =
sizeof(MissSbtRecord);
275 sbt.missRecordCount = RAY_TYPE_COUNT;
276 sbt.hitgroupRecordBase = _hitBuffer.devicePointer();
277 sbt.hitgroupRecordStrideInBytes =
sizeof(HitSbtRecord);
278 sbt.hitgroupRecordCount = RAY_TYPE_COUNT * (
SLuint)meshes.size();
289 _imageBuffer.resize(_sv->scrW() * _sv->scrH() *
sizeof(float4));
291 _params.image =
reinterpret_cast<float4*
>(_imageBuffer.devicePointer());
292 _params.width = _sv->
scrW();
293 _params.height = _sv->scrH();
294 _params.max_depth = _maxDepth;
297 SLMesh::meshIndex = 0;
298 for (
auto mesh : meshes)
300 mesh->createMeshAccelerationStructure();
303 _sbtClassic = createShaderBindingTable(meshes,
false);
304 _sbtDistributed = createShaderBindingTable(meshes,
true);
315 scene->
root3D()->createInstanceAccelerationStructureFlat();
317 _params.handle = scene->
root3D()->optixTraversableHandle();
321 ortCamera cameraData{};
322 cameraData.eye = make_float3(eye);
323 cameraData.U = make_float3(u);
324 cameraData.V = make_float3(v);
325 cameraData.W = make_float3(w);
329 RayGenDistributedSbtRecord rayGenSbtRecord;
330 _rayGenDistributedBuffer.download(&rayGenSbtRecord);
331 OPTIX_CHECK(optixSbtRecordPackHeader(_lens_raygen_prog_group, &rayGenSbtRecord));
332 rayGenSbtRecord.data.lensDiameter = camera->
lensDiameter();
333 rayGenSbtRecord.data.samples.samplesX = camera->
lensSamples()->samplesX();
334 rayGenSbtRecord.data.samples.samplesY = camera->
lensSamples()->samplesY();
335 rayGenSbtRecord.data.camera = cameraData;
336 _rayGenDistributedBuffer.upload(&rayGenSbtRecord);
340 RayGenClassicSbtRecord rayGenSbtRecord;
341 _rayGenClassicBuffer.download(&rayGenSbtRecord);
344 OPTIX_CHECK(optixSbtRecordPackHeader(_pinhole_raygen_prog_group, &rayGenSbtRecord));
348 OPTIX_CHECK(optixSbtRecordPackHeader(_orthographic_raygen_prog_group, &rayGenSbtRecord));
350 rayGenSbtRecord.data = cameraData;
351 _rayGenClassicBuffer.upload(&rayGenSbtRecord);
354 vector<ortLight> lights;
356 unsigned int light_count = 0;
357 for (
auto light : scene->
lights())
361 lights.push_back(light->optixLight(doDistributed()));
365 _lightBuffer.alloc_and_upload(lights);
366 _params.lights =
reinterpret_cast<ortLight*
>(_lightBuffer.devicePointer());
367 _params.numLights = light_count;
370 _paramsBuffer.upload(&_params);
373 SLbool SLOptixRaytracer::renderClassic()
381 OPTIX_CHECK(optixLaunch(
384 _paramsBuffer.devicePointer(),
385 _paramsBuffer.size(),
390 CUDA_SYNC_CHECK(SLOptix::stream);
397 SLbool SLOptixRaytracer::renderDistrib()
403 OPTIX_CHECK(optixLaunch(
406 _paramsBuffer.devicePointer(),
407 _paramsBuffer.size(),
412 CUDA_SYNC_CHECK(SLOptix::stream);
419 void SLOptixRaytracer::prepareImage()
423 _images.push_back(
new CVImage(_sv->scrW(), _sv->scrH(),
PF_rgb,
"Optix Raytracer"));
426 if (_sv->scrW() != (
SLint)_images[0]->width() ||
427 _sv->scrH() != (
SLint)_images[0]->height())
432 if (_cudaGraphicsResource)
434 CUDA_CHECK(cuGraphicsUnregisterResource(_cudaGraphicsResource));
435 _cudaGraphicsResource =
nullptr;
438 glDeleteTextures(1, &_texID);
442 _vaoSprite.clearAttribs();
443 _images[0]->allocate(_sv->scrW(), _sv->scrH(),
PF_rgb);
447 void SLOptixRaytracer::renderImage(
bool updateTextureGL)
453 CUDA_CHECK(cuGraphicsMapResources(1, &_cudaGraphicsResource, SLOptix::stream));
454 CUDA_CHECK(cuGraphicsSubResourceGetMappedArray(&texture_ptr, _cudaGraphicsResource, 0, 0));
456 CUDA_ARRAY_DESCRIPTOR des;
457 cuArrayGetDescriptor(&des, texture_ptr);
458 CUDA_MEMCPY2D memcpy2D;
459 memcpy2D.srcDevice = _imageBuffer.devicePointer();
460 memcpy2D.srcMemoryType = CU_MEMORYTYPE_DEVICE;
461 memcpy2D.srcXInBytes = 0;
463 memcpy2D.srcPitch = 0;
464 memcpy2D.dstArray = texture_ptr;
465 memcpy2D.dstMemoryType = CU_MEMORYTYPE_ARRAY;
466 memcpy2D.dstXInBytes = 0;
468 memcpy2D.dstPitch = 0;
469 memcpy2D.WidthInBytes = des.Width * des.NumChannels *
sizeof(float);
470 memcpy2D.Height = des.Height;
471 CUDA_CHECK(cuMemcpy2D(&memcpy2D));
473 CUDA_CHECK(cuGraphicsUnmapResources(1, &_cudaGraphicsResource, SLOptix::stream));
478 void SLOptixRaytracer::saveImage()
480 float4* image =
static_cast<float4*
>(malloc(_imageBuffer.size()));
481 _imageBuffer.download(image);
483 for (
int i = 0; i < _sv->scrH(); i++)
485 for (
int j = 0; j < _sv->scrW(); j++)
487 float4 pixel = image[i * _sv->scrW() + j];
488 _images[0]->setPixeli(j, i,
CVVec4f(pixel.x, pixel.y, pixel.z));
@ P_monoPerspective
standard mono pinhole perspective projection
vector< SLMesh * > SLVMesh
OpenCV image class with the same interface as the former SLImage class.
Toplevel holder of the assets meshes, materials, textures and shaders.
void colors(const SLCol4f &uniformColor)
Sets a uniform background color.
Active or visible camera node class.
void lensSamples(SLuint x, SLuint y)
void projType(SLProjType p)
void lensDiameter(const SLfloat d)
SLBackground & background()
void UVWFrame(SLVec3f &EYE, SLVec3f &U, SLVec3f &V, SLVec3f &W)
void bindActive(SLuint texUnit=0)
static SLCol4f globalAmbient
static global ambient light intensity
static unsigned int instanceIndex
???
SLRaytracer hold all the methods for Whitted style Ray Tracing.
virtual void renderImage(bool updateTextureGL)
virtual void saveImage()
Saves the current RT image as PNG image.
The SLScene class represents the top level instance holding the scene structure.
void root3D(SLNode *root3D)
SceneView class represents a dynamic real time 3D view onto the scene.
void camera(SLCamera *camera)
void log(const char *tag, const char *format,...)
logs a formatted string platform independently