在 OptiX 7 中计算命中点的表面法线

Computing the surface normal at hit point in OptiX 7

我正在研究 OptiX 7.3OptixTriangle 示例。但是optixTrace的参数含义不清楚:

optixTrace(
        params.handle,
        ray_origin,
        ray_direction,
        0.0f,                       // --- Min intersection distance (tmin)
        1e16f,                      // --- Max intersection distance (tmax)
        0.0f,                       // --- rayTime -- used for motion blur
        OptixVisibilityMask( 255 ), // --- Specify always visible
        OPTIX_RAY_FLAG_NONE,        // --- OPTIX_RAY_FLAG_DISABLE_ANYHIT
        0,                          // --- SBT offset   -- See SBT discussion
        1,                          // --- SBT stride   -- See SBT discussion
        0,                          // --- missSBTIndex -- See SBT discussion
        p0, p1, p2 );
float3 result;
result.x = int_as_float( p0 );
result.y = int_as_float( p1 );
result.z = int_as_float( p2 );

// Record results in our output raster
params.image[idx.y * params.image_width + idx.x] = make_color( result );

特别是:

  1. 参数p0p1p2代表什么?
  2. 如何计算命中点的表面法线,以便我可以用该信息为三角形着色?
  1. OptixTriangle中变量p0p1p2将最近命中程序计算出的颜色带回光线生成程序. OptiX 将概念称为 ray payload。它是一种将最多 8 个值附加到光线并沿着程序管道传递它们的机制,每个被调用的程序都可以在其中读取和写入有效负载值。有关更多信息,请参见 OptiX Programming Guide.

  2. 如果一个三角形基元被击中(如OptixTriangle),你必须从加速结构中获得三角形坐标,并在它们上应用一些向量代数来计算法线顶点之一。命中点的法线与任何三角形顶点的法线相同:它们都共享同一平面。无论如何,为了获得命中点坐标,OptiX API 通过原始属性向命中程序提供交集 barycentric coordinates

要将其转化为代码,您不会绕过对 OptiX 7 的更深入理解。一个好的开始点是 How to Get Started with OptiX 7 as it actually walks you step by step through the OptixTriangle example. To follow-up visit the GitHub repo Siggraph 2019/2020 OptiX 7/7.3 Course Tutorial Code. Walking through the examples makes a steep learning curve. The 5th example 其中显示了正常计算。