Embree使用指南(无SYCL)

        Intel®Embree是由Intel开发的高性能光线跟踪库,以Apache 2.0许可证的开源形式发布。

        Embree的目标是图形应用程序开发人员,以提高逼真照片渲染应用程序的性能。Embree针对生产渲染进行了优化,重点关注非相干光线性能、高质量的加速结构构建、丰富的特征集、准确的原始交集和低内存消耗。

        Embree的特征集包括各种基本类型,如三角形(以及用于降低内存消耗的四边形和网格);Catmull-Clark细分曲面;各种类型的曲线基元,如平面曲线(用于远处视图)、圆曲线(用于近景视图)和法线方向的曲线,所有这些都支持不同的基函数(线性、Bézier、B样条、Hermite和Catmull-Rom);类点基元,例如面向射线的圆盘、面向法线的圆盘和球体;具有过程交集函数的用户定义几何图形;多级实例化;为遇到的任何命中调用的筛选器回调;运动模糊,包括多段运动模糊、变形模糊和四元数运动模糊;和射线掩蔽。

1、Embree API

设备对象

        Embree支持一个设备概念,该概念允许应用程序的不同组件使用Embree API,而不会相互干扰。应用程序通常首先使用[rtcNewDevice]函数创建设备(或当GPU使用SYCL时使用[rtc NewSYCLDevice])。

        然后,该设备可以用于构建其他对象,如场景和几何图形。在应用程序退出之前,它应该通过调用[rtcReleaseDevice]来释放所有设备。一个应用程序通常只创建一个设备。如果有不同的要求,它在任何给定时间都应该只使用少量设备。

        每个用户线程在每个设备上都有自己的错误标志。如果调用API函数时发生错误,则将此标志设置为错误代码(如果以前的错误尚未设置)。

        有关如何读取错误代码的信息,请参阅第[rtcGetDeviceError]节,以及有关如何注册为遇到的每个错误调用的回调的第[rtcSetDeviceErrorFunction]节。建议始终设置错误回调函数,以检测所有错误。

场景对象

        场景是一组几何图形的容器,包含可用于执行不同类型光线查询的空间加速结构。

        使用rtcNewScene函数调用创建场景,并使用rtcReleaseScene函数函数调用释放场景。若要使用几何体填充场景,请使用rtcAttachGeometry调用,若要分离几何体,请使用rtsDetachGeometry呼叫。

        附加所有场景几何体后,rtcCommittScene调用(或rtcJoinCommitSene调用)将完成场景描述并触发内部数据结构的构建。场景提交后,可以安全地执行光线查询(请参见“光线查询”一节)或查询场景边界框(请参见[rtcGetSceneBounds]和[rtcGetSceneLinearBounds])。

        如果场景几何图形被修改、附加或分离,则在对场景执行任何进一步的光线查询之前,必须调用rtcCommittScene调用;否则,光线查询的效果是未定义的。几何体的修改、场景的提交和光线的跟踪必须始终按顺序进行,而决不能同时进行。将场景计数中包含的场景或几何图形的属性设置为场景修改的任何API调用,例如包括交叉点过滤器函数的设置。

