Area lights with triangle mesh

My path tracer supports point light and area light. I store lights in the scene into a buffer. When I need to sample a point on light source, I randomly choose a light from the buffer, and sample a position according the type of the light and its corresponding parameters. This works for point light and area light with analytic shape, like disk or sphere, because a few parameters are need to specify the disk light or spherical light. I also saw many OptiX samples using ParallelogramLight, which can be handled similarly.

But when I use triangle mesh for area light, the problem comes. To sample a position on the light, I need to access to the vertex buffer and index buffer of the mesh. The light sampling is called inside the Closest Hit Program, so where should I store the buffer objects?

My idea is to, associate each triangle mesh area light with one imaginary geometry, then the buffer objects can be stored on these geometries(or GeometryInstance); when I need to sample a light position, I trace a ray (with special type) into this group of geometries to select an area light, and sample a position using the vertex buffer stored on the GeometryInstance. But this method seems a little overkill, I wonder if there is a better solution.

If the light is supposed to be global you can put the buffers into the context. Many different solutions of placing light geometry are possible. It depends on what sampling method you are going to use. It can be placed independently from other scene geometry or together. If I understood it right, the method of sampling mesh light you described sounds like solid angle sampling with respect to self-intersection of the light mesh. Yes, it might be suboptimal. Good survey of sampling direct illumination you can find here http://www.cs.virginia.edu/~jdl/bib/globillum/mis/shirley96.pdf

Thank you. Sorry that my description is quite misleading. By sampling light I mean directly sampling a position on light source, not by a BSDF solid angle sampling. This is exactly the direct illumination method that you mentioned.

The lights are global, and they are placed in a buffer on Context. Each light is a struct that specifies the light’s type and corresponding parameters. I illustrate the struct below.

struct Light
{
  uint type;
  union
  {
    struct // area light
    {
      int geom_type;
      float3 radiance;
      union  
      {
        struct  
        {
          float3 center;
          float radius;
        }sphere;
        struct  
        {
          float3 center;
          float3 face;
          float radius;
        }disk;
        struct  
        {
          int tri_idx; //?? problem here
        }trimesh;
      };
    }arealight;

    struct  
    {
      float3 position;
      float3 intensity;
    }pointlight;
  };
};

My problem is that, if the light is area light with mesh, it will need to access the mesh’s vertex buffer to sample a position on the mesh. This cannot be stored directly in the Light struct like other parameters, because it’s a buffer object, and the Light struct is already in a Buffer.

Please forget the method I mentioned in the end of my first post. My second thought is to store the vertex buffer object on Context, and store a ‘tri_idx’ parameter in Light struct to indicate which vertex buffer will be used. But in this way, I can only support fixed number of mesh area lights (although this is not a problem for most scenes). For example, if I want to support at most 2 mesh area lights in my path tracer, then I store two buffer objects vertex_buffer_1 and vertex_buffer_2 on Context, although there may be more than(or less than) 2 mesh area lights in a scene.

So the problem is that you want to use unknown vertex buffer in a scene at compile time. You can merge all mesh light buffers into one big buffer, that is obviously not very elegant. I think a new feature of coming very soon OptiX 3.5 bindless buffers will help to make it elegant.

Thank you, the bindless buffer seems interesting.
But I ended up with fitting disk arealights to all mesh arealights in the scene, currently it’s not a critical feature for me.