optix入门

射线追踪是embarrassingly parallel/perfectly parallel/pleasingly parallel的问题,就是说基本不用费劲就可以并行化。

optix入门_第1张图片

射线追踪是指从某点发射射线,判断其与几何结构的交点,根据交点对图像进行渲染,或者计算。

nvidia optix是基于cuda的api,可充分利用gpu的计算能力对射线追踪进行加速。

optix入门_第2张图片

 

主要概念和步骤:

cpu端

首先建立场景/环境context,就是进行射线追踪的环境。
        RT_CHECK_ERROR( rtContextCreate( &context ) );

        RT_CHECK_ERROR( rtContextSetRayTypeCount( context, 1 ) );//设置射线类型
射线一般关联一个payload数据结构,用于存储射线追踪过程的数据,如颜色等等。因此,不同payload的射线可以有不同的类型。另外,不同用途的射线也可以设置不同的类型,例如有的用在closest hit中,有的用在any hit中。

RT_CHECK_ERROR( rtContextSetEntryPointCount( context, 1 ) );

设置入口点个数。一个入口点和一个射线生成程序关联。当调用rtContextLaunchnD时,射线生成程序是首先执行的入口点,它的功能类似c语言中的main函数。射线生成程序是并行执行的。每个thread有一个rtLaunchIndex,可用来区分thread。

        RT_CHECK_ERROR( rtBufferCreate( context, RT_BUFFER_OUTPUT, &buffer ) );
        RT_CHECK_ERROR( rtBufferSetFormat( buffer, RT_FORMAT_FLOAT4 ) );
        RT_CHECK_ERROR( rtBufferSetSize2D( buffer, width, height ) );
        RT_CHECK_ERROR( rtContextDeclareVariable( context, "result_buffer", &result_buffer ) );
        RT_CHECK_ERROR( rtVariableSetObject( result_buffer, buffer ) );

buffer缓冲区用来在host和gpu之间交换数据。buffer只能由host创建。

variable变量用来在程序间交互数据。variables可以在各个层级声明,例如context、program、geometry等。
const char *ptx = sutil::getPtxString( "optixHello", "draw_color.cu" );//读取ptx文件
        RT_CHECK_ERROR( rtProgramCreateFromPTXString( context, ptx, "draw_solid_color", &ray_gen_program) );

把ptx文件中draw_solid_color的函数绑定到程序对象ray_gen_program上。
        RT_CHECK_ERROR( rtProgramDeclareVariable( ray_gen_program, "draw_color", &draw_color ) );

声明一个叫做draw_color的变量,绑定到ray_gen_program上。
        RT_CHECK_ERROR( rtVariableSet3f( draw_color, 0.462f, 0.725f, 0.0f ) );
        RT_CHECK_ERROR( rtContextSetRayGenerationProgram( context, 0, ray_gen_program ) );//将draw_solid_color函数绑定到ray_gen_program

        /* Run */
        RT_CHECK_ERROR( rtContextValidate( context ) );
        RT_CHECK_ERROR( rtContextLaunch2D( context, 0 /* entry point */, width, height ) );

contextLaunch_n_D就是生成1维、2维、3维的逻辑计算网格(线程数?),每生成一个计算网格调用一次ray_gen_program,计算结果写入buffer。因此一般buffer的大小和计算网格的大小相同。

        /* Clean up */
        RT_CHECK_ERROR( rtBufferDestroy( buffer ) );
        RT_CHECK_ERROR( rtProgramDestroy( ray_gen_program ) );
        RT_CHECK_ERROR( rtContextDestroy( context ) );

然后设置几何,可以是简单几何体组合、变换,也可以是三角网格。

在gpu端,编写射线求交和渲染的程序。求交点的情况包括求最近交点closest hit、求任意交点any hit。closest hit是在射线与场景所有几何体求交后,得到距离射线起点最近的交点;any hit可能有几种情况:交点被忽略,例如射线经过透明介质;求交结束,此时求交只是为了计算两个表面是否可见;返回交点,并继续求交,这是any hit程序的默认定义。

示例程序

gpu端

1 产生射线

建立简单几何形状和包围盒

求交点

#include
#include

using namespace optix;

rtDeclareVariable(uint2, launch_index, rtLaunchIndex, );

gpu的program还可以通过变量与Host进行交互。上述定义了一个launch_index的变量,它等同于OptiX内置的rtLaunchIndex。launch_index在本program内部使用。定义语法为:rtDeclareVariable(type,name,semantic,annotation )。

rtLaunchIndex是thread的索引号。
rtBuffer   result_buffer;

定义了一个float4的二维数组,result_buffer。

rtDeclareVariable(float3,                draw_color, , );

RT_PROGRAM void draw_solid_color()
{
  result_buffer[launch_index] = make_float4(draw_color, 0.f);
}

optix prime专门用于射线与三角形求交点的高性能计算,而不具备着色等功能。

你可能感兴趣的:(c和c++程序设计,蒙特卡罗射线追踪,蒙特卡洛射线追踪)