几何对象

        使用 rtcNewGeometry 函数创建新的几何体。根据几何体类型,必须绑定不同的缓冲区(例如使用 rtcSetSharedGeometryBuffer来设置几何体数据。在大多数情况下,需要绑定顶点和索引缓冲区。通常根据这些绑定缓冲区的大小来推断该几何体的基元和顶点数量。

        在使用几何体之前,必须始终使用 rtcCommitGeometry 调用提交对几何体的更改。提交后,几何体将不包含在任何场景中。可以使用 rtcAttachGeometry 函数(自动分配几何体 ID)或使用 rtcAttachGeometryById 函数(手动指定几何体 ID)将几何体添加到场景中。几何体可以附加到多个场景。

        所有几何类型都支持在用户指定的时间范围内使用任意数量的等距时间步(在2到129的范围内)的多段运动模糊。每个几何体可以有不同数量的时间步和不同的时间范围。运动模糊几何体是通过线性插值相邻时间步的几何体来定义的。

        要构造运动模糊几何体,首先必须使用 rtcSetGeometryTimeStepCount 函数指定几何体的时间步数,然后必须绑定每个时间步的顶点缓冲区,例如使用 rtcSetSharedGeometryBuffer 函数。可选地,可以使用 rtcSetGeometryTimeRange 函数设置定义第一个(和最后一个)时间步的开始(和结束时间)的时间范围。如果时间范围是[0,1]的子范围,则此功能还将允许几何体在相机快门时间期间出现和消失。

射线查询

        API支持查找光线片段与场景最接近的命中(rtcIntersect-type函数),并确定光线片段与该场景之间是否存在任何命中(rtc遮挡类型函数)。

        支持单个光线查询(rtcIntersect1和rtcOccluded1),以及针对大小为4(rtcIntersect4和rtcOccluded4)的光线包、大小为8(rtcntersect8和rtcFCcluded8)的光线数据包和大小为16(rtcInterface 16和rtcConccluded16)的光线信息包的光线信息查询。

点查询

        API支持使用指定位置和查询半径的点查询对象遍历BVH。对于与相应域相交的所有基元,将调用用户定义的回调函数,该函数允许查询,例如查找场景的曲面几何图形上的最近点(请参见教程“最近点”)或最近邻居查询(请参见Tutorial Voronoi)。

碰撞检测

        Embree API还支持仅由用户几何图形组成的两个场景之间的冲突检测查询。Embree只执行宽相位碰撞检测,窄相位检测可以通过回调函数执行。

滤波函数

        API支持为rtcIntersect-type或rtcOccluded-type调用期间找到的每个交叉点调用的过滤器函数。

        可以使用rtcSetGeometryIntersectFilterFunction和rtcSetGeometryOccludedFilterFunction调用为每个几何体设置过滤函数。前者称为几何相交过滤函数,后者称为几何遮挡过滤函数。这些过滤函数被设计用于忽略基本体的用户定义轮廓之外的交叉点,例如使用透明纹理对树叶进行建模。

BVH构建

        构建BVH的内部算法通过RTCBVH对象和rtcBuildBVH调用公开。通过此调用,可以在用户指定的基元上以用户指定的格式构建BVH。有关更多详细信息,请参阅rtcBuildBVH调用的文档。

2、函数

rtcNewDevice-创建一个新设备

rtcRetainDevice-增加设备引用计数

rtcReleaseDevice-减少设备引用计数

rtcGetDeviceProperty-查询设备的属性

         RTC_DEVICE_PROPERTY_VERSION:查询组合版本号(MAJOR.MINOR.PACH),每个组件有两位小数。例如,对于Embree 2.8.3,返回整数208003。

        RTC_DEVICE_PROPERTY_VERSION_MAJOR:查询Embree的主要版本号。

        RTC_DEVICE_PROPERTY_VERSION_MINOR:查询Embree的次要版本号。

        RTC_DEVICE_PROPERTY_VERSION_PATCH:查询Embree的补丁版本号。

        RTC_DEVICE_PROPERTY_NATIVE_RAY4_SUPPORTED:查询rtcIntersect4和rtcOccluded4函数在调用回调函数时是否保留数据包大小和光线顺序。只有在编译Embree时启用了Embree_RAY_PACKETS和SSE2(或SSE4.2),并且运行它的机器支持SSE2(或者SSE4.2)时,才会出现这种情况。

        RTC_DEVICE_PROPERTY_NATIVE_RAY8_SUPPORTED:查询rtcIntersect8和rtcOccluded8函数在调用回调函数时是否保留数据包大小和光线顺序。只有在编译Embree时启用了Embree_RAY_PACKETS和AVX(或AVX2),并且运行它的机器支持AVX(或者AVX2)时,才会出现这种情况。

        RTC_DEVICE_PROPERTY_NATIVE_RAY16_SUPPORTED:查询rtcIntersect16和rtcOccluded16函数在调用回调函数时是否保留数据包大小和光线顺序。只有当Embree是在启用Embree_RAY_PACKETS和AVX512的情况下编译的,并且运行它的机器支持AVX512时,才会出现这种情况。

        RTC_DEVICE_PROPERTY_RAY_MASK_SUPPORTED:查询是否支持光线遮罩。只有在启用Embree_RAY_MASK的情况下编译Embree时才会出现这种情况。

        RTC_DEVICE_PROPERTY_BACKFACE_CULLING_ENABLED:查询是否启用了背面剔除。只有在启用Embree_BACKFACE_CULLING的情况下编译Embree时才会出现这种情况。

        RTC_DEVICE_PROPERTY_BACKFACE_CULING_CURVES_ENABLED:查询是否启用了曲线的背面剔除。只有在启用Embree_BACKFACE_CULLING_CURVES的情况下编译Embree时才会出现这种情况。

        RTC_DEVICE_PROPERTY_BACKFACE_CULLING_SPHERES_ENABLED:查询是否启用了球体的背面剔除。只有在启用Embree_BACKFACE_CULLING_SPHERES的情况下编译Embree时才会出现这种情况。

        RTC_DEVICE_PROPERTY_COMPACT_POLYS_ENABLED:查询是否启用了紧凑型多边形。只有在启用Embree_COMPACT_POLYS的情况下编译Embree时才会出现这种情况。

        RTC_DEVICE_PROPERTY_FILTER_FUNCTION_SUPPORTED:查询是否支持筛选器函数,如果Embree是在启用Embree_FILTER-FUNCTION的情况下编译的,则会出现这种情况。

        RTC_DEVICE_PROPERTY_IGNORE_INVALID_RAYS_ENABLED:查询是否忽略无效射线,如果Embree是在启用Embree_IGNORE-INVALID_RAYS的情况下编译的,则会出现这种情况。

        RTC_DEVICE_PROPERTY_TRIANGLE_GEOMETRY_SUPPORTED:查询是否支持三角形,如果Embree是在启用Embree_GEOMETERY_TRIANGLE的情况下编译的,则会出现这种情况。

        RTC_DEVICE_PROPERTY_QUAD_GEOMETRY_SUPPORTED:查询是否支持四边形,如果Embree是在启用Embree_GEOMETRY_QUAD的情况下编译的,则会出现这种情况。

        RTC_DEVICE_PROPERTY_SUBDIVISION_GEOMETRY_SUPPORTED:查询是否支持细分网格,如果Embree是在启用Embree_GEOMETY_SUBDIVISION的情况下编译的,则会出现这种情况。

        RTC_DEVICE_PROPERTY_CURVE_GEOMETRY_SUPPORTED:查询是否支持曲线,如果Embree是在启用Embree_GEOMETERY_CURVE的情况下编译的,则会出现这种情况。

        RTC_DEVICE_PROPERTY_POINT_GEOMETRY_SUPPORTED:查询是否支持点,如果Embree是在启用Embree_GEOMETERY_POINT的情况下编译的,则会出现这种情况。

        RTC_DEVICE_PROPERTY_USER_GEOMETRY_SUPPORTED:查询是否支持用户几何图形,如果Embree是在启用Embree_GEOMETY_USER的情况下编译的,则会出现这种情况。

        RTC_DEVICE_PROPERTY_TASKING_SYSTEM:查询编译Embree的任务系统。可能的返回值为:内部任务系统;英特尔线程构建块(TBB);并行模式库(PPL)

         RTC_DEVICE_PROPERTY_JOIN_COMMIT_SUPPORTED:查询是否支持rtcJoinCommitScene。当使用PPL或旧版本的TBB编译Embree时,情况并非如此。

        RTC_DEVICE_PROPERTY_PALLEL_COMMIT_SUPPORTED:查询是否可以同时从多个TBB工作线程调用rtcCommittScene。仅从TBB 2019更新9开始支持此功能。

rtcGetDeviceError-返回设备的错误代码
RTCError rtcGetDeviceError(RTCDevice device);

        RTC_ERROR_NONE:未发生错误。

        RTC_ERROR_UNKNOWN:发生未知错误。

        RTC_ERROR_INVALID_ARGUMENT:指定的参数无效。

        RTC_ERROR_INVALID_OPERATION:不允许对指定的对象执行该操作。

        RTC_ERROR_OUT_OF_MEMORY:剩余内存不足,无法完成操作。

        RTC_ERROR_UNSUPPORTED_CPU:不支持CPU,因为它不支持编译的最低ISA Embree。

        RTC_ERROR_CANCELLED:内存监视器回调或进度监视器回调函数取消了操作。 

rtcSetDeviceErrorFunction-为设备设置错误回调函数

typedef void (*RTCErrorFunction)(
  void* userPtr,
  RTCError code,
  const char* str
);

void rtcSetDeviceErrorFunction(
  RTCDevice device,
  RTCErrorFunction error,
  void* userPtr
);

rtcSetDeviceMemoryMonitorFunction-注册一个回调函数来跟踪内存消耗

void rtcSetDeviceMemoryMonitorFunction(
  RTCDevice device,
  RTCMemoryMonitorFunction memoryMonitor,
  void* userPtr
);

rtcNewScene-创建新场景

rtcGetSceneDevice-返回在其中创建场景的设备

rtcRetainScene-增加场景引用计数

rtcReleaseScene-减少场景引用计数

rtcAttachGeometry-将几何体附加到场景

rtcAttachGeometryByID-使用指定的几何体ID将几何体附加到场景

   

rtcDetachGeometry-从场景中分离几何体

rtcGetGeometry-返回绑定到指定几何体ID的几何体

rtcCommittScene-提交场景更改

rtcCommittGeometry-提交几何体更改

rtcJoinCommitScene-从多个线程提交场景

rtcSetSceneProgressMonitorFunction-注册回调以跟踪生成进度

rtcSetSceneBuildQuality-设置场景的构建质量

        RTC_BUILD_QUALITY_LOW:创建较低质量的数据结构,例如用于动态场景。启用此模式时会构建两级空间索引结构,支持快速局部场景更新,并允许通过rtcSetGeometryBuildQuality函数设置每个几何体的构建质量。

        RTC_BUILD_QUALITY_MEDIUM:大多数用途的默认生成质量。在生成性能和渲染性能之间提供良好的折衷。

        RTC_BUILD_QUALITY_HIGHT:为最终帧渲染创建更高质量的数据结构。对于某些几何图形类型,这将启用空间拆分BVH。启用高质量模式时,可以对同一几何体多次调用过滤器回调。 

rtcSetSceneFlags-设置场景的标志

        RTC_SCENE_FLAG_NONE:未设置任何标志。

        RTC_SCENE_FLAG_DYNAMIC:为动态场景提供更好的构建性能(但也更高的内存消耗)。

        RTC_SCENE_FLAG_COMPACT:使用紧凑的加速结构,避免使用消耗大量内存的算法。

        RTC_SCENE_FLAG_ROBUST:使用允许稳健遍历的加速结构,并避免降低算术精度的优化。此模式通常用于避免光线穿过相邻基本体的边缘而导致的伪影。

        RTC_SCENE_FLAG_FILTER_UNCTION_IN_ARGUMENTS:启用对作为参数传递给遍历函数的筛选器函数的场景支持。

rtcGetSceneFlags-返回场景的标志

rtcGetSceneBounds-返回场景的轴对齐边界框

rtcGetSceneLinearBounds-返回场景的线性边界

rtcNewGeometry-创建一个新的几何体对象

        几何体是表示相同类型的基元数组的对象。rtcNewGeometry函数创建绑定到指定设备(设备参数)的指定类型(类型参数)的新几何体,并返回该几何体的句柄。几何体对象是参考计数的,初始参考计数为1。可以使用rtcReleaseGeometry API调用释放几何体句柄。       

        构建后,默认情况下会启用几何体,并且不会附加到任何场景。几何图形可以被禁用(rtcDisableGeometry调用),也可以再次启用(rtcEnableGeometry呼叫)。可以使用rtcAttachGeometry调用(或rtcAttacheGeometryByID调用)将几何体附加到多个场景,并使用rtcDetachGeometry呼叫分离几何体。在附着过程中,几何体ID会指定给几何体(或由用户在使用rtcAttachGeometryByID调用时指定),该ID唯一标识该场景中的几何体。当几何体的基本体在以后的场景光线查询中被命中时,将返回此标识符。

        几何图形也可以修改,包括其顶点和索引缓冲区。修改缓冲区后,必须调用rtcUpdateGeometryBuffer来通知缓冲区已被修改。

        应用程序可以使用rtcSetGeometryUserData函数将用户数据指针设置为其自己的几何表示,然后使用rtcGetGeometryUser数据函数读取该指针。

        设置或修改几何体后,必须调用rtcCommittGeometry来完成几何体设置。在提交几何体之后,可以使用rtcInterpolate和rtcInterpolateN函数执行顶点数据插值。

RTC_GEOMETRY_TYPE_TRIANGLE-三角形几何类型

RTC_GEOMETRY_TYPE_QUAD 四元几何类型

RTC_GEOMETRY_TYPE_GRID-网格几何类型

RTC_GEOMETRY_TYPE_SUBDIVISION-细分几何体类型

RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE-
线性基的平曲线几何

RTC_GEOMETRY_TYPE_FLAT_beziercurve-
三次Bézier基的平曲线几何

RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE-
三次B样条基的平曲线几何

RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE-
三次Hermite基的平曲线几何

RTC_GEOMETRY_TYPE_FLAT_catmul_ROM_CURVE-
Catmull-Rom基的平曲线几何

RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE-
三次Bézier基的平面法向曲线几何

RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_scurve-
三次B样条基平面法线定向曲线几何

RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_HERMITE_CURVE-
具有三次Hermite基的平坦法线定向曲线几何

RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_CATMULL_ROM_CURVE-
基于Catmull-Rom基的平面法向曲线几何

RTC_GEOMETRY_TYPE_CONE_LINEAR_CURVE-
带线性基的帽锥曲线几何&边界不连续

RTC_GEOMETRY_TYPE_ROUND_LINEAR_CURVE-
带线性基和球形端点的帽锥曲线几何

RTC_GEOMETRY_TYPE_ROUND_beziercurve-
基于三次Bézier基的扫掠曲面曲线几何

RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE-
基于三次B样条的扫掠曲面曲线几何

RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE-
基于三次Hermite基的扫掠曲面曲线几何

RTC_GEOMETRY_TYPE_ROUND_catmul_ROM_CURVE-
基于Catmull-Rom基的扫掠曲面曲线几何

RTC_GEOMETRY_TYPE_SPHERE_POINT-点几何球体

RTC_GEOMETRY_TYPE_DISC_POINT-具有射线定向圆盘的点几何图形

RTC_GEOMETRY_TYPE_ORIENTED_DISC_POINT-具有法线定向圆盘的点几何图形

RTC_GEOMETRY_TYPE_USER-用户几何体类型

RTC_GEOMETRY_TYPE_INSTANCE-实例几何体类型

RTC_GEOMETRY_TYPE_INSTANCE_ARAY-实例数组几何体类型

  

RTCCurveFlags-曲线几何图形的每段标志

rtcRetainGeometry-增加几何体引用计数

  

rtcReleaseGeometry-减少几何体引用计数

  

rtcCommittGeometry-提交几何体更改

rtcEnableGeometry-启用几何体

rtcDisableGeometry-禁用几何体

   

rtcSetGeometryTimeStepCount-设置几何体的时间步数

  

rtcSetGeometryTimeRange-设置运动模糊几何体的时间范围

rtcSetGeometryVertexAttributeCount-设置几何体的顶点属性数

  

rtcSetGeometryMask-设置几何体掩码

  

rtcSetGeometryBuildQuality-设置几何体的构建质量

   

rtcSetGeometryMaxRadiusScale-为最小宽度特征指定最大曲线半径比例因子

rtcSetGeometryBuffer-为几何体指定缓冲区视图

rtcSetSharedGeometryBuffer-将共享数据缓冲区的视图分配给几何体

rtcSetNewGeometryBuffer-创建一个新的数据缓冲区并将其分配给几何体

        rtcSetNewGeometryBuffer:这个函数通常用于为新创建的几何体设置缓冲区。当你首次创建一个几何体并需要为其分配缓冲区时,你会使用这个函数。它通常涉及到内存分配,因为你需要为几何体数据提供存储空间。在设置缓冲区之后,Embree会负责管理这块内存,并在必要时进行优化。

        rtcSetGeometryBuffer:这个函数用于更新已存在的几何体的缓冲区。当你需要修改几何体的数据,但不想重新创建一个新的几何体时,你会使用这个函数。它允许你更改顶点数据、索引等,而不会影响到几何体的其他属性或设置。这个函数不涉及内存分配,因为它只是更新已分配的内存区域。

RTCFormat-指定缓冲区中数据的格式

  

rtcGetGeometryBufferData-获取指向第一个缓冲区视图元素的指针

rtcUpdateGeometryBuffer-将绑定到几何体的缓冲区视图标记为已修改

rtcSetGeometryIntersectFilterFunction-设置几何图形的交集过滤器

rtcSetGeometryOccludedFilterFunction-设置几何体的遮挡过滤器

        rtcSetGeometryIntersectFilterFunction:这个函数用于设置当光线与几何体相交时的过滤函数。当光线与几何体相交时,这个过滤函数会被调用,允许你自定义相交的处理方式。你可以使用这个函数来定义自定义的相交测试,例如基于纹理、法线方向、材质属性等。它主要用于处理光线与物体表面相交的情况,提供更多的控制和自定义能力。

        rtcSetGeometryOccludedFilterFunction:这个函数用于设置当光线被几何体遮挡时的过滤函数。当光线被几何体完全遮挡,即无法继续前进时,这个过滤函数会被调用。与rtcSetGeometryIntersectFilterFunction类似,你可以使用这个函数来自定义遮挡的处理方式。它主要用于处理光线被物体完全遮挡的情况,提供更多的控制和自定义能力。

rtcSetGeometryEnableFilterFunctionFromArguments-为几何体启用参数筛选函数

rtcInvokeIntersectFilterFromGeometry-从几何体调用交集过滤器函数

  

rtcInvokeOccludedFilterFromGeometry-从几何体调用遮挡过滤器函数

        rtcSetGeometryIntersectFilterFunction:这个函数用于为几何体设置一个过滤函数,该函数将在每个相交操作之前被调用。它提供了一个自定义的过滤机制,允许你根据特定条件来决定是否接受或拒绝相交操作。你可以在过滤函数中根据需要执行各种检查,例如基于材质、对象类型、碰撞属性等。使用这个函数,你可以在相交操作之前应用自定义的逻辑,从而影响相交的结果或行为。

        rtcInvokeIntersectFilterFromGeometry:这个函数允许你直接从几何体调用一个已存在的过滤函数。它提供了一种方式,让你能够利用已经设置好的过滤函数来过滤相交操作。与rtcSetGeometryIntersectFilterFunction不同,它不是用于设置新的过滤函数,而是用于调用现有的过滤函数。这使得你可以复用已经定义好的过滤逻辑,而不需要为每个几何体重新定义或设置过滤函数。

        总结一下,rtcSetGeometryIntersectFilterFunction是用于设置自定义过滤函数的,而rtcInvokeIntersectFilterFromGeometry是用于调用已存在的过滤函数的。

rtcSetGeometryUserData-设置几何图形的用户定义数据指针

rtcGetGeometryUserData-返回几何图形的用户数据指针

rtcGetGeometryUserDataFromScene-通过场景对象返回几何体的用户数据指针

rtcSetGeometryUserPrimitiveCount-设置用户定义的几何体的基元数

rtcSetGeometryBoundsFunction-设置回调以查询用户定义基元的边界框

rtcSetGeometryIntersectFunction-将回调函数设置为与用户几何图形相交

rtcSetGeometryOccludedFunction-设置回调函数以测试用户几何体的遮挡

rtcSetGeometryPointQueryFunction-设置几何图形的点查询回调函数

rtcGetSYCLDeviceFunctionPointer-获取某些SYCL函数的设备端函数指针

rtcSetGeometryInstancedScene-设置实例几何体的实例化场景

void rtcSetGeometryInstancedScene(
  RTCGeometry geometry,
  RTCScene scene
);
rtcSetGeometryInstancedScenes-设置实例阵列几何体可以实例化的场景阵列

void rtcSetGeometryInstancedScenes(
  RTCGeometry geometry,
  RTCScene* scene,
  size_t numScenes
);

rtcSetGeometryTransform-为实例几何体的特定时间步长设置变换

rtcSetGeometryTransformQuaternion-将实例几何体的特定时间步长的变换
设置为使用四元数表示旋转的变换矩阵的分解。

rtcGetGeometryTransform-返回指定时间内的插值实例转换

rtcGetGeometryTransformEx-返回指定时间内实例数组几何体实例的插值实例变换。

rtcGetGeometryTransformFromScene-返回指定时间的插值实例变换

rtcSetGeometryEssellationRate-设置几何体的镶嵌速率

rtcSetGeometryTopologyCount-设置细分几何体的拓扑数量

rtcSetGeometrySubdivisionMode-设置细分几何体的细分模式

rtcSetGeometryDisplacementFunction-设置细分几何体的位移函数

void rtcSetGeometryDisplacementFunction(
  RTCGeometry geometry,
  RTCDisplacementFunctionN displacement
);

rtcGetGeometryFirstHalfEdge-返回面的前半条边

rtcGetGeometryFace-返回某个半边的面

rtcGetGeometryNextHalfEdge-返回下一个半边

rtcGetGeometryPreviousHalfEdge-返回上一个半边

rtcInterpolateN-执行顶点属性数据的N次插值

rtcNewBuffer-创建一个新的数据缓冲区

rtcNewSharedBuffer-创建一个新的共享数据缓冲区

        当缓冲区将用作顶点缓冲区时(RTC_buffer_TYPE_vertex和RTC_buffer_TYPE_VETEX_ATTRIBUTE),最后一个缓冲区元素必须使用16字节SSE加载指令可读,因此某些布局需要填充最后一个元素。例如,标准float3顶点缓冲区布局应将至少一个以上浮点的存储添加到缓冲区的末尾。

rtcRetainBuffer-增加缓冲区引用计数

rtcReleaseBuffer-减少缓冲区引用计数

rtcGetBufferData-获取指向缓冲区数据的指针

        RTCRay:这是一个光线,它从一个光源发出,穿过像素网格,并试图找到一个物体表面。如果光线击中一个物体,那么这个击中点就是RTCRay的终点。

        RTCHit:当光线击中一个物体时,这个击中点就是RTCHit。它描述了光线与物体表面的交互点,包括表面的颜色、纹理、光照等信息。

RTCRayN-运行时大小的射线数据包

RTCHitN-运行时大小的命中数据包

RTCRayHitN-运行时大小的组合射线/命中数据包

RTCFeatureFlags-指定要为光线查询启用的功能

 RTC_FEATURE_FLAG_MOTION_BLUR:为所有几何体类型启用运动模糊。

RTC_FEATURE_FLAG_TRIANGLE:启用三角形几何图形(RTC_GEOMETRY_TYPE_TRIANGLE)。

RTC_FEATURE_FLAG_QUAD:启用四元几何图形(RTC_GEOMETRY_TYPE_QUAD)。

RTC_FEATURE_FLAG_GRID:启用栅格几何图形(RTC_GEOMETRY_TYPE_GRID)。

RTC_FEATURE_FLAG_SUBDIVISION:启用细分几何图形(RTC_GEOMETRY_TYPE_SUBDIVISION)。

RTC_FEATURE_FLAG_POINT:启用所有点几何图形类型(RTC_geometry_TYPE_XXX_POINT)

RTC_FEATURE_FLAG_CURVES:启用所有曲线几何图形类型(RTC_geometry_TYPE_XXX_YYY_curve)

RTC_FEATURE_FLAG_ROUND_CURVES:启用所有圆形曲线(RTC_GEOMETRY_TYPE_ROUND_XXX_CURVE)。

RTC_FEATURE_FLAG_FLAG_CURVES:启用所有平坦曲线(RTC_GEOMETRY_TYPE_FLAT_XXX_CURVE)。

RTC_FEATURE_FLAG_NORMAL_ORINTED_CURVES:启用所有法线方向的曲线(RTC_GEOMETRY_TYPE_NORMAL_OORINTED_XXX_CURVE)。

RTC_FEATURE_FLAG_LINAR_CURVES:启用所有线性曲线(RTC_GEOMETRY_TYPE_XXX_LINEAR_CURVE)。

RTC_FEATURE_FLAG_BEZIER_CURVES:启用所有Bézier曲线(RTC_GEOMETRY_TYPE_XXX_BEZIER_CURVE)。

RTC_FEATURE_FLAG_BSPLINE_CURVES:启用所有B样条曲线(RTC_GEOMETRY_TYPE_XXX_BSPLINE_CURVE)。

RTC_FEATURE_FLAG_HERMITE_CURVES:启用所有埃尔米特曲线(RTC_GEOMETRY_TYPE_XXX_HERMITE_CCURVE)。

RTC_FEATURE_FLAG_CONE_LINEAR_CURVE:启用圆锥体几何图形类型(RTC_geometry_type_CONE_LINEAR_CURVE)。

RTC_FEATURE_FLAG_ROUND_LINEAR_CURVE:启用圆形线性曲线(RTC_GEOMETRY_TYPE_ROUND_LINAR_CURVE)。

RTC_FEATURE_FLAG_LAT_LINEAR_CURVE:启用平坦线性曲线(RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE)。

RTC_FEATURE_FLAG_ROUND_BEZIER_CURVE:启用圆Bézier曲线(RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE)。

RTC_FEATURE_FLAG_FLAG_BEZIER_CURVE:启用平坦的Bézier曲线(RTC_GEOMETRY_TYPE_FLAT_BEZIER-CURVE)。

RTC_FEATURE_FLAG_NORMAL_ORIENTED_BEIZIER_CURVE:启用法线方向的贝塞尔曲线(RTC_GEOMETRY_TYPE_NORMAL_OERINTED_BEZIER_CURVE)。

RTC_FEATURE_FLAG_ROUND_BSPLINE_CURVE:启用圆形B样条曲线(RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE)。

RTC_FEATURE_FLAG_LAT_BSPLINE_CURVE:启用平坦B样条曲线(RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE)。

RTC_FEATURE_FLAG_NORMAL_ORIENTED_BSPLINE_CURVE:启用法线方向的B样条曲线(RTC_GEOMETRY_TYPE_NORMAL_OLIENTED_BSTLINE_CURVE.)。

RTC_FEATURE_FLAG_ROUND_HERMITE_CURVE:启用圆形埃尔米特曲线(RTC_GEOMETRY_TYPE_ROUND_HERITE_CURVE)。

RTC_FEATURE_FLAG_FLAT_HERMITE_CURVE:启用平坦的埃尔米特曲线(RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE)。

RTC_FEATURE_FLAG_NORMAL_ORIENTED_HERMITE_CURVE:启用法线方向的埃尔米特曲线(RTC_GEOMETRY_TYPE_NORMAL_OERINTED_HERMITE_CCURVE)。

RTC_FEATURE_FLAG_ROUND_CAMULL_ROM_CURVE:启用圆形CATMULL-ROM曲线(RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_URVE)。

RTC_FEATURE_FLAG_LAT_CATMULL_ROM_CURVE:启用平坦CATMULL-ROM曲线(RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE)。

RTC_FEATURE_FLAG_NORMAL_ORINTED_CATMULL_ROM_CURVE:启用法线方向的CATMULL-ROM曲线

RTC_GEOMETRY_TYPE_NORMAL_ORINNTED_CATMULL_ROM_URVE)。
RTC_FEATURE_FLAG_PHERE_POINT:启用球体几何体类型(RTC_geometry_type_SPHERE_POINT)。

