How can I build a geometry of glass material in OptixMeshviewer example program?

Hi, everyone!
I am a novice and using Optix 7.2 to create a simple scene.
I am trying to build a geometry of glass material in OptixMeshviewer example, I do this in the hope that I can add a glass object while importing a gltf model.
Can you give me a example about how to create a glass object in OptixMeshviewer example or tell what I should do to make it success, I have tried lots of times, but I can’t make it, I wish you can help me!
Thank you !!!

Welcome!

There is an example of a glass object in the optixWhitted sample in the OptiX SDK.


David.

David, thank you for your answer!

I have tried to imitate the OptixWhitted sample in the OptixMeshviewer, including sphere_bound, buildGas, but it didn’t work.The program can run normally but the glass material is not displayed, it means the gltf object can display but the glass object is not displayed.

In the sample, I build the structure of acceleration like OptixWhitted and I have created raygen, miss, closest_hit and any_hit program like OptixWhitted, and I created the Sbt table and bound the above content according to the OptixWhitted example.

I try to output a specific statement in the .cu file to determine whether the corresponding function is called, just like

extern "C" __global__ void __intersection__sphere_shell()
{
	printf("__intersection__sphere_shell run! ");
        ......
}

But I found it didn’t run at all.

I sincerely wish you can help me solve the problem, I have been stuck here for several days.

Thank you for your help!!

I don’t know how to help without a lot more information, but I might be able to help suggest a strategy.

Trying to handle many changes at once can be confusing - it’s a new object with a new geometry type and new material. Focusing on just one of those things at a time might help get you there faster.

You did the right thing by seeing if the intersection program is running. It’s likely you’re just missing one of the several connections you need to make in order to get a new object in your scene.

There are many possible causes for geometry not showing up:

  • The geometry / primitive acceleration wasn’t added to the acceleration structure (GAS)
  • The geometry primitive info is missing from a buffer
  • The instance transform puts the instance outside of the camera’s view
  • The instance AABB position does not match the geometry position
  • The SBT index for the instance is incorrect
  • The SBT entry for the instance is missing from the SBT or at a different index than you think.

One common mistake is adding something to a buffer on the host but not paying close attention to when the buffer is copied from the CPU to the GPU. It can be easy to put something in a buffer after the buffer is copied, without realizing it.

I would recommend starting with smaller steps, and make changes one step at a time to keep your program working at all times and make sure you understand every step thoroughly. Maybe first, duplicate the glass sphere in the optixWhitted sample, while keeping everything else the same (geometry type & material). Move it slightly (using the instance transform) so you can see it. Once that is working, copy the intersection program to a new one, and add your printf to only the new intersection program. Update your SBT entry to point to the new sphere type, and make sure the printf is printing out. You can reference the existing materials in your SBT hit group while you work on the intersection program. Once the new intersection program is running, then copy the hit shaders to make a new material, and update your SBT entry to use the new hit shaders. You can add printf in your new closest-hit to make sure it’s running too.


David.

Dear David,

Thank you for your help, glass objects can be displayed now.

The way I realized it was to modify the corresponding handle, but another problem arises.

When I put the hitgroup binding of the gltf model behind the binding of the custom primitive, the glass material can be displayed, but when I change the order between them, the glass material cannot be displayed. I think there may be a problem with the offset of the hitgroup , but I don’t know how to modify it, I hope you can help me.

My other idea is to create two handles, one for gltf and the other for custom primitives, create two raygen__program at the same time, and execute two OptixTrace() after binding the corresponding sbt. I don’t know if this will work.

My final idea is to manage multiple objects with one handle. I sincerely hope that you can give me some suggestions in this regard.

Thank you very much for your help.

The following is a supplement to the above answer.

Here is the code of binding sbt, I sincerely hope you can help me solve the problem.

