提示和技巧:光线跟踪最佳实践 (3)

将负载和属性大小设置为可能的最小值。为MaxPayloadSizeInBytes和MaxAttributeSizeInBytes配置的值直接影响寄存器压力,因此不要将它们设置得高于应用程序/管道绝对需要的值。             

将最大跟踪递归深度设置为可能的最小值。跟踪递归深度影响为DispatchRays启动分配的堆栈内存量。这会对内存消耗和总体性能产生很大影响。

2.2 – Shaders

2.2.1 – General

保持射线有效载荷小。有效负载大小转换为寄存器计数,因此直接影响占用率。像打包gbuffer那样打包有效负载通常需要一些数学知识。大量的有效载荷会溢出到记忆中。             

保持低属性计数。与有效负载数据类似,自定义交集着色器的属性转换为寄存器计数,因此应保持最小值。固定函数三角形相交使用两个属性,这是一个很好的准则。             

尽可能使用RAY_FLAG_ACCEPT_FIRST_HIT_和_END_SEARCH/gl_RayFlagsTerminateOnFirstHitNV。例如,这通常适用于阴影光线和环境光遮挡光线。请注意,使用此标志比显式调用AcceptHitAndEndSearch()/terminateRayNV()的any hit着色器更有效。             

避免跨跟踪调用的实时状态。通常,在TraceRay调用之前计算并在TraceRay之后使用的变量必须溢出到堆栈中。编译器可以在某些情况下避免这种情况,例如使用重新物质化,但通常溢出是必要的。因此,材质球一开始越能避开它们,效果越好。在某些情况下,当阴影复杂度非常低并且没有递归TraceRay调用时,将一些活动状态放入有效负载中以避免溢出是有意义的。然而,这与保持有效载荷小的愿望相冲突,所以要非常明智地使用这个技巧。             

避免着色器中的跟踪调用过多。着色器中的许多TraceRay调用可能会导致次优性能和着色器编译时间。尝试构造代码,使多个跟踪调用合并为一个。             

明智地使用循环展开。如果所述循环包含跟踪调用(前一点的必然结果),则尤其如此。复杂的材质球可能会受到展开循环的影响,而不是从中受益。尝试HLSL中的[loop]属性或GLSL中的显式展开。              

尝试无条件执行TraceRay调用。保持TraceRay调用不使用“if”语句可以帮助编译器简化生成的代码并提高性能。不要使用条件,尝试将光线的tmin和tmax值设置为0以触发未命中,并且(如果需要正确的行为)使用无操作未命中着色器以避免意外的副作用。

Use RAY_FLAG_CULL_BACK_FACING_TRIANGLES / gl_RayFlagsCullBackFacingTrianglesNV judiciously。与光栅化不同,光线跟踪中的背面消隐通常不是性能优化,它可以导致执行更多而不是更少的工作。

2.2.2 – Ray-Generation Shaders

确保每个光线生成线程生成一个光线。在最终不会产生任何光线的光线生成着色器中调度/分配线程可能会损害调度。这里可能需要人工压实。

2.2.3 – Any Hit Shaders

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzwgsj.html