RTC_FEATURE_FLAG_DISC_POINT:启用光盘几何类型(RTC_geometry_type_DISC_POINT)。

RTC_FEATURE_FLAG_ORIENTED_DISC_POINT:启用定向光盘几何类型(RTC_geometry_TYPE_ORIENTEDD_DISC_POINT)。

RTC_FEATURE_FLAG_INSTANCE:启用实例几何图形(RTC_GEOMETRY_TYPE_INSTANCE)。

RTC_FEATURE_FLAG_FILTER_UNCTION_IN_ARGUMENTS:启用通过相交参数传递的筛选器函数。

RTC_FEATURE_FLAG_FILTER_UNCTION_IN_GEOMETRY:启用通过几何体的过滤函数。

RTC_FEATURE_FLAG_FILTER_UNCTION:启用过滤器功能(参数和几何体版本)。

RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_ARGUMENTS:启用

RTC_GEOMETERY_TYPE_USER,函数指针通过相交参数传递。

RTC_FEATURE_FLAG_USER_GEOMETRY_CALLBACK_IN_GEOMETRY:启用函数指针通过几何对象的RTC_GEOMETRY_TYPE_USER。

RTC_FEATURE_FLAG_USER_GEOMETRY:启用RTC_GEOMETRY_TYPE_USER几何图形(参数和几何图形回调版本)。