Thank you for your help!!

                        std::vector<HitGroupRecord> hitgroup_records;
			for (const auto mesh : m_meshes)
			{
				for (size_t i = 0; i < mesh->material_idx.size(); ++i)
				{

					HitGroupRecord rec = {};
					OPTIX_CHECK(optixSbtRecordPackHeader(m_radiance_hit_group, &rec));
					rec.data.geometry.geometry_data.type = GeometryData::TRIANGLE_MESH;
					rec.data.geometry.geometry_data.triangle_mesh.positions = mesh->positions[i];
					rec.data.geometry.geometry_data.triangle_mesh.normals = mesh->normals[i];
					rec.data.geometry.geometry_data.triangle_mesh.texcoords = mesh->texcoords[i];
					rec.data.geometry.geometry_data.triangle_mesh.indices = mesh->indices[i];

					const int32_t mat_idx = mesh->material_idx[i];

					if (mat_idx >= 0)
						rec.data.shading.material_data.pbr = m_materials[mat_idx];
					else
						rec.data.shading.material_data.pbr = MaterialData::Pbr();
					hitgroup_records.push_back(rec);

					 
           
          OPTIX_CHECK(optixSbtRecordPackHeader(m_occlusion_hit_group, &rec));
					hitgroup_records.push_back(rec);
				}
			}
			//HitGroupRecord* hitgroup_records;
			
			
			HitGroupRecord radiance_sphere = {};
			OPTIX_CHECK(optixSbtRecordPackHeader(
				m_radiance_glass_sphere_prog_group,
				&radiance_sphere
			));

			radiance_sphere.data.geometry.sphere_shell = g_sphere_shell;
			radiance_sphere.data.shading.glass= {
			1e-2f,                                  // importance_cutoff
			{ 0.034f, 0.055f, 0.085f },             // cutoff_color
			3.0f,                                   // fresnel_exponent
			0.1f,                                   // fresnel_minimum
			1.0f,                                   // fresnel_maximum
			1.4f,                                   // refraction_index
			{ 1.0f, 1.0f, 1.0f },                   // refraction_color
			{ 1.0f, 1.0f, 1.0f },                   // reflection_color
			{ logf(.83f), logf(.83f), logf(.83f) }, // extinction_constant
			{ 0.6f, 0.6f, 0.6f },                   // shadow_attenuation
			10,                                     // refraction_maxdepth
			5                                       // reflection_maxdepth
			};

			hitgroup_records.push_back(radiance_sphere);

			HitGroupRecord occlusion_sphere = {};
			OPTIX_CHECK(optixSbtRecordPackHeader(
				m_occlusion_glass_sphere_prog_group,
				&occlusion_sphere
			));

			occlusion_sphere.data.geometry.sphere_shell = g_sphere_shell;
			occlusion_sphere.data.shading.glass.shadow_attenuation = { 0.6f, 0.6f, 0.6f };
			hitgroup_records.push_back(occlusion_sphere);


const size_t hitgroup_record_size = sizeof(HitGroupRecord);
			CUDA_CHECK(cudaMalloc(
				reinterpret_cast<void**>(&m_sbt.hitgroupRecordBase),
				hitgroup_record_size*hitgroup_records.size()
			));
			CUDA_CHECK(cudaMemcpy(
				reinterpret_cast<void*>(m_sbt.hitgroupRecordBase),
				hitgroup_records.data(),
				hitgroup_record_size*hitgroup_records.size(),
				cudaMemcpyHostToDevice
			));
                        m_sbt.hitgroupRecordStrideInBytes = static_cast<unsigned int>(hitgroup_record_size);
			m_sbt.hitgroupRecordCount = static_cast<unsigned int>(hitgroup_records.size());

Hey this doesn’t give me enough information to help, it’s only filling the std::vector in the given order. The part I can’t see is what indices you’re using in your accel structures.

When you change the order of items in your SBT, are you also changing the indices you use? Are you keeping track of how many hit records each mesh corresponds to?

This is another spot where taking things in small steps can help a lot. One suggestion I have is to add some macros that allow you to print debug information for only the pixel you clicked on. Then you can start with a single material + single mesh, have the hit program identify itself (which should tell you what kind of material it is). Add one material, and make sure both work. Add another mesh, and make sure all work. It will be easier to spot any SBT gaps if you work with small numbers of meshes and materials. Going straight for multiple meshes with multiple materials and multiple geometry type all at once is harder to debug.


David.

Scene.cpp (83.1 KB)

Thank you for your help!

This is the file of my acceleration structure. I think it is mainly the problem of the offset setting of the two functions of buildgas() and buildInstanceAccel() and the size of the table in the creation of sbt. I sincerely hope that you can help me take a look.

Thank you for your help!