Are bounding box programs supposed to be per triangle, or per mesh?

When reading the Optix programming guide, the example bound program given is for an entire sphere. But when looking at some of the samples, I found this code in triangle_mesh.cu:

RT_PROGRAM void mesh_bounds (int primIdx, float result[6])
{
  const int3 v_idx = index_buffer[primIdx];

  const float3 v0   = vertex_buffer[ v_idx.x ];
  const float3 v1   = vertex_buffer[ v_idx.y ];
  const float3 v2   = vertex_buffer[ v_idx.z ];
  const float  area = length(cross(v1-v0, v2-v0));

  optix::Aabb* aabb = (optix::Aabb*)result;
  
  if(area > 0.0f && !isinf(area)) {
    aabb->m_min = fminf( fminf( v0, v1), v2 );
    aabb->m_max = fmaxf( fmaxf( v0, v1), v2 );
  } else {
    aabb->invalidate();
  }
}

Which is calculating the bounding box for individual triangles, unless I am mistaken? Isn’t this very slow or am I missing something?

The scene I have is a patch of terrain with some objects on it, all made up of triangles. Would it make sense to use this mesh_bounds function for that?

The bounding box program calculates an axis aligned bounding box (AABB) per primitive.
You need to implement one for each geometric primitive type you want to use.

The bounding box program needs to be assigned to the OptiX Geometry nodes in you scene graph.
That establishes the connection between your bounding box program and the named buffers of this Geometry node which contain the geometric primitive data.
Same for the intersection program, one per primitive type, assigned to the Geometry nodes.

Means if you have a parametric sphere primitive type you need to have a pair of bounding box and intersection programs for that.
If you have have triangle geometry in some topology (e.g. indexed mesh like in the above example, non-indexed mesh, strip, fan, etc.) you would need to provide a pair of programs which handle those, so yes, if you have terrain as triangulated triangle mesh, you need to implement a bounding box and intersection program which can address the individual triangles in your structure.

Plus:

  • It’s not particularly slow because the bounding box program is being invoked on the device using many parallel CUDA threads at once.
  • For triangles, under certain conditions, OptiX ignores your bounding box program and uses its own, so that it can do spatial splitting of triangles. This doesn’t matter much when you write your program, but it could matter for debugging.

Thank you for the clarification.