RTC_FEATURE_FLAG_32_BIT_RAY_MASK:启用完整的32位光线遮罩。如果不使用,则仅正确处理射线掩模中较低的7位。

RTC_FEATURE_FLAG_ALL:启用所有功能(默认)。

rtcInitIntersectArguments-初始化intersect arguments结构

rtcInitOccludedArguments-初始化被遮挡的参数结构

rtcInitRayQueryContext-初始化光线查询上下文

        rtcOccluded:这个函数用于确定光线是否被场景中的物体完全遮挡。如果光线被某个物体完全遮挡,它会返回该物体的ID和遮挡点的参数值。它通常用于确定光线是否被遮挡,而不是仅仅与物体相交。如果光线与物体相交但没有被完全遮挡,此函数可能不会返回任何结果。

        rtcIntersect:这个函数用于确定光线是否与场景中的任何物体相交。如果光线与某个物体相交,它会返回该物体的ID和相交点的参数值。它通常用于确定光线是否与任何物体相交,而不考虑之前是否已经测到相交。

        总结:rtcOccluded用于检测光线是否被物体完全遮挡。rtcIntersect用于检测光线是否与任何物体相交。 

rtcOccluded1-查找单个光线的任何命中

rtcIntersect1-查找单个光线的最接近命中数

rtcIntersect4/8/16-查找射线包的最接近命中数

