Build vertices with floating point array for GAS

Hello all,

I apologize if this is a dumb question, but suppose I have an array of vertices defined in a single dimension floating point array (which are logically a series of triangles) and I want to use it to build the acceleration structure. I have been successful using the float3 array as in the following code snippet, where d_vertices is a CUdeviceptr of float3 values:

    const uint32_t triangle_input_flags[1] = { OPTIX_GEOMETRY_FLAG_NONE };
    OptixBuildInput triangle_input = {};

    // Vertices
    triangle_input.type   = OPTIX_BUILD_INPUT_TYPE_TRIANGLES;
    triangle_input.triangleArray.vertexFormat = OPTIX_VERTEX_FORMAT_FLOAT3;

    triangle_input.triangleArray.numVertices = static_cast<uint32_t>(vertex_size);
    triangle_input.triangleArray.vertexBuffers = &d_vertices;

    // One SBT entry and no per-primitive materials
    triangle_input.triangleArray.flags = triangle_input_flags;
    triangle_input.triangleArray.numSbtRecords= 1;
    triangle_input.triangleArray.sbtIndexOffsetBuffer = 0;
    triangle_input.triangleArray.sbtIndexOffsetSizeInBytes = 0;
    triangle_input.triangleArray.sbtIndexOffsetStrideInBytes = 0;

However I have not found information regarding using an array of floats for this. Is there a flag or option in OptiX 7.2 that will easily allow one to pass an array of floats for vertices during the creation of the geometry acceleration structure?

Thank you in advance for any hints or information.

Hey @picard1969,

As far as OptiX is concerned, there’s no difference between an array of float vs an array of float3, as long as what you want is triplets of float values. Instead of creating a buffer of N float3s, you can create a buffer of 3*N floats and copy your data, then give OptiX the pointer to that buffer and tell OptiX that it’s a type OPTIX_VERTEX_FORMAT_FLOAT3. Use of the float3 type on your end is purely optional for your convenience. The layout of the float3 type is just 3 consecutive floats in memory, so pointers to floats can be used as if they’re float3, and vice-versa.

I hope that answers what you meant. If you were thinking of wanting OPTIX_VERTEX_FORMAT_FLOAT, or a different layout in memory, then maybe I didn’t understand the question entirely.


David.

Thank you @dhart for the reply. I think that answers what I was asking.

I have an array of floats, each of which contains x, y, and z elements that I am trying to use to build GAS with. The array is already on DEVICE side and has the following structure (all floats):
x0,y0,z0,x1,y1,z1,...xN-1,yN-1,zN-1

The array of floats above is called d_vertices which I then use it to build GAS as in following:

const uint32_t triangle_input_flags[1] = { OPTIX_GEOMETRY_FLAG_NONE };
OptixBuildInput triangle_input = {};

// Vertices
triangle_input.type   = OPTIX_BUILD_INPUT_TYPE_TRIANGLES;
triangle_input.triangleArray.vertexFormat = OPTIX_VERTEX_FORMAT_FLOAT3;

triangle_input.triangleArray.numVertices = static_cast<uint32_t>(vertex_size);
triangle_input.triangleArray.vertexBuffers = &d_vertices;

 // One SBT entry and no per-primitive materials
 triangle_input.triangleArray.flags = triangle_input_flags;
 triangle_input.triangleArray.numSbtRecords= 1;
 triangle_input.triangleArray.sbtIndexOffsetBuffer = 0;
 triangle_input.triangleArray.sbtIndexOffsetSizeInBytes = 0;
 triangle_input.triangleArray.sbtIndexOffsetStrideInBytes = 0;

If I understand correctly, I should be able to directly pass d_vertices to OptiX 7.2 given it is already defined as triplets?

Thanks again.

Yep, that array looks good, you can pass the pointer and let OptiX interpret it as float3 even though it’s a float array.


David.

1 Like

Thanks @dhart

Something that may be obvious to anyone out there trying to pass array of floats versus array of float3, do not forget to adjust the vertex_size by 3 otherwise access to area outside of intended space could occur.

For example, if you have an array of floats of length N, the vertex_size must be set to N / 3.

This may or may not help anyone out there, but I wanted to include just in case.

Please note that the case of reinterpreting a float array as a float3 array works without issues in CUDA because the memory alignment requirements of float and float3 are the same. The data must reside on 4-byte aligned addresses.

More care needs to be taken for float2 and float4 vector types which have CUDA memory alignment requirements of 8-byte and 16-byte addresses respectively, means reinterpreting float array data to either of these would need to make sure the float array resides on a properly aligned address.
Similar for all other built-in CUDA vector data types.

Please find the CUDA alignment requirements for built-in data types here:
https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#vector-types__alignment-requirements-in-device-code

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.