Optix 7.0 Instance build inputs not working, need example code

I have been trying unsuccessfully for several weeks to get instance acceleration structures working in my application. For reference, I started with the Optix 7 SDK optixTriangle example code and added the following code right after the single triangle geometry acceleration structure was created:
//---------------------------------------------------------------------------
// Added code - create an IAS instance of the above GAS
//---------------------------------------------------------------------------
OptixTraversableHandle ias_handle;

	OptixInstance optixInstance = {};

	optixInstance.flags = OPTIX_INSTANCE_FLAG_NONE;

	float identityXform[12]
	{
		1.f, 0.f, 0.f,
		0.f, 1.f, 0.f,
		0.f, 0.f, 1.f,
		0.f, 0.f, 0.f
	};
	memcpy(optixInstance.transform, identityXform, sizeof(float) * 12);
	optixInstance.visibilityMask = 255;
	optixInstance.sbtOffset = 0;
	optixInstance.instanceId = 0; 
	optixInstance.traversableHandle = gas_handle; // Triangle geometry created above

	// Copy OptixInstance to the GPU
	CUdeviceptr d_optixInstance;
	const size_t optixInstancesSize = sizeof(OptixInstance);
	CUDA_CHECK(cudaMalloc(reinterpret_cast<void**>(&d_optixInstance), optixInstancesSize));
	CUDA_CHECK(cudaMemcpy(
		reinterpret_cast<void*>(d_optixInstance),
		&optixInstance,
		optixInstancesSize,
		cudaMemcpyHostToDevice
	));

	OptixBuildInput build_input = {};
	build_input.type = OPTIX_BUILD_INPUT_TYPE_INSTANCES;
	build_input.instanceArray.instances = d_optixInstance;
	build_input.instanceArray.numInstances = 1;

	OptixAccelBuildOptions accel_options = {};
	accel_options.buildFlags = OPTIX_BUILD_FLAG_ALLOW_COMPACTION;
	accel_options.operation = OPTIX_BUILD_OPERATION_BUILD;

	OptixAccelBufferSizes ias_buffer_sizes;
	OPTIX_CHECK(optixAccelComputeMemoryUsage(context, &accel_options, &build_input,
		1,  // Number of build inputs
		&ias_buffer_sizes));
	CUdeviceptr d_temp_buffer_ias;
	CUDA_CHECK(cudaMalloc(reinterpret_cast<void**>(&d_temp_buffer_ias), ias_buffer_sizes.tempSizeInBytes));

	// non-compacted output
	CUdeviceptr d_buffer_temp_output_ias_and_compacted_size;
	size_t compactedSizeOffset = roundUp<size_t>(ias_buffer_sizes.outputSizeInBytes, 8ull);
	CUDA_CHECK(cudaMalloc(reinterpret_cast<void**>(
		&d_buffer_temp_output_ias_and_compacted_size),
		compactedSizeOffset + 8
	));

	OptixAccelEmitDesc emitProperty = {};
	emitProperty.type = OPTIX_PROPERTY_TYPE_COMPACTED_SIZE;
	emitProperty.result = (CUdeviceptr)((char*)d_buffer_temp_output_ias_and_compacted_size + compactedSizeOffset);

	OPTIX_CHECK(optixAccelBuild(
		context,
		0,              // CUDA stream
		&accel_options,
		&build_input,
		1,              // num build inputs
		d_temp_buffer_ias,
		ias_buffer_sizes.tempSizeInBytes,
		d_buffer_temp_output_ias_and_compacted_size,
		ias_buffer_sizes.outputSizeInBytes,
		&ias_handle,    // Optix handle to instance hierarchy structure on GPU
		&emitProperty,  // emitted property list
		1               // num emitted properties
	));
	//---------------------------------------------------------------------------
	// End added code
	//---------------------------------------------------------------------------

then I modified the optix launch to use the IAS in place of the GAS:
//-------------------------------------------------------------------
// Ray trace using identity transformed instance of triangle geometry
params.handle = ias_handle;
// params.handle = gas_handle;
//-------------------------------------------------------------------

I get the same result I have been getting in my own app–ray tracing is not getting to the triangle geometry. Any help would be greatly appreciated.

1 Like

Please make sure you have set the correct value for the OptixPipelineCompileOptions.
When using a single level of instances over bottom level GAS, the traversableGraphFlags should be set to OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_LEVEL_INSTANCING
If the example you changed only used OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_GAS before, the instancing won’t work.

Please refer to the OptiX 7 programming guide and API reference for more information.
https://raytracing-docs.nvidia.com/

enum OptixTraversableGraphFlags
https://raytracing-docs.nvidia.com/optix7/api/html/group__optix__types.html#gabd8bb7368518a44361e045fe5ad1fd17

For examples showing instancing, please follow both links inside this sticky thread.
My OptiX 7 Apps are all using single level instancing so far.
https://forums.developer.nvidia.com/t/optix-advanced-samples-on-github/48410/4

2 Likes

Also, your identity matrix is aligned wrong. If I take your code and use the following instead:

float identityXform[12]
{
        1.f, 0.f, 0.f, 0.f,
        0.f, 1.f, 0.f, 0.f,
        0.f, 0.f, 1.f, 0.f
};

then your example works as expected for me (assuming the traversableGraphFlags is correctly set to single-level instancing as well).

1 Like