rtcOccluded4/16-查找射线包的任何命中

        rtcForwardOccluded1:这个函数是用于前向遮挡查询的。前向遮挡查询是一种直接的方法,其中光线从相机位置发出,检查是否与任何几何体相交。rtcForwardOccluded1允许你查询一个光线是否与一个几何体相交,并返回遮挡状态。它通常用于渲染过程中,检查从相机到像素的光线是否被遮挡。

        rtcOccluded:这个函数用于检查光线与一组几何体的遮挡关系。它是一种更通用的方法,可以处理多个几何体的遮挡情况。rtcOccluded接受一个光线和一个几何体ID数组,并返回一个布尔值,指示光线是否与这些几何体中的任何一个相交。它可以用于各种场景,包括检查场景中任意光线与多个几何体的遮挡关系。

        总结一下,rtcForwardOccluded1专注于单个几何体的遮挡查询,通常用于渲染中的前向遮挡检查;而rtcOccluded则提供了一种更通用的方法,用于检查多个几何体的遮挡关系。选择使用哪个函数取决于你的具体需求和场景:如果你只需要检查单个几何体的遮挡关系,使用rtcForwardOccluded1;如果你需要处理多个几何体的遮挡情况,使用rtcOccluded

        rtcForwardOccluded1:这个函数用于确定光线是否被场景中的物体完全遮挡。如果光线被某个物体完全遮挡,它会返回该物体的ID和遮挡点的参数值。它通常用于确定光线是否被遮挡,而不是仅仅与物体相交。如果光线与物体相交但没有被完全遮挡,此函数可能不会返回任何结果。

        rtcForwardIntersect1:这个函数用于确定光线是否与场景中的任何物体相交。如果光线与某个物体相交,它会返回该物体的ID和相交点的参数值。它通常用于确定光线是否与任何物体相交,而不考虑之前是否已经检测到相交。       

