0%
Theme NexT works best with JavaScript enabled
Optix7 Course
Main Talk
cuda runtime API vs driver API
cuda* prefix (i.e.,
cudaStreamCreate)
cu* prefi (i.e., cuStreamCreate)
Launch with <<<
>>>>
Launch kernels with cuLaunch*
CUDA kernels embedded in .o
Kernels loaded or compiled at
runtime
compilation
OptiX is built on separate compilation
shader
1 2 extern "C" __global__ void __raygen__pathtrace() { }
pipeline creation
cuda shader -> PTX -> Module(s) -> ProgramGroup(s) ->
Pipeline(s)
traversable
General
Geometry Acceleration structure (GAS)
Triangles or custom primitives
Instance Acceleration structure (IAS)
Motion blur
Matrix motion transform
SRT motion transform
Scale Rotation Translation
Static Transform (rarely used)
object-to-world transform
Shader Binding Table
SBT is just GPU memory
Keep them small
denoiser
1 2 3 4 5 6 7 8 9 10 11 12 optixDenoiserCreate ();optixDenoiserSetModel ();optixDenoiserComputeMemoryResources ();cuMemAlloc ();optixDenoiserSetup ();optixDenoiserInvoke ();
visibility mask
Can be used to disable certain geometry with some
rays
(no shadows through glass, invisible in reflections, etc)
multi-GPU
Demand Texture
Github :allows
hardware-accelerated sparse textures to be loaded on demand
ray
tracing gems
本影、半影
ray:\((t_{\min},t_{\max})\)
如何防止自相交(当处于 grazing angle 的时候,\(\delta\) 可能不管用)
Sample Transformations Zoo
Importance Sampling of Many Lights on The GPU
Material Definition Language (MDL)
OSL:Open Shading Language
其他资源
Tutorial
E01-helloOptix
1 2 3 4 cudaFree (0 );OPTIX_CHECK ( optixInit () );
预先将 cuda 代码编译成字符串
cmake
cuda_compile_ptx
编译成 ptx 代码
bin2c
转化为字符串
作为 target 的一部分添加
1 2 extern "C" char embedded_ptx_code[];
1 2 3 4 add_executable (ex02_pipelineAndRayGen ${embedded_ptx_code} );
E02-pipelineAndRayGen
1 2 3 4 5 6 7 8 inline OptixResult optixLaunch (OptixPipeline pipeline, CUstream stream, CUdeviceptr pipelineParams, size_t pipelineParamsSize, const OptixShaderBindingTable* sbt, unsigned int width, unsigned int height, unsigned int depth )
1 2 extern "C" __constant__ LaunchParams optixLaunchParams;
E03-inGLFWindow
E04-firstTriangleMesh
trace-ray 加速结构构建
optixAccelBuild()
optixAccelCompact()
作为 launchParams 传递给 cuda
PRD (per ray data)
通过 payload 传递,但是传递的数据必须是 32bit-int
在 ray-gen 中获得数据地址,通过 payload 传递给
closest-hit,解包地址写入数据
optixTrace
的最后参数就是变长参数,即 payload 的
slot(传递数据 PRD)
1 2 3 4 5 6 7 8 9 10 11 12 static __forceinline__ __device__void *unpackPointer (uint32_t i0, uint32_t i1) { const uint64_t uptr = static_cast <uint64_t >(i0) << 32 | i1; void *ptr = reinterpret_cast <void *>(uptr); return ptr; } static __forceinline__ __device__ void packPointer (void *ptr, uint32_t &i0, uint32_t &i1) { const uint64_t uptr = reinterpret_cast <uint64_t >(ptr); i0 = uptr >> 32 ; i1 = uptr & 0x00000000ffffffff ; }
E05-firstSBTData
optixGetSbtDataPointer()
从不同的 shader 中能够获取到不同的资源(SBT 生成的时候指定的)
E06-multipleObjects
optixAccelComputeMemoryUsage()
、optixAccelBuild()
中的每一个 OptixBuildInput
结构体指向一个 object
(Mesh)
optixGetSbtDataPointer()
:不同的
OptixBuildInput
对应不同的返回值
optixGetPrimitiveIndex()
:返回的是在每一个
OptixBuildInput
内部的索引
E07-firstRealModel
使用 tinyobjloader 加载 obj 模型
tinyobjloader 最原始的加载
加载结束包含多个 shape,每一个 shape 中的 mesh
结构包含所有的面片信息
每一个 shape
内部,顶点、法线、纹理坐标、材质贴图索引 都重新开始编号(从
0 开始)
mesh
包含每一个顶点的索引、每一个面的顶点数、每一个面的材质、(smoothing_group_ids、tags)
index 顶点索引包括位置、法向、纹理坐标
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 typedef struct { std::string name; mesh_t mesh; lines_t lines; points_t points; } shape_t ; typedef struct { std::vector<index_t > indices; std::vector<unsigned char > num_face_vertices; std::vector<int > material_ids; std::vector<unsigned int > smoothing_group_ids; std::vector<tag_t > tags; } mesh_t ; typedef struct { int vertex_index; int normal_index; int texcoord_index; } index_t ;
加载处理
按照材质进行分类,每一个材质构建一个新的索引序列(int),即顶点、法线、纹理共用一个索引
不同于原始的索引,原始的索引是(3 x
int),顶点、法线、纹理分开存索引
只有顶点、法线、纹理都相同的顶点(原始索引相同),索引才相同
other :也可以按照原始的方式,每一个顶点保存 3
个索引
处理完之后,每一个材质内部的做因都重新编号(都是从 0 开始)
1 2 3 4 5 6 7 8 9 10 11 struct TriangleMesh { std::vector<vec3f> vertex; std::vector<vec3f> normal; std::vector<vec2f> texcoord; std::vector<vec3i> index; vec3f diffuse; };
cpp 并行库:tbb
之后和E6 一样处理,每一个加载好的
mesh 作为一个 OptixBuildInput
E08-addingTextures
使用 cuda 的 API 进行控制
在模型加载的时候同时加载纹理,TriangleMesh
结构体中加上材质 ID
加载的纹理挂载到 model 上(不是 Mesh 上)
一个 model 上从 0 开始编码
通过文件名进行区分
1 2 3 4 5 struct TriangleMesh { int diffuseTextureID{-1 }; };
1 stbi_set_flip_vertically_on_load (true );
一起上传到 device 端,将指针保存到 SBT 结构中
1 2 3 4 5 6 7 8 9 struct TriangleMeshSBTData { vec3f color; vec3f *vertex; vec3f *normal; vec2f *texcoord; vec3i *index; bool hasTexture; cudaTextureObject_t texture; };
E09-shadowRays
增加 shadow ray
需要增加各种 shadow ray 的 program,在如下函数中添加
createMissPrograms()
createHitgroupPrograms()
sbt 也需要两个
shadow ray
在 __closesthit__radiance()
里面发射 shadow ray
在 miss shader 中设置 visible,其他的 shader 不需要
rayFlags 如下
1 2 3 4 5 6 rayFlags = OPTIX_RAY_FLAG_DISABLE_ANYHIT | OPTIX_RAY_FLAG_TERMINATE_ON_FIRST_HIT | OPTIX_RAY_FLAG_DISABLE_CLOSESTHIT;
E10-softShadows
软阴影
面光源
随机数生成器:simple 24-bit linear congruence generator
随机数也放在 PRD 中传递(每一根光线拥有自己的随机数种子)
样例实现
spp:raygen 中在像素内发生 \(N\)
条光线
shadow ray:在光源上采样 \(M\)
个点,做可见性测试,结果求平均作为最终结果
E11-denoiseColorOnly
1 2 3 4 5 6 7 optixDenoiserCreate ();optixDenoiserComputeMemoryResources ();optixDenoiserSetup ();optixDenoiserInvoke ();optixDenoiserDestroy ();
E12-denoiseSeparateChannels
在调用 optixDenoiserInvoke()
的时候加入
OptixDenoiserGuideLayer()
albedo, normal
具体数据在 __closesthit__radiance
中记录第一个点的
albedo、normal
同时加上了 tonemapping