rtcForwardIntersect1/Ex-将单个光线从用户几何体回调转发到新场景

void rtcForwardIntersect1(
  const struct RTCIntersectFunctionNArguments* args,
  RTCScene scene,
  struct RTCRay* ray,
  unsigned int instID
);
rtcForwardOcclude1/Ex-将单个光线从用户几何体回调转发到新场景

void rtcForwardOccluded1(
  const struct RTCOccludedFunctionNArguments* args,
  RTCScene scene,
  struct RTCRay* ray,
  unsigned int instID
);

   rtcForwardIntersectrtcForwardOccluded是RTC(Real-Time Collision)检测中用于光线追踪的两个常用函数。这两个函数都用于确定光线与场景中的物体是否相交,但它们的目的和行为有所不同。

        rtcForwardIntersect:这个函数用于确定光线是否与场景中的任何物体相交。如果光线与某个物体相交,它会返回该物体的ID和相交点的参数值。它通常用于确定光线是否与场景中的任何物体相交,而不考虑之前是否已经检测到相交。

        rtcForwardOccluded:这个函数用于确定光线是否被场景中的物体完全遮挡。如果光线被某个物体完全遮挡,它返回该物体的ID和遮挡点的参数值。它通常用于确定光线是否被遮挡,而不是仅仅与物体相交。如果光线与物体相交但没有被完全遮挡,则此函数可能不会返回任何结果。

rtcForwardIntersect4/8/16/Ex-将光线包从用户几何体回调转发到新场景

void rtcForwardIntersect4(
  void int* valid,
  const struct RTCIntersectFunctionNArguments* args,
  RTCScene scene,
  struct RTCRay4* ray,
  unsigned int instID
);
rtcForwardOccluded4/16/16/Ex-将光线包从用户几何体回调转发到新场景

void rtcForwardOccluded4(
  void int* valid,
  const struct RTCOccludedFunctionNArguments* args,
  RTCScene scene,
  struct RTCRay4* ray,
  unsigned int instID
);
rtcInitPointQueryContext-初始化点查询的上下文信息(例如,(多级)实例转换的堆栈)

rtcPointQuery-使用点查询对象遍历BVH

void rtcPointQuery(
  RTCScene scene,
  struct RTCPointQuery* query,
  struct RTCPointQueryContext* context,
  struct RTCPointQueryFunction* queryFunc,
  void* userPtr
);

         rtcPointQuery函数使用rtcPointQuery对象(查询参数)遍历BVH,并为与查询域相交的场景的每个基元(场景参数)调用用户定义的回调函数(例如queryFunc参数)。
用户必须初始化范围内的查询位置(x、y和z成员)和查询半径
。如果场景包含运动模糊几何图形,则查询时间(时间成员)也必须初始化为范围内的值
.
        此外,必须创建并初始化RTCPointQueryContext(上下文参数)。如果使用(多级)实例化,它包含实例化层次结构的ID和转换信息。有关更多信息,请参见[rtcInitPointQueryContext]。
对于与查询域相交的每个基元,都会调用回调函数(queryFunc参数),在该函数中可以实现到基元的距离计算。用户将被提供相应图元的primID和geomID,然而,几何信息(例如三角形索引和顶点数据)必须手动确定。userPtr参数可用于输入场景的几何体数据或点查询的输出结果(例如,当前在曲面几何体上找到的最近点(请参见教程[ClosstPoint]))。

        参数queryFunc是可选的,可以为NULL,在这种情况下不调用回调函数。但是,回调函数仍然可以使用[rtcSetGeometryPointQueryFunction]附加到特定的RTCGeometry对象。如果回调函数附加到几何体,并且(可能不同的)回调函数作为参数传递给rtcPointQuery,则会为相应几何体的基元调用这两个函数。

        可以在回调函数中减少查询半径,这允许在BVH遍历过程中有效地剔除场景的部分。增加查询半径和修改查询的时间或位置将导致未定义的行为。

        回调函数将为BVH的叶节点中的所有基元调用,即使基元在查询域之外,因为Embree不会在内部收集基元的几何信息。

        点查询可以与(多级)实例化一起使用。但是,当实例转换包含各向异性缩放或剪切时,必须小心。在这些情况下,必须在世界空间中执行距离计算以确保正确性,并且椭球查询域(在实例空间中)将在内部使用其轴对齐的边界框进行近似。因此,即使对于不与查询域相交的内部BVH节点中的基元,也可能调用回调函数。有关详细信息,请参见[rtcSetGeometryPointQueryFunction]。
点查询结构必须与16个字节对齐。

rtcCollide-将一个BVH与另一个相交

         rtcCollide函数将hscene0的BVH与场景hscene1的BVH相交,并为两个场景之间的每对相交基元调用用户定义的回调函数(例如回调参数)。还可以传入用户定义的数据指针(userPtr参数)。

        对于每一对可能相互交叉的基元,都会调用回调函数(回调参数)。将向用户提供多个潜在相交基元对的primID和geomID。目前,只支持完全由用户几何图形组成的场景,因此用户需要实现基元/基元交集,以过滤回调函数中的误报。userPtr参数可用于输入场景的几何数据或输出交叉点查询的结果。

rtcNewBVH-创建一个新的BVH对象

         此函数创建一个新的BVH对象,并返回此BVH的句柄。BVH对象被引用计数,初始引用计数为1。可以使用rtcReleaseBVH API调用释放句柄。

rtcRetainBVH-增加BVH参考计数
rtcBuildBVH - builds a BVH

         rtcBuildBVH函数可用于在任意基元上以用户定义的格式构建BVH。函数的所有参数都是通过RTCBuildArguments结构提供的。该结构的第一个成员必须设置为以字节为单位的结构大小(bytesSize成员),这允许该结构的未来扩展。建议使用rtcDefaultBuildArguments函数初始化生成参数结构。

        rtcBuildBVH函数将传递要构建的BVH(BVH成员)、基元数组(基元成员)、该数组的容量(primitiveArrayCapacity成员)、存储在数组内的基元数(primitive Count成员)、回调函数指针以及用户定义的指针(userPtr成员),该指针在调用时传递给所有回调函数。在构建BVH之后,应用程序可以释放基元数组。所有回调函数通常都是从多个线程调用的,因此它们的实现必须是线程安全的。

        必须注册四个回调函数,它们在构建过程中被调用以创建BVH节点(createNode成员)、设置指向所有子节点的指针(setNodeChildren成员)、设定所有子节点(setNodeBounds成员)的边界框以及创建叶节点(createLeaf成员)。

        指向基元分割函数(splitPrimitive成员)的函数指针可能为NULL,但是,在高质量模式下不可能进行空间分割。用于报告构建进度的函数指针(buildProgress成员)是可选的,也可能为NULL。

        此外,还会传递一些构建设置来配置BVH构建。使用构建质量设置(buildQuality成员),可以在适用于动态场景的更快、低质量构建和适用于静态场景的标准质量构建之间进行选择。还可以指定BVH的期望最大分支因子(maxBranchingFactor成员)、BVH应该具有的最大深度(maxDepth成员)、SAH启发式的块大小(sahBlockSize成员)、最小和最大叶大小(minLeafSize和maxLeafSize成员),以及一个遍历步骤和一个基元交集的估计成本(traversalCost和intersectionCost成员)。当启用RTC_BUILD_FLAG_DYNAMIC构建标志(buildFlags成员)时,动态场景的重新构建性能会以更高的内存需求为代价得到改善。

        要在高质量模式下在空间上拆分基元,构建器需要在构建基元数组的末尾有额外的空间来存储拆分的基元。构建基元数组的总容量是使用primitiveArrayCapacity成员传递的,并且应该是使用空间拆分时基元数量的两倍左右。

        RTCCreateNodeFunc和RTCCreateLeafFunc回调传递一个线程本地分配器对象,该对象应用于使用rtcThreadLocalAlloc函数快速分配节点。我们强烈建议使用这种分配机制,因为像标准malloc这样的替代方法可能会慢10倍以上。传递给创建回调的分配器对象只能在当前线程内部使用。删除RTCBVH对象时,使用rtcThreadLocalAlloc分配的内存将自动释放。如果您使用自己的内存分配方案,则在不再使用RTCBVH对象时,您必须自己释放内存。

        RTCCreateNodeFunc回调还获取该节点的子节点数,其范围从2到maxBranchingFactor(childCount参数)。

        RTCSetNodeChildFunc回调函数获取指向节点的指针作为输入(nodePtr参数)、指向子级的指针数组(childPtrs参数)以及此数组的大小(childCount参数)。

        RTCSetNodeBoundsFunc回调函数获取指向节点的指针作为输入(nodePtr参数)、指向子对象边界框的指针数组(bounds参数)以及此数组的大小(childCount参数)。

        RTCCreateLeafFunc回调还获取一个基元数组作为输入(基元参数),以及该数组的大小(primitiveCount参数)。回调应该从传递的基元中读取geomID和primID成员,以构建叶。
在高质量模式下调用RTCSplitLimitiveFunc回调,以拆分指定位置(位置参数)和维度(维度参数)处的基元(基元参数)。回调应该返回基元的剪裁左部分和右部分的边界(leftBounds和rightBounds参数)。

        调用RTCProgressMonitorFunction回调函数时,估计完成率n在范围内
。从回调返回true可以继续构建;返回false将取消生成。

RTCQuaternationDecomposition-表示仿射变换的四元数分解的结构

struct RTCQuaternionDecomposition
{
  float scale_x, scale_y, scale_z;
  float skew_xy, skew_xz, skew_yz;
  float shift_x, shift_y, shift_z;
  float quaternion_r, quaternion_i, quaternion_j, quaternion_k;
  float translation_x, translation_y, translation_z;
};
RTCQuaternationDecomposition-表示仿射变换的四元数分解的结构

         四元数和仿射变换之间存在一定的关系。在三维空间中,仿射变换可以由一个四元数表示。这个四元数由一个标量部分和三个向量部分组成,其中标量部分表示仿射变换的缩放因子,向量部分表示仿射变换的平移向量。

        具体来说,如果一个点P在仿射变换下的新位置是P',那么这个仿射变换可以用一个四元数Q表示。这个四元数Q可以通过点P和点P'的坐标计算得到。具体计算公式如下:

        Q = (a+bi+cj+dk)[(x+yi+zj+t*k)]

        其中,a、b、c、d是四元数中的标量部分,x、y、z、t是点P的坐标,i、j、k是虚数单位,分别表示向量部分。

        通过这个四元数Q,我们可以方便地计算出点P'的坐标,从而实现仿射变换。因此,四元数在仿射变换中起着重要的表示和计算作用。

rtcInitQuaternionDecomposition-初始化四元数分解

        rtcInitQuaternationDecomposition函数初始化RTCQuaternationdecomposition结构以表示身份转换。 

        首先,使用 rtcInitQuaternionDecomposition 初始化状态,然后使用 RTCQuaternionDecomposition 进行实际的转换。

4、CPU性能建议

MXCSR控制和状态寄存器

        强烈建议在调用rtcIntersect类型和rtcOccluded类型函数之前,为每个线程启用MXCSR控制和状态寄存器的Flush to Zero和Denormals is Zero模式。否则,在某些情况下,对非规范化浮点数的特殊处理会显著降低应用程序和Embree的性能。将Embree与“英特尔®线程构建块”一起使用时,只需在应用程序主线程的开头(在创建tbb::task_scheduler_init对象之前)执行以下代码即可:

#include <xmmintrin.h>
#include <pmmintrin.h>
...
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);

线程创建和相关性设置

        像TBB这样的任务系统会根据需要创建工作线程,这将为第一个rtcCommittScene调用增加运行时开销。如果要对场景构建时间进行基准测试,则应在应用程序启动时启动线程。通过将start_threads=1传递给rtcNewDevice的cfg参数,可以让Embree启动TBB线程。

        在具有高线程数的机器(例如,双套接字Xeon或Xeon Phi机器)上,对TBB工作线程进行亲和处理可以提高构建和渲染性能。通过将set_affinity=1传递给rtcNewDevice的cfg参数,可以让Embree关联TBB工作线程。默认情况下,Embree不关联线程,Xeon Phi处理器除外,默认情况下它们是关联的。

        所有Embree教程都通过将start_threads=1、set_affinity=1传递给rtcNewDevice来自动启动和关联TBB工作线程。

快速相干射线

        为了获得高相干光线(如主阴影光线或硬阴影光线)的最高性能,建议使用数据包,同时在传递给rtcIntersect/rtcOccluded调用的RTCIntersectArguments结构中设置RTC_RAY_QUERY_FLAG_CORENT标志。每个数据包内的射线应尽可能地进行分组。

巨大的页面支持

        建议在Linux下使用巨大的页面来提高渲染性能。Embree在Windows、Linux和macOS下支持2MB的巨大页面。在Linux下,默认启用巨大页面支持,在Windows和macOS下,默认禁用。可以在Embree中通过将hugepages=1传递给rtcNewDevice来启用巨大页面支持,也可以通过将hukepages=0传递给rtc NewDevice来禁用巨大页面支持。

        我们建议在Linux下使用2MB的大页面和Embree,因为这可以将光线跟踪性能提高约5-10%。在Windows下,使用巨大的页面需要应用程序在提升模式下运行,这是一个安全问题,因此在大多数用例中可能不是一个选项。在macOS下,巨大的页面很少可用,因为内存往往会迅速碎片化,因此我们不建议在macOS上使用巨大的页面。

避免单射线的存储到加载转发问题

        我们建议使用单个SSE存储来设置组织和tnear组件,使用单个SSE-存储来设置单个射线的目录和时间组件(RTCRay类型)。使用标量存储存储这些值会导致存储加载转发惩罚,因为Embree稍后将使用SSE加载读取这些组件。

5、GPU性能建议

低代码复杂度

        一般来说,尽量降低代码的复杂度,以避免溢出代码的生成。为了实现这一点,我们建议将渲染器拆分为单独的内核,而不是使用单个Uber内核调用。

        通过使用SYCL专用化常数来启用渲染给定场景所需的渲染功能,代码可以进一步减少。

功能标志

        使用SYCL专用化常量和rtcIntersect1和rtcOccluded1调用的功能标志(请参阅[RTCFeatureFlags]一节)来JIT编译最小代码。传递的功能标志应仅包含渲染当前场景所需的功能。如果JIT编译时间是一个问题,请减少使用的功能掩码的数量并使用JIT缓存(请参阅SYCL JIT缓存一节)。

内联间接调用

        由于性能原因,SYCL不支持将用户几何图形和交集过滤器回调附加到场景的几何图形。

        相反,通过RTCIntersectArguments(和RTCOccludedArguments)结构将用户几何图形和交集过滤器回调函数直接传递给rtcIntersect1(和rtcOccluded1)API函数,如下例所示:

RTC_SYCL_INDIRECTLY_CALLABLE void intersectionFilter(
  const RTCFilterFunctionNArguments* args
) { ... }

RTCIntersectArguments args;
rtcInitIntersectArguments(&args);
args.filter = intersectionFilter;

rtcIntersect1(scene,&ray,&args);

        如果以这种方式直接传递回调函数,SYCL编译器可以内联间接调用,这将带来巨大的性能优势。不要从某个内存位置读取函数指针并将其传递给rtcIntersect1(和rtcOccluded1),因为这也会阻止内联。

7位射线掩模

        如果可能的话,只使用射线和几何体遮罩的低7位,即使Embree支持32位射线遮罩用于几何体遮罩。在CPU上,使用32位中的任何一位都会产生相同的性能,但光线跟踪硬件仅支持8位掩码,因此如果使用,Embree必须模拟32位掩码。

        由于这个原因,较低的7个掩码位是硬件加速和快速的,而掩码位7-31需要一些软件干预,并且使用它们会降低性能。要打开32位光线遮罩,请使用RTC_FEATURE_FLAG_32_bit_ray_MASK(请参阅[RTCFeatureFlags]部分)。

限制运动模糊运动

        SYCL上的运动模糊实现在支持的运动方面有一些限制。基本体运动应最大化为基本体大小的小倍数,否则性能可能会大大降低。如果详细的几何体移动得很快,最好将几何体放入实例中,并将运动模糊应用于实例本身,这样可以有效地进行更大的运动。作为后备方案,有问题的场景仍然可以在CPU上进行稳健渲染。

通用指针

        Embree在其实现中使用标准C++指针。SYCL可能无法检测这些指针所指的内存空间,并且必须将它们视为执行不最佳的通用指针。DPC++编译器具有高级优化,可以推断出正确的地址空间,从而避免使用通用指针。

        但是,如果在SYCL内核的提前编译过程中仍然遇到以下警告,则会出现从通用指针加载的情况:

warning: Adding XX occurrences of additional control flow due to presence
         of generic address space operations in function YYY.

         要解决此问题,我们建议:

        不要在跟踪光线的内核中使用本地内存。在这种情况下,DPC++编译器知道不可能存在本地内存指针,并将优化通用加载。由于渲染器通常是这种情况,一般指针通常不会引起问题。

        即使内核不使用本地内存,可间接调用的函数也可能会导致问题。因此,最好在间接可调用函数中使用SYCL指针,如SYCL::global_ptr<T>{=html}和SYCL::private_ptr<T>{=html},以避免通用地址空间的使用。

        您还可以使用以下DPC++编译标志强制使用全局指针:-cl-intel强制全局内存分配-cl-intel-no-local-to-generic。

6、使用教程

        目前的教程基于glfw,tbb,imgui,这些库实现,主要通过glfw创建窗口和循环,在显示中进行渲染。imgui主要进行文本显示的渲染也在上述过程中,光线追踪的渲染使用tbb进行加速,计算每一个像素的颜色,然后进行显示。

7、其他

        embree::TutorialBenchmark是一个光线追踪基准测试工具,用于评估和优化光线追踪渲染的性能。它提供了一组用于评估渲染性能的基准测试场景,以及用于测量渲染时间、帧率等性能指标的函数。

        embree::TutorialBenchmark的使用通常包括以下步骤:创建embree::TutorialBenchmark对象,并配置所需的测试参数。定义场景描述和渲染参数,包括场景中的几何体、光源、材质等。调用embree::TutorialBenchmark的基准测试函数,例如执行渲染并测量渲染时间。获取基准测试结果,包括平均渲染时间、帧率等性能指标。

  embree::TutorialApplication 类提供了一个简单的框架,用于演示如何使用 Embree 库来创建光线追踪应用程序。它包含了一些基本的渲染功能,如加载场景、设置渲染参数、执行光线追踪渲染等。

        以下是使用 embree::TutorialApplication 进行光线追踪渲染的一般步骤:创建 embree::TutorialApplication 对象。加载场景描述文件,包括几何体、光源、材质等。设置渲染参数,如渲染分辨率、采样数量等。进入渲染循环,执行光线追踪渲染。在渲染过程中,可以通过回调函数处理用户输入、显示渲染结果等。结束应用程序时,释放资源并清理内存。

  • 42
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值