View on GitHub

Embree

High Performance Ray Tracing Kernels

We recently released Embree v3.2.0!

Embree API

The Embree API is a low-level C99 ray tracing API which can be used to construct 3D scenes and perform ray queries of different types inside these scenes. All API calls carry the prefix rtc (or RTC for types) which stands for ray tracing core.

The API also exists in an ISPC version, which is almost identical but contains additional functions that operate on ray packets with a size of the native SIMD width used by ISPC. For simplicity this document refers to the C99 version of the API functions. For changes when upgrading from the Embree 2 to the current Embree 3 API see Section Upgrading from Embree 2 to Embree 3.

The API supports scenes consisting of different geometry types such as triangle meshes, quad meshes (triangle pairs), grid meshes, flat curves, round curves, oriented curves, subdivision meshes, instances, and user-defined geometries. See Section Scene Object for more information.

Finding the closest hit of a ray segment with the scene (rtcIntersect-type functions), and determining whether any hit between a ray segment and the scene exists (rtcOccluded-type functions) are both supported. The API supports queries for single rays, ray packets, and ray streams. See Section Ray Queries for more information.

The API is designed in an object-oriented manner, e.g. it contains device objects (RTCDevice type), scene objects (RTCScene type), geometry objects (RTCGeometry type), buffer objects (RTCBuffer type), and BVH objects (RTCBVH type). All objects are reference counted, and handles can be released by calling the appropriate release function (e.g. rtcReleaseDevice) or retained by incrementing the reference count (e.g. rtcRetainDevice). In general, API calls that access the same object are not thread-safe, unless specified differently. However, attaching geometries to the same scene and performing ray queries in a scene is thread-safe.

Device Object

Embree supports a device concept, which allows different components of the application to use the Embree API without interfering with each other. An application typically first creates a device using the rtcNewDevice function. This device can then be used to construct further objects, such as scenes and geometries. Before the application exits, it should release all devices by invoking rtcReleaseDevice. An application typically creates only a single device. If required differently, it should only use a small number of devices at any given time.

Each user thread has its own error flag per device. If an error occurs when invoking an API function, this flag is set to an error code (if it isn’t already set by a previous error). See Section rtcGetDeviceError for information on how to read the error code and Section rtcSetDeviceErrorFunction on how to register a callback that is invoked for each error encountered. It is recommended to always set a error callback function, to detect all errors.

Scene Object

A scene is a container for a set of geometries, and contains a spatial acceleration structure which can be used to perform different types of ray queries.

A scene is created using the rtcNewScene function call, and released using the rtcReleaseScene function call. To populate a scene with geometries use the rtcAttachGeometry call, and to detach them use the rtcDetachGeometry call. Once all scene geometries are attached, an rtcCommitScene call (or rtcJoinCommitScene call) will finish the scene description and trigger building of internal data structures. After the scene got committed, it is safe to perform ray queries (see Section Ray Queries) or to query the scene bounding box (see rtcGetSceneBounds and rtcGetSceneLinearBounds).

If scene geometries get modified or attached or detached, the rtcCommitScene call must be invoked before performing any further ray queries for the scene; otherwise the effect of the ray query is undefined. The modification of a geometry, committing the scene, and tracing of rays must always happen sequentially, and never at the same time.

Scene flags can be used to configure a scene to use less memory (RTC_SCENE_FLAG_COMPACT), use more robust traversal algorithms (RTC_SCENE_FLAG_ROBUST), and to optimize for dynamic content. See Section rtcSetSceneFlags for more details.

A build quality can be specified for a scene to balance between acceleration structure build performance and ray query performance. See Section rtcSetSceneBuildQuality for more details on build quality.

Geometry Object

A new geometry is created using the rtcNewGeometry function. Depending on the geometry type, different buffers must be bound (e.g. using rtcSetSharedGeometryBuffer) to set up the geometry data. In most cases, binding of a vertex and index buffer is required. The number of primitives and vertices of that geometry is typically inferred from the size of these bound buffers.

Changes to the geometry always must be committed using the rtcCommitGeometry call before using the geometry. After committing, a geometry is not included in any scene. A geometry can be added to a scene by using the rtcAttachGeometry function (to automatically assign a geometry ID) or using the rtcAttachGeometryById function (to specify the geometry ID manually). A geometry can only be attached to a single scene at a time.

All geometry types support multi-segment motion blur with an arbitrary number of equidistant time steps (in the range of 2 to 129). Each geometry can have a different number of time steps. The motion blur geometry is defined by linearly interpolating the geometries of neighboring time steps. To construct a motion blur geometry, first the number of time steps of the geometry must be specified using the rtcSetGeometryTimeStepCount function, and then a vertex buffer for each time step must be bound, e.g. using the rtcSetSharedGeometryBuffer function.

The API supports per-geometry filter callback functions (see rtcSetGeometryIntersectFilterFunction and rtcSetGeometryOccludedFilterFunction) that are invoked for each intersection found during the rtcIntersect-type or rtcOccluded-type calls. The former ones are called geometry intersection filter functions, the latter ones geometry occlusion filter functions. These filter functions are designed to be used to ignore intersections outside of a user-defined silhouette of a primitive, e.g. to model tree leaves using transparency textures.

Ray Queries

The API supports finding the closest hit of a ray segment with the scene (rtcIntersect-type functions), and determining whether any hit between a ray segment and the scene exists (rtcOccluded-type functions).

Supported are single ray queries (rtcIntersect1 and rtcOccluded1) as well as ray packet queries for ray packets of size 4 (rtcIntersect4 and rtcOccluded4), ray packets of size 8 (rtcIntersect8 and rtcOccluded8), and ray packets of size 16 (rtcIntersect16 and rtcOccluded16).

Ray streams in a variety of layouts are supported as well, such as streams of single rays (rtcIntersect1M and rtcOccluded1M), streams of pointers to single rays (rtcIntersect1p and rtcOccluded1p), streams of ray packets (rtcIntersectNM and rtcOccludedNM), and large packet-like streams in structure of pointer layout (rtcIntersectNp and rtcOccludedNp).

See Sections rtcIntersect1 and rtcOccluded1 for a detailed description of how to set up and trace a ray.

See tutorial Triangle Geometry for a complete example of how to trace single rays and ray packets. Also have a look at the tutorial Stream Viewer for an example of how to trace ray streams.

Miscellaneous

A context filter function, which can be set per ray query is supported (see rtcInitIntersectContext). This filter function is designed to change the semantics of the ray query, e.g. to accumulate opacity for transparent shadows, count the number of surfaces along a ray, collect all hits along a ray, etc.

The internal algorithms to build a BVH are exposed through the RTCBVH object and rtcBuildBVH call. This call makes it possible to build a BVH in a user-specified format over user-specified primitives. See the documentation of the rtcBuildBVH call for more details.

For getting the most performance out of Embree, see the Section Performance Recommendations.

Upgrading from Embree 2 to Embree 3

We decided to introduce an improved API in Embree 3 that is not backward compatible with the Embree 2 API. This step was required to remove various deprecated API functions that accumulated over time, improve extensibility of the API, fix suboptimal design decisions, fix design mistakes (such as incompatible single ray and ray packet layouts), clean up inconsistent naming, and increase flexibility.

To make porting to the new API easy, we provide a conversion script that can do most of the work, and will annotate the code with remaining changes required. The script can be invoked the following way for CPP files:

./scripts/cpp-patch.py --patch embree2_to_embree3.patch
  --in infile.cpp --out outfile.cpp

When invoked for ISPC files, add the --ispc option:

./scripts/cpp-patch.py --ispc --patch embree2_to_embree3.patch
  --in infile.ispc --out outfile.ispc

Apply the script to each source file of your project that contains Embree API calls or types. The input file and output file can also be identical to perform the patch in-place. Please always backup your original code before running the script, and inspect the code changes done by the script using diff (e.g. git diff), to make sure no undesired code locations got changed. Grep the code for comments containing EMBREE_FIXME and perform the action described in the comment.

The following changes need to be performed when switching from Embree 2 to Embree 3. Most of these changes are automatically done by the script if not described differently.

We strongly recommend to set an error callback function (see rtcSetDeviceErrorFunction) when porting to Embree 3 to detect all runtime errors early.

Device

Scene

Geometry

Buffers

Miscellaneous

Embree API Reference

rtcNewDevice

NAME

rtcNewDevice - creates a new device

SYNOPSIS

#include <embree3/rtcore.h>

RTCDevice rtcNewDevice(const char* config);

DESCRIPTION

This function creates a new device and returns a handle to this device. The device object is reference counted with an initial reference count of 1. The handle can be released using the rtcReleaseDevice API call.

The device object acts as a class factory for all other object types. All objects created from the device (like scenes, geometries, etc.) hold a reference to the device, thus the device will not be destroyed unless these objects are destroyed first.

Objects are only compatible if they belong to the same device, e.g it is not allowed to create a geometry in one device and attach it to a scene created with a different device.

A configuration string (config argument) can be passed to the device construction. This configuration string can be NULL to use the default configuration.

When creating the device, Embree reads configurations for the device from the following locations in order:

  1. config string passed to the rtcNewDevice function
  2. .embree3 file in the application folder
  3. .embree3 file in the home folder

Settings performed later overwrite previous settings. This way the configuration for the application can be changed globally (either through the rtcNewDevice call or through the .embree3 file in the application folder), and each user has the option to modify the configuration to fit their needs.

The following configuration is supported:

Different configuration options should be separated by commas, e.g.:

rtcNewDevice("threads=1,isa=avx");

EXIT STATUS

On success returns a handle of the created device. On failure returns NULL as device and sets a per-thread error code that can be queried using rtcDeviceGetError(NULL).

SEE ALSO

rtcRetainDevice, rtcReleaseDevice

rtcRetainDevice

NAME

rtcRetainDevice - increments the device reference count

SYNOPSIS

#include <embree3/rtcore.h>

void rtcRetainDevice(RTCDevice device);

DESCRIPTION

Device objects are reference counted. The rtcRetainDevice function increments the reference count of the passed device object (device argument). This function together with rtcReleaseDevice allows to use the internal reference counting in a C++ wrapper class to manage the ownership of the object.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewDevice, rtcReleaseDevice

rtcReleaseDevice

NAME

rtcReleaseDevice - decrements the device reference count

SYNOPSIS

#include <embree3/rtcore.h>

void rtcReleaseDevice(RTCDevice device);

DESCRIPTION

Device objects are reference counted. The rtcReleaseDevice function decrements the reference count of the passed device object (device argument). When the reference count falls to 0, the device gets destroyed.

All objects created from the device (like scenes, geometries, etc.) hold a reference to the device, thus the device will not get destroyed unless these objects are destroyed first.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewDevice, rtcRetainDevice

rtcGetDeviceProperty

NAME

rtcGetDeviceProperty - queries properties of the device

SYNOPSIS

#include <embree3/rtcore.h>

ssize_t rtcGetDeviceProperty(
  RTCDevice device,
  RTCDeviceProperty prop
);

DESCRIPTION

The rtcGetDeviceProperty function can be used to query properties (prop argument) of a device object (device argument). The returned property is an integer of type ssize_t.

Possible properties to query are:

EXIT STATUS

On success returns the value of the queried property. For properties returning a boolean value, the return value 0 denotes false and 1 denotes true.

On failure zero is returned and an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

[rtcSetDeviceProperty]

rtcGetDeviceError

NAME

rtcGetDeviceError - returns the error code of the device

SYNOPSIS

#include <embree3/rtcore.h>

RTCError rtcGetDeviceError(RTCDevice device);

DESCRIPTION

Each thread has its own error code per device. If an error occurs when calling an API function, this error code is set to the occurred error if it stores no previous error. The rtcGetDeviceError function reads and returns the currently stored error and clears the error code. This assures that the returned error code is always the first error occurred since the last invocation of rtcGetDeviceError.

Possible error codes returned by rtcGetDeviceError are:

When the device construction fails, rtcNewDevice returns NULL as device. To detect the error code of a such a failed device construction, pass NULL as device to the rtcGetDeviceError function. For all other invocations of rtcGetDeviceError, a proper device pointer must be specified.

EXIT STATUS

Returns the error code for the device.

SEE ALSO

rtcSetDeviceErrorFunction

rtcSetDeviceErrorFunction

NAME

rtcSetDeviceErrorFunction - sets an error callback function for the device

SYNOPSIS

#include <embree3/rtcore.h>

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

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

DESCRIPTION

Using the rtcSetDeviceErrorFunction call, it is possible to set a callback function (error argument) with payload (userPtr argument), which is called whenever an error occurs for the specified device (device argument).

Only a single callback function can be registered per device, and further invocations overwrite the previously set callback function. Passing NULL as function pointer disables the registered callback function.

When the registered callback function is invoked, it gets passed the user-defined payload (userPtr argument as specified at registration time), the error code (code argument) of the occurred error, as well as a string (str argument) that further describes the error.

The error code is also set if an error callback function is registered.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcGetDeviceError

rtcSetDeviceMemoryMonitorFunction

NAME

rtcSetDeviceMemoryMonitorFunction - registers a callback function
  to track memory consumption

SYNOPSIS

#include <embree3/rtcore.h>

typedef bool (*RTCMemoryMonitorFunction)(
  void* userPtr,
  ssize_t bytes,
  bool post
);

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

DESCRIPTION

Using the rtcSetDeviceMemoryMonitorFunction call, it is possible to register a callback function (memoryMonitor argument) with payload (userPtr argument) for a device (device argument), which is called whenever internal memory is allocated or deallocated by objects of that device. Using this memory monitor callback mechanism, the application can track the memory consumption of an Embree device, and optionally terminate API calls that consume too much memory.

Only a single callback function can be registered per device, and further invocations overwrite the previously set callback function. Passing NULL as function pointer disables the registered callback function.

Once registered, the Embree device will invoke the memory monitor callback function before or after it allocates or frees important memory blocks. The callback function gets passed the payload as specified at registration time (userPtr argument), the number of bytes allocated or deallocated (bytes argument), and whether the callback is invoked after the allocation or deallocation took place (post argument). The callback function might get called from multiple threads concurrently.

The application can track the current memory usage of the Embree device by atomically accumulating the bytes input parameter provided to the callback function. This parameter will be >0 for allocations and <0 for deallocations.

Embree will continue its operation normally when returning true from the callback function. If false is returned, Embree will cancel the current operation with the RTC_ERROR_OUT_OF_MEMORY error code. Issuing multiple cancel requests from different threads is allowed. Canceling will only happen when the callback was called for allocations (bytes > 0), otherwise the cancel request will be ignored.

If a callback to cancel was invoked before the allocation happens (post == false), then the bytes parameter should not be accumulated, as the allocation will never happen. If the callback to cancel was invoked after the allocation happened (post == true), then the bytes parameter should be accumulated, as the allocation properly happened and a deallocation will later free that data block.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewDevice

rtcNewScene

NAME

rtcNewScene - creates a new scene

SYNOPSIS

#include <embree3/rtcore.h>

RTCScene rtcNewScene(RTCDevice device);

DESCRIPTION

This function creates a new scene bound to the specified device (device argument), and returns a handle to this scene. The scene object is reference counted with an initial reference count of 1. The scene handle can be released using the rtcReleaseScene API call.

EXIT STATUS

On success a scene handle is returned. On failure NULL is returned and an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcRetainScene, rtcReleaseScene

rtcRetainScene

NAME

rtcRetainScene - increments the scene reference count

SYNOPSIS

#include <embree3/rtcore.h>

void rtcRetainScene(RTCScene scene);

DESCRIPTION

Scene objects are reference counted. The rtcRetainScene function increments the reference count of the passed scene object (scene argument). This function together with rtcReleaseScene allows to use the internal reference counting in a C++ wrapper class to handle the ownership of the object.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewScene, rtcReleaseScene

rtcReleaseScene

NAME

rtcReleaseScene - decrements the scene reference count

SYNOPSIS

#include <embree3/rtcore.h>

void rtcReleaseScene(RTCScene scene);

DESCRIPTION

Scene objects are reference counted. The rtcReleaseScene function decrements the reference count of the passed scene object (scene argument). When the reference count falls to 0, the scene gets destroyed.

The scene holds a reference to all attached geometries, thus if the scene gets destroyed, all geometries get detached and their reference count decremented.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewScene, rtcRetainScene

rtcAttachGeometry

NAME

rtcAttachGeometry - attaches a geometry to the scene

SYNOPSIS

#include <embree3/rtcore.h>

unsigned int rtcAttachGeometry(
  RTCScene scene,
  RTCGeometry geometry
);

DESCRIPTION

The rtcAttachGeometry function attaches a geometry (geometry argument) to a scene (scene argument) and assigns a geometry ID to that geometry. All geometries attached to a scene are defined to be included inside the scene. A geometry can only get attached to a single scene at a given time. However, it is possible to detach and re-attach a geometry to a different scene. The geometry ID is unique for the scene, and is used to identify the geometry when hit by a ray during ray queries.

This function is thread-safe, thus multiple threads can attach geometries to a scene in parallel.

The geometry IDs are assigned sequentially, starting from 0, as long as no geometry got detached. If geometries got detached, the implementation will reuse IDs in an implementation dependent way. Consequently sequential assignment is no longer guaranteed, but a compact range of IDs.

These rules allow the application to manage a dynamic array to efficiently map from geometry IDs to its own geometry representation. Alternatively, the application can also use per-geometry user data to map to its geometry representation. See rtcSetGeometryUserData and rtcGetGeometryUserData for more information.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcSetGeometryUserData, rtcGetGeometryUserData

rtcAttachGeometryByID

NAME

rtcAttachGeometryByID - attaches a geometry to the scene
  using a specified geometry ID

SYNOPSIS

#include <embree3/rtcore.h>

void rtcAttachGeometryByID(
  RTCScene scene,
  RTCGeometry geometry,
  unsigned int geomID
);

DESCRIPTION

The rtcAttachGeometryByID function attaches a geometry (geometry argument) to a scene (scene argument) and assigns a user provided geometry ID (geomID argument) to that geometry. All geometries attached to a scene are defined to be included inside the scene. A geometry can only get attached to a single scene at a given time. However, it is possible to detach and re-attach a geometry to a different scene. The passed user-defined geometry ID is used to identify the geometry when hit by a ray during ray queries. Using this function, it is possible to share the same IDs to refer to geometries inside the application and Embree.

This function is thread-safe, thus multiple threads can attach geometries to a scene in parallel.

The user-provided geometry ID must be unused in the scene, otherwise the creation of the geometry will fail. Further, the user-provided geometry IDs should be compact, as Embree internally creates a vector which size is equal to the largest geometry ID used. Creating very large geometry IDs for small scenes would thus cause a memory consumption and performance overhead.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcAttachGeometry

rtcDetachGeometry

NAME

rtcDetachGeometry - detaches a geometry from the scene

SYNOPSIS

#include <embree3/rtcore.h>

void rtcDetachGeometry(RTCScene scene, unsigned int geomID);

DESCRIPTION

This function detaches a geometry identified by its geometry ID (geomID argument) from a scene (scene argument). When detached, the geometry is no longer contained in the scene.

This function is thread-safe, thus multiple threads can detach geometries from a scene at the same time.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcAttachGeometry, rtcAttachGeometryByID

rtcGetGeometry

NAME

rtcGetGeometry - returns the geometry bound to
  the specified geometry ID

SYNOPSIS

#include <embree3/rtcore.h>

RTCGeometry rtcGetGeometry(RTCScene scene, unsigned int geomID);

DESCRIPTION

The rtcGetGeometry function returns the geometry that is bound to the specified geometry ID (geomID argument) for the specified scene (scene argument). This function just looks up the handle and does not increment the reference count. If you want to get ownership of the handle, you need to additionally call rtcRetainGeometry. For this reason, this function is fast and can be used during rendering. However, it is generally recommended to store the geometry handle inside the application’s geometry representation and look up the geometry handle from that representation directly.

EXIT STATUS

On failure NULL is returned and an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcAttachGeometry, rtcAttachGeometryByID

rtcCommitScene

NAME

rtcCommitScene - commits scene changes

SYNOPSIS

#include <embree3/rtcore.h>

void rtcCommitScene(RTCScene scene);

DESCRIPTION

The rtcCommitScene function commits all changes for the specified scene (scene argument). This internally triggers building of a spatial acceleration structure for the scene using all available worker threads. Ray queries can be performed only after committing all scene changes.

The kind of acceleration structure built can be influenced using scene flags (see rtcSetSceneFlags), and the quality can be specified using the rtcSetSceneBuildQuality function.

Embree silently ignores primitives during spatial acceleration structure construction that would cause numerical issues, e.g. primitives containing NaNs, INFs, or values greater than 1.844E18f (as no reasonable calculations can be performed with such values without causing overflows).

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

[rtcCommitJoinScene]

rtcJoinCommitScene

NAME

rtcJoinCommitScene - commits the scene from multiple threads

SYNOPSIS

#include <embree3/rtcore.h>

void rtcJoinCommitScene(RTCScene scene);

DESCRIPTION

The rtcJoinCommitScene function commits all changes for the specified scene (scene argument). In contrast to the rtcCommitScene function, the rtcJoinCommitScene function can be called from multiple threads, which all cooperate in the same scene commit. All threads will return from this function after the scene commit is finished. All threads must consistently call rtcJoinCommitScene and not rtcCommitScene.

The scene commit internally triggers building of a spatial acceleration structure for the scene. Ray queries can be performed after scene changes got properly committed.

The rtcJoinCommitScene feature allows a flexible way to lazily create hierarchies during rendering. A thread reaching a not-yet-constructed sub-scene of a two-level scene can generate the sub-scene geometry and call rtcJoinCommitScene on that just generated scene. During construction, further threads reaching the not-yet-built scene can join the build operation by also invoking rtcJoinCommitScene. A thread that calls rtcJoinCommitScene after the build finishes will directly return from the rtcJoinCommitScene call.

Multiple scene commit operations on different scenes can be running at the same time, hence it is possible to commit many small scenes in parallel, distributing the commits to many threads.

When using Embree with the Intel® Threading Building Blocks (which is the default), threads that call rtcJoinCommitScene will join the build operation, but other TBB worker threads might also participate in the build. To avoid thread oversubscription, we recommend using TBB also inside the application. Further, the join mode only works properly starting with TBB v4.4 Update 1. For earlier TBB versions, threads that call rtcJoinCommitScene to join a running build will just trigger the build and wait for the build to finish. Further, old TBB versions with TBB_INTERFACE_VERSION_MAJOR < 8 do not support rtcJoinCommitScene, and invoking this function will result in an error.

When using Embree with the internal tasking system, only threads that call rtcJoinCommitScene will perform the build operation, and no additional worker threads will be scheduled.

When using Embree with the Parallel Patterns Library (PPL), rtcJoinCommitScene is not supported and calling that function will result in an error.

To detect whether rtcJoinCommitScene is supported, use the rtcGetDeviceProperty function.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcCommitScene, rtcGetDeviceProperty

rtcSetSceneProgressMonitorFunction

NAME

rtcSetSceneProgressMonitorFunction - registers a callback
  to track build progress

SYNOPSIS

#include <embree3/rtcore.h>

typedef bool (*RTCProgressMonitorFunction)(
  void* ptr,
  double n
);

void rtcSetSceneProgressMonitorFunction(
  RTCScene scene,
  RTCProgressMonitorFunction progress,
  void* userPtr
);

DESCRIPTION

Embree supports a progress monitor callback mechanism that can be used to report progress of hierarchy build operations and to cancel build operations.

The rtcSetSceneProgressMonitorFunction registers a progress monitor callback function (progress argument) with payload (userPtr argument) for the specified scene (scene argument).

Only a single callback function can be registered per scene, and further invocations overwrite the previously set callback function. Passing NULL as function pointer disables the registered callback function.

Once registered, Embree will invoke the callback function multiple times during hierarchy build operations of the scene, by passing the payload as set at registration time (userPtr argument), and a double in the range [0, 1] which estimates the progress of the operation (n argument). The callback function might be called from multiple threads concurrently.

When returning true from the callback function, Embree will continue the build operation normally. When returning false, Embree will cancel the build operation with the RTC_ERROR_CANCELLED error code. Issuing multiple cancel requests for the same build operation is allowed.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewScene

rtcSetSceneBuildQuality

NAME

rtcSetSceneBuildQuality - sets the build quality for
  the scene

SYNOPSIS

#include <embree3/rtcore.h>

void rtcSetSceneBuildQuality(
  RTCScene scene,
  enum RTCBuildQuality quality
);

DESCRIPTION

The rtcSetSceneBuildQuality function sets the build quality (quality argument) for the specified scene (scene argument). Possible values for the build quality are:

Selecting a higher build quality results in better rendering performance but slower scene commit times. The default build quality for a scene is RTC_BUILD_QUALITY_MEDIUM.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

[rtcGetSceneBuildQuality], rtcSetGeometryBuildQuality

rtcSetSceneFlags

NAME

rtcSetSceneFlags - sets the flags for the scene

SYNOPSIS

#include <embree3/rtcore.h>

void rtcSetSceneFlags(RTCScene scene, enum RTCSceneFlags flags);

DESCRIPTION

The rtcSetSceneFlags function sets the scene flags (flags argument) for the specified scene (scene argument). Possible scene flags are:

Multiple flags can be enabled using an or operation, e.g. RTC_SCENE_FLAG_COMPACT | RTC_SCENE_FLAG_ROBUST.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcGetSceneFlags

rtcGetSceneFlags

NAME

rtcGetSceneFlags - returns the flags of the scene

SYNOPSIS

#include <embree3/rtcore.h>

enum RTCSceneFlags rtcGetSceneFlags(RTCScene scene);

DESCRIPTION

Queries the flags of a scene. This function can be useful when setting individual flags, e.g. to just set the robust mode without changing other flags the following way:

RTCSceneFlags flags = rtcGetSceneFlags(scene);
rtcSetSceneFlags(scene, RTC_SCENE_FLAG_ROBUST | flags);

EXIT STATUS

On failure RTC_SCENE_FLAG_NONE is returned and an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcSetSceneFlags

rtcGetSceneBounds

NAME

rtcGetSceneBounds - returns the axis-aligned bounding box of the scene

SYNOPSIS

#include <embree3/rtcore.h>

struct RTCORE_ALIGN(16) RTCBounds
{
  float lower_x, lower_y, lower_z, align0;
  float upper_x, upper_y, upper_z, align1;
};

void rtcGetSceneBounds(
  RTCScene scene,
  struct RTCBounds* bounds_o
);

DESCRIPTION

The rtcGetSceneBounds function queries the axis-aligned bounding box of the specified scene (scene argument) and stores that bounding box to the provided destination pointer (bounds_o argument). The stored bounding box consists of lower and upper bounds for the x, y, and z dimensions as specified by the RTCBounds structure.

The provided destination pointer must be aligned to 16 bytes. The function may be invoked only after committing the scene; otherwise the result is undefined.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcGetSceneLinearBounds, rtcCommitScene, rtcJoinCommitScene

rtcGetSceneLinearBounds

NAME

rtcGetSceneLinearBounds - returns the linear bounds of the scene

SYNOPSIS

#include <embree3/rtcore.h>

struct RTCORE_ALIGN(16) RTCLinearBounds
{
  RTCBounds bounds0;
  RTCBounds bounds1;
};

void rtcGetSceneLinearBounds(
  RTCScene scene,
  struct RTCLinearBounds* bounds_o
);

DESCRIPTION

The rtcGetSceneLinearBounds function queries the linear bounds of the specified scene (scene argument) and stores them to the provided destination pointer (bounds_o argument). The stored linear bounds consist of bounding boxes for time 0 (bounds0 member) and time 1 (bounds1 member) as specified by the RTCLinearBounds structure. Linearly interpolating these bounds to a specific time t yields bounds for the geometry at that time.

The provided destination pointer must be aligned to 16 bytes. The function may be called only after committing the scene, otherwise the result is undefined.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcGetSceneBounds, rtcCommitScene, rtcJoinCommitScene

rtcNewGeometry

NAME

rtcNewGeometry - creates a new geometry object

SYNOPSIS

#include <embree3/rtcore.h>

enum RTCGeometryType
{
 RTC_GEOMETRY_TYPE_TRIANGLE,
 RTC_GEOMETRY_TYPE_QUAD,
 RTC_GEOMETRY_TYPE_SUBDIVISION,
 RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE,
 RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE,
 RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE,
 RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE,
 RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE,
 RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE,
 RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_CURVE,
 RTC_GEOMETRY_TYPE_GRID,
 RTC_GEOMETRY_TYPE_USER,
 RTC_GEOMETRY_TYPE_INSTANCE
};

RTCGeometry rtcNewGeometry(
  RTCDevice device,
  enum RTCGeometryType type
);

DESCRIPTION

Geometries are objects that represent an array of primitives of the same type. The rtcNewGeometry function creates a new geometry of specified type (type argument) bound to the specified device (device argument) and returns a handle to this geometry. The geometry object is reference counted with an initial reference count of 1. The geometry handle can be released using the rtcReleaseGeometry API call.

Supported geometry types are triangle meshes (RTC_GEOMETRY_TYPE_TRIANGLE type), quad meshes (triangle pairs) (RTC_GEOMETRY_TYPE_QUAD type), Catmull-Clark subdivision surfaces (RTC_GEOMETRY_TYPE_SUBDIVISION type), curve geometries with different bases (RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE, RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE, RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE, RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE, RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE, RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE, RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_CURVE types), grid meshes (RTC_GEOMETRY_TYPE_GRID), user-defined geometries (RTC_GEOMETRY_TYPE_USER), and instances (RTC_GEOMETRY_TYPE_INSTANCE).

The types RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE and RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE will treat the curve as a sweep surface of a varying-radius circle swept tangentially along the curve. The types RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE and RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE use ray-facing ribbons as a faster-to-intersect approximation.

After construction, geometries are enabled by default and not attached to any scene. Geometries can be disabled (rtcDisableGeometry call), and enabled again (rtcEnableGeometry call). A geometry can be attached to a single scene using the rtcAttachGeometry call (or rtcAttachGeometryByID call), and detached using the rtcDetachGeometry call. During attachment, a geometry ID is assigned to the geometry (or assigned by the user when using the rtcAttachGeometryByID call), which uniquely identifies the geometry inside that scene. This identifier is returned when primitives of the geometry are hit in later ray queries for the scene.

Geometries can also be modified, including their vertex and index buffers. After modifying a buffer, rtcUpdateGeometryBuffer must be called to notify that the buffer got modified.

The application can use the rtcSetGeometryUserData function to set a user data pointer to its own geometry representation, and later read out this pointer using the rtcGetGeometryUserData function.

After setting up the geometry or modifying it, rtcCommitGeometry must be called to finish the geometry setup. After committing the geometry, vertex data interpolation can be performed using the rtcInterpolate and rtcInterpolateN functions.

A build quality can be specified for a geometry using the rtcSetGeometryBuildQuality function, to balance between acceleration structure build performance and ray query performance. The build quality per geometry will be used if a two-level acceleration structure is built internally, which is the case if the RTC_BUILD_QUALITY_LOW is set as the scene build quality. See Section rtcSetSceneBuildQuality for more details.

EXIT STATUS

On failure NULL is returned and an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcEnableGeometry, rtcDisableGeometry, rtcAttachGeometry, rtcAttachGeometryByID, rtcUpdateGeometryBuffer, rtcSetGeometryUserData, rtcGetGeometryUserData, rtcCommitGeometry, rtcInterpolate, rtcInterpolateN, rtcSetGeometryBuildQuality, rtcSetSceneBuildQuality, RTC_GEOMETRY_TYPE_TRIANGLE, RTC_GEOMETRY_TYPE_QUAD, RTC_GEOMETRY_TYPE_SUBDIVISION, RTC_GEOMETRY_TYPE_CURVE, RTC_GEOMETRY_TYPE_GRID, RTC_GEOMETRY_TYPE_USER, RTC_GEOMETRY_TYPE_INSTANCE

RTC_GEOMETRY_TYPE_TRIANGLE

NAME

RTC_GEOMETRY_TYPE_TRIANGLE - triangle geometry type

SYNOPSIS

#include <embree3/rtcore.h>

RTCGeometry geometry =
  rtcNewGeometry(device, RTC_GEOMETRY_TYPE_TRIANGLE);

DESCRIPTION

Triangle meshes are created by passing RTC_GEOMETRY_TYPE_TRIANGLE to the rtcNewGeometry function call. The triangle indices can be specified by setting an index buffer (RTC_BUFFER_TYPE_INDEX type) and the triangle vertices by setting a vertex buffer (RTC_BUFFER_TYPE_VERTEX type). See rtcSetGeometryBuffer and rtcSetSharedGeometryBuffer for more details on how to set buffers. The index buffer contains an array of three 32-bit indices per triangle (RTC_FORMAT_UINT format) and the number of primitives is inferred from the size of that buffer. The vertex buffer contains an array of single precision x, y, z floating point coordinates (RTC_FORMAT_FLOAT3 format), and the number of vertices are inferred from the size of that buffer. The vertex buffer can be at most 16 GB large.

The parametrization of a triangle uses the first vertex p0 as base point, the vector p1 - p0 as u-direction and the vector p2 - p0 as v-direction. Thus vertex attributes t0,t1,t2 can be linearly interpolated over the triangle the following way:

t_uv = (1-u-v)*t0 + u*t1 + v*t2
     = t0 + u*(t1-t0) + v*(t2-t0)

A triangle whose vertices are laid out counter-clockwise has its geometry normal pointing upwards outside the front face, like illustrated in the following picture:

[][imgTriangleUV]

For multi-segment motion blur, the number of time steps must be first specified using the rtcSetGeometryTimeStepCount call. Then a vertex buffer for each time step can be set using different buffer slots, and all these buffers have to have the same stride and size.

Also see tutorial [Triangle Geometry] for an example of how to create triangle meshes.

EXIT STATUS

On failure NULL is returned and an error code is set that be get queried using rtcDeviceGetError.

SEE ALSO

rtcNewGeometry

RTC_GEOMETRY_TYPE_QUAD

NAME

RTC_GEOMETRY_TYPE_QUAD - quad geometry type

SYNOPSIS

#include <embree3/rtcore.h>

RTCGeometry geometry =
  rtcNewGeometry(device, RTC_GEOMETRY_TYPE_QUAD);

DESCRIPTION

Quad meshes are created by passing RTC_GEOMETRY_TYPE_QUAD to the rtcNewGeometry function call. The quad indices can be specified by setting an index buffer (RTC_BUFFER_TYPE_INDEX type) and the quad vertices by setting a vertex buffer (RTC_BUFFER_TYPE_VERTEX type). See rtcSetGeometryBuffer and rtcSetSharedGeometryBuffer for more details on how to set buffers. The index buffer contains an array of four 32-bit indices per quad (RTC_FORMAT_UINT format), and the number of primitives is inferred from the size of that buffer. The vertex buffer contains an array of single precision x, y, z floating point coordinates (RTC_FORMAT_FLOAT3 format), and the number of vertices is inferred from the size of that buffer. The vertex buffer can be at most 16 GB large.

A quad is internally handled as a pair of two triangles v0,v1,v3 and v2,v3,v1, with the u'/v' coordinates of the second triangle corrected by u = 1-u' and v = 1-v' to produce a quad parametrization where u and v are in the range 0 to 1. Thus the parametrization of a quad uses the first vertex p0 as base point, and the vector p1 - p0 as u-direction, and p3 - p0 as v-direction. Thus vertex attributes t0,t1,t2,t3 can be bilinearly interpolated over the quadrilateral the following way:

t_uv = (1-v)((1-u)*t0 + u*t1) + v*((1-u)*t3 + u*t2)

Mixed triangle/quad meshes are supported by encoding a triangle as a quad, which can be achieved by replicating the last triangle vertex (v0,v1,v2 -> v0,v1,v2,v2). This way the second triangle is a line (which can never get hit), and the parametrization of the first triangle is compatible with the standard triangle parametrization.

A quad whose vertices are laid out counter-clockwise has its geometry normal pointing upwards outside the front face, like illustrated in the following picture.

[][imgQuadUV]

For multi-segment motion blur, the number of time steps must be first specified using the rtcSetGeometryTimeStepCount call. Then a vertex buffer for each time step can be set using different buffer slots, and all these buffers must have the same stride and size.

EXIT STATUS

On failure NULL is returned and an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewGeometry

RTC_GEOMETRY_TYPE_GRID

NAME

RTC_GEOMETRY_TYPE_GRID - grid geometry type

SYNOPSIS

#include <embree3/rtcore.h>

RTCGeometry geometry =
  rtcNewGeometry(device, RTC_GEOMETRY_TYPE_GRID);

DESCRIPTION

Grid meshes are created by passing RTC_GEOMETRY_TYPE_GRID to the rtcNewGeometry function call, and contain an array of grid primitives. This array of grids can be specified by setting up a grid buffer (with RTC_BUFFER_TYPE_GRID type and RTC_FORMAT_GRID format) and the grid mesh vertices by setting a vertex buffer (RTC_BUFFER_TYPE_VERTEX type). See rtcSetGeometryBuffer and rtcSetSharedGeometryBuffer for more details on how to set buffers. The number of grid primitives in the grid mesh is inferred from the size of the grid buffer.

The vertex buffer contains an array of single precision x, y, z floating point coordinates (RTC_FORMAT_FLOAT3 format), and the number of vertices is inferred from the size of that buffer.

Each grid in the grid buffer is of the type RTCGrid:

struct RTCGrid
{
  unsigned int startVertexID;
  unsigned int stride;
  unsigned short width,height; 
};

The RTCGrid structure describes a 2D grid of vertices (with respect to the vertex buffer of the grid mesh). The width and height members specify the number of vertices in u and v direction, e.g. setting both width and height to 3 sets up a 3x3 vertex grid. The maximum allowed width and height is 32767. The startVertexID specifies the ID of the top-left vertex in the vertex grid, while the stride parameter specifies a stride (in number of vertices) used to step to the next row.

A vertex grid of dimensions width and height is treated as a (width-1) x (height-1) grid of quads (triangle-pairs), with the same shared edge handling as for regular quad meshes. However, the u/v coordinates have the uniform range [0..1] for an entire vertex grid. The u direction follows the width of the grid while the v direction the height.

For multi-segment motion blur, the number of time steps must be first specified using the rtcSetGeometryTimeStepCount call. Then a vertex buffer for each time step can be set using different buffer slots, and all these buffers must have the same stride and size.

EXIT STATUS

On failure NULL is returned and an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewGeometry

RTC_GEOMETRY_TYPE_SUBDIVISION

NAME

RTC_GEOMETRY_TYPE_SUBDIVISION - subdivision geometry type

SYNOPSIS

#include <embree3/rtcore.h>

RTCGeometry geometry =
  rtcNewGeometry(device, RTC_GEOMETRY_TYPE_SUBDIVISION);

DESCRIPTION

Catmull-Clark subdivision meshes are supported, including support for edge creases, vertex creases, holes, non-manifold geometry, and face-varying interpolation. The number of vertices per face can be in the range of 3 to 15 vertices (triangles, quadrilateral, pentagons, etc).

Subdivision meshes are created by passing RTC_GEOMETRY_TYPE_SUBDIVISION to the rtcNewGeometry function. Various buffers need to be set by the application to set up the subdivision mesh. See rtcSetGeometryBuffer and rtcSetSharedGeometryBuffer for more details on how to set buffers. The face buffer (RTC_BUFFER_TYPE_FACE type and RTC_FORMAT_UINT format) contains the number of edges/indices of each face (3 to 15), and the number of faces is inferred from the size of this buffer. The index buffer (RTC_BUFFER_TYPE_INDEX type) contains multiple (3 to 15) 32-bit vertex indices (RTC_FORMAT_UINT format) for each face, and the number of edges is inferred from the size of this buffer. The vertex buffer (RTC_BUFFER_TYPE_VERTEX type) stores an array of single precision x, y, z floating point coordinates (RTC_FORMAT_FLOAT3 format), and the number of vertices is inferred from the size of this buffer.

Optionally, the application may set additional index buffers using different buffer slots if multiple topologies are required for face-varying interpolation. The standard vertex buffers (RTC_BUFFER_TYPE_VERTEX) are always bound to the geometry topology (topology 0) thus use RTC_BUFFER_TYPE_INDEX with buffer slot 0. User vertex data interpolation may use different topologies as described later.

Optionally, the application can set up the hole buffer (RTC_BUFFER_TYPE_HOLE) which contains an array of 32-bit indices (RTC_FORMAT_UINT format) of faces that should be considered non-existing in all topologies. The number of holes is inferred from the size of this buffer.

Optionally, the application can fill the level buffer (RTC_BUFFER_TYPE_LEVEL) with a tessellation rate for each of the edges of each face. This buffer must have the same size as the index buffer. The tessellation level is a positive floating point value (RTC_FORMAT_FLOAT format) that specifies how many quads along the edge should be generated during tessellation. If no level buffer is specified, a level of 1 is used. The maximally supported edge level is 4096, and larger levels are clamped to that value. Note that edges may be shared between (typically 2) faces. To guarantee a watertight tessellation, the level of these shared edges should be identical. A uniform tessellation rate for an entire subdivision mesh can be set by using the rtcSetGeometryTessellationRate function. The existence of a level buffer has precedence over the uniform tessellation rate.

Optionally, the application can fill the sparse edge crease buffers to make edges appear sharper. The edge crease index buffer (RTC_BUFFER_TYPE_EDGE_CREASE_INDEX) contains an array of pairs of 32-bit vertex indices (RTC_FORMAT_UINT2 format) that specify unoriented edges in the geometry topology. The edge crease weight buffer (RTC_BUFFER_TYPE_EDGE_CREASE_WEIGHT) stores for each of these crease edges a positive floating point weight (RTC_FORMAT_FLOAT format). The number of edge creases is inferred from the size of these buffers, which has to be identical. The larger a weight, the sharper the edge. Specifying a weight of infinity is supported and marks an edge as infinitely sharp. Storing an edge multiple times with the same crease weight is allowed, but has lower performance. Storing an edge multiple times with different crease weights results in undefined behavior. For a stored edge (i,j), the reverse direction edges (j,i) do not have to be stored, as both are considered the same unoriented edge. Edge crease features are shared between all topologies.

Optionally, the application can fill the sparse vertex crease buffers to make vertices appear sharper. The vertex crease index buffer (RTC_BUFFER_TYPE_VERTEX_CREASE_INDEX), contains an array of 32-bit vertex indices (RTC_FORMAT_UINT format) to specify a set of vertices from the geometry topology. The vertex crease weight buffer (RTC_BUFFER_TYPE_VERTEX_CREASE_WEIGHT) specifies for each of these vertices a positive floating point weight (RTC_FORMAT_FLOAT format). The number of vertex creases is inferred from the size of these buffers, and has to be identical. The larger a weight, the sharper the vertex. Specifying a weight of infinity is supported and makes the vertex infinitely sharp. Storing a vertex multiple times with the same crease weight is allowed, but has lower performance. Storing a vertex multiple times with different crease weights results in undefined behavior. Vertex crease features are shared between all topologies.

Subdivision modes can be used to force linear interpolation for parts of the subdivision mesh; see rtcSetGeometrySubdivisionMode for more details.

For multi-segment motion blur, the number of time steps must be first specified using the rtcSetGeometryTimeStepCount call. Then a vertex buffer for each time step can be set using different buffer slots, and all these buffers have to have the same stride and size.

Also see tutorial [Subdivision Geometry] for an example of how to create subdivision surfaces.

Parametrization

The parametrization for subdivision faces is different for quadrilaterals and non-quadrilateral faces.

The parametrization of a quadrilateral face uses the first vertex p0 as base point, and the vector p1 - p0 as u-direction and p3 - p0 as v-direction.

The parametrization for all other face types (with number of vertices not equal 4), have a special parametrization where the subpatch ID n (of the n-th quadrilateral that would be obtained by a single subdivision step) and the local hit location inside this quadrilateral are encoded in the UV coordinates. The following code extracts the sub-patch ID i and local UVs of this subpatch:

unsigned int l = floorf(0.5f*U);
unsigned int h = floorf(0.5f*V);
unsigned int i = 4*h+l;
float u = 2.0f*fracf(0.5f*U)-0.5f;
float v = 2.0f*fracf(0.5f*V)-0.5f;

This encoding allows local subpatch UVs to be in the range [-0.5,1.5[ thus negative subpatch UVs can be passed to rtcInterpolate to sample subpatches slightly out of bounds. This can be useful to calculate derivatives using finite differences if required. The encoding further has the property that one can just move the value u (or v) on a subpatch by adding du (or dv) to the special UV encoding as long as it does not fall out of the [-0.5,1.5[ range.

To smoothly interpolate vertex attributes over the subdivision surface we recommend using the rtcInterpolate function, which will apply the standard subdivision rules for interpolation and automatically takes care of the special UV encoding for non-quadrilaterals.

Face-Varying Data

Face-varying interpolation is supported through multiple topologies per subdivision mesh and binding such topologies to vertex attribute buffers to interpolate. This way, texture coordinates may use a different topology with additional boundaries to construct separate UV regions inside one subdivision mesh.

Each such topology i has a separate index buffer (specified using RTC_BUFFER_TYPE_INDEX with buffer slot i) and separate subdivision mode that can be set using rtcSetGeometrySubdivisionMode. A vertex attribute buffer RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE bound to a buffer slot j can be assigned to use a topology for interpolation using the rtcSetGeometryVertexAttributeTopology call.

The face buffer (RTC_BUFFER_TYPE_FACE type) is shared between all topologies, which means that the n-th primitive always has the same number of vertices (e.g. being a triangle or a quad) for each topology. However, the indices of the topologies themselves may be different.

EXIT STATUS

On failure NULL is returned and an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewGeometry

RTC_GEOMETRY_TYPE_CURVE

NAME

RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE -
  flat curve geometry with linear basis

RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE -
  flat curve geometry with cubic Bézier basis

RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE - 
  flat curve geometry with cubic B-spline basis

RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE - 
  flat curve geometry with cubic Hermite basis

RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE -
  flat normal oriented curve geometry with cubic Bézier basis

RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_CURVE - 
  flat normal oriented curve geometry with cubic B-spline basis

RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_HERMITE_CURVE - 
  flat normal oriented curve geometry with cubic Hermite basis

RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE -
  sweep surface curve geometry with cubic Bézier basis

RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE -
  sweep surface curve geometry with cubic B-spline basis

RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE -
  sweep surface curve geometry with cubic Hermite basis

SYNOPSIS

#include <embree3/rtcore.h>

rtcNewGeometry(device, RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_HERMITE_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE);
rtcNewGeometry(device, RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE);

DESCRIPTION

Curves with per vertex radii are supported with linear, cubic Bézier, cubic B-spline, and cubic Hermite bases. Such curve geometries are created by passing RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE, RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE, RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE, RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE, RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_FLAT_BEZIER_CURVE, RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_FLAT_BSPLINE_CURVE, RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_FLAT_HERMITE_CURVE, RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE, RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE, or RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE to the rtcNewGeometry function. The curve indices can be specified through an index buffer (RTC_BUFFER_TYPE_INDEX) and the curve vertices through a vertex buffer (RTC_BUFFER_TYPE_VERTEX). For the Hermite basis a tangent buffer (RTC_BUFFER_TYPE_TANGENT) and for normal oriented curves a normal buffer (RTC_BUFFER_TYPE_NORMAL) has to get specified additionally. See rtcSetGeometryBuffer and rtcSetSharedGeometryBuffer for more details on how to set buffers.

The index buffer contains an array of 32-bit indices (RTC_FORMAT_UINT format), each pointing to the first control vertex in the vertex buffer, but also to the first tangent in the tangent buffer, and first normal in the normal buffer if these buffers are present.

The vertex buffer stores each control vertex in the form of a single precision position and radius stored in (x, y, z, r) order in memory (RTC_FORMAT_FLOAT4 format). The number of vertices is inferred from the size of this buffer. The radii may be smaller than zero but the interpolated radii should always be greater or equal to zero. Similarly, the tangent buffer stores the derivative of each control vertex (x, y, z, r order and RTC_FORMAT_FLOAT4 format) and the normal buffer stores a single precision normal per control vertex (x, y, z order and RTC_FORMAT_FLOAT3 format).

For the linear basis the indices point to the first of 2 consecutive control points in the vertex buffer. The first control point is the start and the second control point the end of the line segment. When constructing hair strands in this basis, the end-point can be shared with the start of the next line segment.

For the cubic Bézier basis the indices point to the first of 4 consecutive control points in the vertex buffer. These control points use the cubic Bézier basis, where the first control point represents the start point of the curve, and the 4th control point the end point of the curve. The Bézier basis is interpolating, thus the curve does go exactly through the first and fourth control vertex.

For the cubic B-spline basis the indices point to the first of 4 consecutive control points in the vertex buffer. These control points make up a cardinal cubic B-spline (implicit equidistant knot vector). This basis is not interpolating, thus the curve does in general not go through any of the control points directly. A big advantage of this basis is that 3 control points can be shared for two continuous neighboring curve segments, e.g. the curves (p0,p1,p2,p3) and (p1,p2,p3,p4) are C1 continuous. This feature make this basis a good choise to construct continuous multi-segment curves, as memory consumption can be kept minimal.

For the cubic Hermite basis the indices point to the first of 2 consecutive points in the vertex buffer, and the first of 2 consecutive tangents in the tangent buffer. These two points and two tangents make up a cubic Hermite curve. This basis is interpolating, thus does exactly go through the first and second control point, and the first order derivative at the begin and end matches exactly the value specified in the tangent buffer. When connecting two segments continuously, the end point and tangent of the previous segment can be shared. Different versions of Catmull-Rom splines can be easily constructed usig the Hermite basis, by calculating a proper tangent buffer from the control points.

The RTC_GEOMETRY_TYPE_FLAT_* flat mode is a fast mode designed to render distant hair. In this mode the curve is rendered as a connected sequence of ray facing quads. Individual quads are considered to have subpixel size, and zooming onto the curve might show geometric artifacts. The number of quads to subdivide into can be specified through the rtcSetGeometryTessellationRate function. By default the tessellation rate is 4.

The RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_* mode is a mode designed to render blades of grass. In this mode the curve is rendered as a flat band whose center exactly follows the provided vertex spline, whose half width approximately follows the provided radius spline, and whose orientation follows the provided normals. For normal oriented curves, the indices point to the first of 2 consecutive normals in the normal buffer. The normal of the constructed curve will match the direction of the first normal at the beginning, and the direction of the second normal at the end of the curve. Please note that this layout of the normal buffer is independent of the used basis for the curve itself. For the cubic B-spline and cubic Hermite basis the stride from the first control vertex of the first and the next segment is typically 1, thus the normal buffer is compact and the curves share the normal at the begin and end. However, for the cubic Bézier basis, the stride is typically 3, thus begin and end normal cannot get shared. We recommend using the Hermite basis instead of the Bézier basis, as it allows a more compact layout.

To intersect the normal oriented curve, we perform a newton-raphson style intersection of a ray with a tensor product surface of a linear basis (perpendicular to the curve) and cubic Bézier basis (along the curve). We construct the 8 control points of this surface in Bézier basis by calculating a normalized direction d01=normalize(v1-v0,n0) and d23=normalize(v3-v2,n1). These directions are perpendicular to the tangent direction of the center curve and first and second specified normal. The 8 control vertices of the surface are constructed as:

 p00 = v0-r0*d01, p10 = v0+r0*d01
 p01 = v1-r1*d01, p11 = v1+r1*d01
 p02 = v2-r2*d23, p12 = v2+r2*d23
 p03 = v3-r3*d23, p13 = v3+r3*d23

The center of this curve exactly follows the specified center spline, the normal at the start (and end) exactly match the fisrst (and second) specified normal, and the half width exactly matches the evaluated radius spline at the start (and end). In-between the radius and orientation of the curve changes smoothly. Note that the construction does not work when the provided normals are parallel to the curve direction, as then no well defined perpendicular direction d01 or d23 are defined. For this reason thus the provided normals should best be kept as perpendicular to the curve direction as possible.

In the RTC_GEOMETRY_TYPE_ROUND_* round mode, a real geometric surface is rendered for the curve, which is more expensive but allows closeup views. This mode renders a sweep surface by sweeping a varying radius circle tangential along the curve. As a limitation, the radius of the curve has to be smaller than the curvature radius of the curve at each location on the curve. The round mode is currently not supported for the linear basis.

The intersection with the curve segment stores the parametric hit location along the curve segment as u-coordinate (range 0 to +1).

For Bézier, B-spline, and Hermite curves, the v-coordinate is set to the normalized distance in the range -1 to +1. For the linear basis and in round mode the v-coordinate is set to zero.

In flat mode, the geometry normal Ng is set to the tangent of the curve at the hit location. In round mode and for normal oriented curves, the geometry normal Ng is set to the non-normalized geometric normal of the surface.

For multi-segment motion blur, the number of time steps must be first specified using the rtcSetGeometryTimeStepCount call. Then a vertex buffer for each time step can be set using different buffer slots, and all these buffers must have the same stride and size. For the Hermite basis also a tangent buffer has to be set for each time step and for normal oriented curves a normal buffer has to get specified for each time step.

Also see tutorials [Hair] and [Curves] for examples of how to create and use curve geometries.

EXIT STATUS

On failure NULL is returned and an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewGeometry

RTC_GEOMETRY_TYPE_USER

NAME

RTC_GEOMETRY_TYPE_USER - user geometry type

SYNOPSIS

#include <embree3/rtcore.h>

RTCGeometry geometry =
  rtcNewGeometry(device, RTC_GEOMETRY_TYPE_USER);

DESCRIPTION

User-defined geometries contain a number of user-defined primitives, just like triangle meshes contain multiple triangles. The shape of the user-defined primitives is specified through registered callback functions, which enable extending Embree with arbitrary types of primitives.

User-defined geometries are created by passing RTC_GEOMETRY_TYPE_USER to the rtcNewGeometry function call. One has to set the number of primitives (see rtcSetGeometryUserPrimitiveCount), a user data pointer (see rtcSetGeometryUserData), a bounding function closure (see rtcSetGeometryBoundsFunction), as well as user-defined intersect (see rtcSetGeometryIntersectFunction) and occluded (see rtcSetGeometryOccludedFunction) callback functions. The bounding function is used to query the bounds of all time steps of a user primitive, while the intersect and occluded callback functions are called to intersect the primitive with a ray. The user data pointer is passed to each callback invocation and can be used to point to the application’s representation of the user geometry.

The creation of a user geometry typically looks the following:

RTCGeometry geometry = rtcNewGeometry(device, RTC_GEOMETRY_TYPE_USER);
rtcSetGeometryUserPrimitiveCount(geometry, numPrimitives);
rtcSetGeometryUserData(geometry, userGeometryRepresentation);
rtcSetGeometryBoundsFunction(geometry, boundsFunction);
rtcSetGeometryIntersectFunction(geometry, intersectFunction);
rtcSetGeometryOccludedFunction(geometry, occludedFunction);

Please have a look at the rtcSetGeometryBoundsFunction, rtcSetGeometryIntersectFunction, and rtcSetGeometryOccludedFunction functions on the implementation of the callback functions.

See tutorial [User Geometry] for an example of how to use the user-defined geometries.

EXIT STATUS

On failure NULL is returned and an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewGeometry, rtcSetGeometryUserPrimitiveCount, rtcSetGeometryUserData, rtcSetGeometryBoundsFunction, rtcSetGeometryIntersectFunction, rtcSetGeometryOccludedFunction

RTC_GEOMETRY_TYPE_INSTANCE

NAME

RTC_GEOMETRY_TYPE_INSTANCE - instance geometry type

SYNOPSIS

#include <embree3/rtcore.h>

RTCGeometry geometry =
   rtcNewGeometry(device, RTC_GEOMETRY_TYPE_INSTANCE);

DESCRIPTION

Embree supports instancing of scenes using affine transformations (3x3 matrix plus translation). As the instanced scene is stored only a single time, even if instanced to multiple locations, this feature can be used to create very complex scenes with small memory footprint. Only single-level instancing is supported natively by Embree, however, multi-level instancing can be manually implemented through user geometries.

Instances are created by passing RTC_GEOMETRY_TYPE_INSTANCE to the rtcNewGeometry function call. The instanced scene can be set using the rtcSetGeometryInstancedScene call, and the affine transformation can be set using the rtcSetGeometryTransform function.

Please note that rtcCommitScene on the instanced scene should be called first, followed by rtcCommitGeometry on the instance, followed by rtcCommitScene for the top-level scene containing the instance.

If a ray hits the instance, the geomID and primID members of the hit are set to the geometry ID and primitive ID of the hit primitive in the instanced scene, and the instID member of the hit is set to the geometry ID of the instance in the top-level scene.

The instancing scheme can also be implemented using user geometries. To achieve this, the user geometry code should set the instID member of the intersection context to the geometry ID of the instance, then trace the transformed ray, and finally set the instID field of the intersection context again to -1. The instID field is copied automatically by each primitive intersector into the instID field of the hit structure when the primitive is hit. See the [User Geometry] tutorial for an example.

For multi-segment motion blur, the number of time steps must be first specified using the rtcSetGeometryTimeStepCount function. Then a transformation for each time step can be specified using the rtcSetGeometryTransform function.

See tutorial [Instanced Geometry] for an example of how to use instances.

EXIT STATUS

On failure NULL is returned and an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewGeometry, rtcSetGeometryInstancedScene, rtcSetGeometryTransform

rtcRetainGeometry

NAME

rtcRetainGeometry - increments the geometry reference count

SYNOPSIS

#include <embree3/rtcore.h>

void rtcRetainGeometry(RTCGeometry geometry);

DESCRIPTION

Geometry objects are reference counted. The rtcRetainGeometry function increments the reference count of the passed geometry object (geometry argument). This function together with rtcReleaseGeometry allows to use the internal reference counting in a C++ wrapper class to handle the ownership of the object.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewGeometry, rtcReleaseGeometry

rtcReleaseGeometry

NAME

rtcReleaseGeometry - decrements the geometry reference count

SYNOPSIS

#include <embree3/rtcore.h>

void rtcReleaseGeometry(RTCGeometry geometry);

DESCRIPTION

Geometry objects are reference counted. The rtcReleaseGeometry function decrements the reference count of the passed geometry object (geometry argument). When the reference count falls to 0, the geometry gets destroyed.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewGeometry, rtcRetainGeometry

rtcCommitGeometry

NAME

rtcCommitGeometry - commits geometry changes

SYNOPSIS

#include <embree3/rtcore.h>

void rtcCommitGeometry(RTCGeometry geometry);

DESCRIPTION

The rtcCommitGeometry function is used to commit all geometry changes performed to a geometry (geometry parameter). After a geometry gets modified, this function must be called to properly update the internal state of the geometry to perform interpolations using rtcInterpolate or to commit a scene containing the geometry using rtcCommitScene.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcInterpolate, rtcCommitScene

rtcEnableGeometry

NAME

rtcEnableGeometry - enables the geometry

SYNOPSIS

#include <embree3/rtcore.h>

void rtcEnableGeometry(RTCGeometry geometry);

DESCRIPTION

The rtcEnableGeometry function enables the specified geometry (geometry argument). Only enabled geometries are rendered. Each geometry is enabled by default at construction time.

After enabling a geometry, the scene containing that geometry must be committed using rtcCommitScene for the change to have effect.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewGeometry, rtcDisableGeometry, rtcCommitScene

rtcDisableGeometry

NAME

rtcDisableGeometry - disables the geometry

SYNOPSIS

#include <embree3/rtcore.h>

void rtcDisableGeometry(RTCGeometry geometry);

DESCRIPTION

The rtcDisableGeometry function disables the specified geometry (geometry argument). A disabled geometry is not rendered. Each geometry is enabled by default at construction time.

After disabling a geometry, the scene containing that geometry must be committed using rtcCommitScene for the change to have effect.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewGeometry, rtcEnableGeometry, rtcCommitScene

rtcSetGeometryTimeStepCount

NAME

rtcSetGeometryTimeStepCount - sets the number of time steps of the
  geometry

SYNOPSIS

#include <embree3/rtcore.h>

void rtcSetGeometryTimeStepCount(
  RTCGeometry geometry,
  unsigned int timeStepCount
);

DESCRIPTION

The rtcSetGeometryTimeStepCount function sets the number of time steps for multi-segment motion blur (timeStepCount parameter) of the specified geometry (geometry parameter).

For triangle meshes (RTC_GEOMETRY_TYPE_TRIANGLE), quad meshes (RTC_GEOMETRY_TYPE_QUAD), curves (RTC_GEOMETRY_TYPE_CURVE), and subdivision geometries (RTC_GEOMETRY_TYPE_SUBDIVISION), the number of time steps directly corresponds to the number of vertex buffer slots available (RTC_BUFFER_TYPE_VERTEX buffer type). For these geometries, one vertex buffer per time step must be specified when creating multi-segment motion blur geometries.

For instance geometries (RTC_GEOMETRY_TYPE_INSTANCE), a transformation must be specified for each time step (see rtcSetGeometryTransform).

For user geometries, the registered bounding callback function must provide a bounding box per primitive and time step, and the intersection and occlusion callback functions should properly intersect the motion-blurred geometry at the ray time.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewGeometry

rtcSetGeometryVertexAttributeCount

NAME

rtcSetGeometryVertexAttributeCount - sets the number of vertex
  attributes of the geometry

SYNOPSIS

#include <embree3/rtcore.h>

void rtcSetGeometryVertexAttributeCount(
  RTCGeometry geometry,
  unsigned int vertexAttributeCount
);

DESCRIPTION

The rtcSetGeometryVertexAttributeCount function sets the number of slots (vertexAttributeCount parameter) for vertex attribute buffers (RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) that can be used for the specified geometry (geometry parameter).

This function is supported only for triangle meshes (RTC_GEOMETRY_TYPE_TRIANGLE), quad meshes (RTC_GEOMETRY_TYPE_QUAD), curves (RTC_GEOMETRY_TYPE_CURVE), and subdivision geometries (RTC_GEOMETRY_TYPE_SUBDIVISION).

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewGeometry, [RTCBufferType]

rtcSetGeometryMask

NAME

rtcSetGeometryMask - sets the geometry mask

SYNOPSIS

#include <embree3/rtcore.h>

void rtcSetGeometryMask(
  RTCGeometry geometry,
  unsigned int mask
);

DESCRIPTION

The rtcSetGeometryMask function sets a 32-bit geometry mask (mask argument) for the specified geometry (geometry argument).

This geometry mask is used together with the ray mask stored inside the mask field of the ray. The primitives of the geometry are hit by the ray only if the bitwise and operation of the geometry mask with the ray mask is not 0. This feature can be used to disable selected geometries for specifically tagged rays, e.g. to disable shadow casting for certain geometries.

Ray masks are disabled in Embree by default at compile time, and can be enabled through the EMBREE_RAY_MASK parameter in CMake. One can query whether ray masks are enabled by querying the RTC_DEVICE_PROPERTY_RAY_MASK_SUPPORTED device property using rtcGetDeviceProperty.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

RTCRay, rtcGetDeviceProperty

rtcSetGeometryBuildQuality

NAME

rtcSetGeometryBuildQuality - sets the build quality for the geometry

SYNOPSIS

#include <embree3/rtcore.h>

void rtcSetGeometryBuildQuality(
  RTCGeometry geometry,
  enum RTCBuildQuality quality
);

DESCRIPTION

The rtcSetGeometryBuildQuality function sets the build quality (quality argument) for the specified geometry (geometry argument). The per-geometry build quality is only a hint and may be ignored. Embree currently uses the per-geometry build quality when the scene build quality is set to RTC_BUILD_QUALITY_LOW. In this mode a two-level acceleration structure is build, and geometries build a separate acceleration structure using the geometry build quality. The per-geometry build quality can be one of:

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcSetSceneBuildQuality

rtcSetGeometryBuffer

NAME

rtcSetGeometryBuffer - assigns a view of a buffer to the geometry

SYNOPSIS

#include <embree3/rtcore.h>

void rtcSetGeometryBuffer(
  RTCGeometry geometry,
  enum RTCBufferType type,
  unsigned int slot,
  enum RTCFormat format,
  RTCBuffer buffer,
  size_t byteOffset,
  size_t byteStride,
  size_t itemCount
);

DESCRIPTION

The rtcSetGeometryBuffer function binds a view of a buffer object (buffer argument) to a geometry buffer type and slot (type and slot argument) of the specified geometry (geometry argument).

One can specify the start of the first buffer element in bytes (byteOffset argument), the byte stride between individual buffer elements (byteStride argument), the format of the buffer elements (format argument), and the number of elements to bind (itemCount).

The start address (byteOffset argument) and stride (byteStride argument) must be both aligned to 4 bytes, otherwise the rtcSetGeometryBuffer function will fail.

After successful completion of this function, the geometry will hold a reference to the buffer object.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcSetSharedGeometryBuffer, rtcSetNewGeometryBuffer

rtcSetSharedGeometryBuffer

NAME

rtcSetSharedGeometryBuffer - assigns a view of a shared data buffer
  to a geometry

SYNOPSIS

#include <embree3/rtcore.h>

void rtcSetSharedGeometryBuffer(
  RTCGeometry geometry,
  enum RTCBufferType type,
  unsigned int slot,
  enum RTCFormat format,
  const void* ptr,
  size_t byteOffset,
  size_t byteStride,
  size_t itemCount
);

DESCRIPTION

The rtcSetSharedGeometryBuffer function binds a view of a shared user-managed data buffer (ptr argument) to a geometry buffer type and slot (type and slot argument) of the specified geometry (geometry argument).

One can specify the start of the first buffer element in bytes (byteOffset argument), the byte stride between individual buffer elements (byteStride argument), the format of the buffer elements (format argument), and the number of elements to bind (itemCount).

The start address (byteOffset argument) and stride (byteStride argument) must be both aligned to 4 bytes; otherwise the rtcSetGeometryBuffer function will fail.

When the buffer will be used as a vertex buffer (RTC_BUFFER_TYPE_VERTEX and RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE), the last buffer element must be readable using 16-byte SSE load instructions, thus padding the last element is required for certain layouts. E.g. a standard float3 vertex buffer layout should add storage for at least one more float to the end of the buffer.

The buffer data must remain valid for as long as the buffer may be used, and the user is responsible for freeing the buffer data when no longer required.

Sharing buffers can significantly reduce the memory required by the application, thus we recommend using this feature. When enabling the RTC_SCENE_COMPACT scene flag, the spatial index structures index into the vertex buffer, resulting in even higher memory savings.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcSetGeometryBuffer, rtcSetNewGeometryBuffer

rtcSetNewGeometryBuffer

NAME

rtcSetNewGeometryBuffer - creates and assigns a new data buffer to
  the geometry

SYNOPSIS

#include <embree3/rtcore.h>

void* rtcSetNewGeometryBuffer(
  RTCGeometry geometry,
  enum RTCBufferType type,
  unsigned int slot,
  enum RTCFormat format,
  size_t byteStride,
  size_t itemCount
);

DESCRIPTION

The rtcSetNewGeometryBuffer function creates a new data buffer of specified format (format argument), byte stride (byteStride argument), and number of items (itemCount argument), and assigns it to a geometry buffer slot (type and slot argument) of the specified geometry (geometry argument). The buffer data is managed internally and automatically freed when the geometry is destroyed.

The byte stride (byteStride argument) must be aligned to 4 bytes; otherwise the rtcSetNewGeometryBuffer function will fail.

The allocated buffer will be automatically over-allocated slightly when used as a vertex buffer, where a requirement is that each buffer element should be readable using 16-byte SSE load instructions.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcSetGeometryBuffer, rtcSetSharedGeometryBuffer

rtcGetGeometryBufferData

NAME

rtcGetGeometryBufferData - gets pointer to
  the first buffer view element

SYNOPSIS

#include <embree3/rtcore.h>

void* rtcGetGeometryBufferData(
  RTCGeometry geometry,
  enum RTCBufferType type,
  unsigned int slot
);

DESCRIPTION

The rtcGetGeometryBufferData function returns a pointer to the first element of the buffer view attached to the specified buffer type and slot (type and slot argument) of the geometry (geometry argument).

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcSetGeometryBuffer, rtcSetSharedGeometryBuffer, rtcSetNewGeometryBuffer

rtcUpdateGeometryBuffer

NAME

rtcUpdateGeometryBuffer - marks a buffer view bound to the geometry
  as modified

SYNOPSIS

#include <embree3/rtcore.h>

void rtcUpdateGeometryBuffer(
  RTCGeometry geometry,
  enum RTCBufferType type,
  unsigned int slot
);

DESCRIPTION

The rtcUpdateGeometryBuffer function marks the buffer view bound to the specified buffer type and slot (type and slot argument) of a geometry (geometry argument) as modified.

If a data buffer is changed by the application, the rtcUpdateGeometryBuffer call must be invoked for that buffer. Each buffer view assigned to a buffer slot is initially marked as modified, thus this function needs to be called only when doing buffer modifications after the first rtcCommitScene.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewGeometry, rtcCommitScene

rtcSetGeometryIntersectFilterFunction

NAME

rtcSetGeometryIntersectFilterFunction - sets the intersection filter
  for the geometry

SYNOPSIS

#include <embree3/rtcore.h>

struct RTCFilterFunctionNArguments
{
  int* valid;
  void* geometryUserPtr;
  const struct RTCIntersectContext* context;
  struct RTCRayN* ray;
  struct RTCHitN* hit;
  unsigned int N;
};

typedef void (*RTCFilterFunctionN)(
  const struct RTCFilterFunctionNArguments* args
);

void rtcSetGeometryIntersectFilterFunction(
  RTCGeometry geometry,
  RTCFilterFunctionN filter
);

DESCRIPTION

The rtcSetGeometryIntersectFilterFunction function registers an intersection filter callback function (filter argument) for the specified geometry (geometry argument).

Only a single callback function can be registered per geometry, and further invocations overwrite the previously set callback function. Passing NULL as function pointer disables the registered callback function.

The registered intersection filter function is invoked for every hit encountered during the rtcIntersect-type ray queries and can accept or reject that hit. The feature can be used to define a silhouette for a primitive and reject hits that are outside the silhouette. E.g. a tree leaf could be modeled with an alpha texture that decides whether hit points lie inside or outside the leaf.

If the RTC_SCENE_HIGH_QUALITY mode is set, the filter functions may be called multiple times for the same primitive hit. Further, rays hitting exactly the edge might also report two hits for the same surface. For certain use cases, the application may have to work around this limitation by collecting already reported hits (geomID/primID pairs) and ignoring duplicates.

The filter function callback of type RTCFilterFunctionN gets passed a number of arguments through the RTCFilterFunctionNArguments structure. The valid parameter of that structure points to an integer valid mask (0 means invalid and -1 means valid). The geometryUserPtr member is a user pointer optionally set per geometry through the rtcSetGeometryUserData function. The context member points to the intersection context passed to the ray query function. The ray parameter points to N rays in SOA layout. The hit parameter points to N hits in SOA layout to test. The N parameter is the number of rays and hits in ray and hit. The hit distance is provided as the tfar value of the ray. If the hit geometry is instanced, the instID member of the ray is valid, and the ray and the potential hit are in object space.

The filter callback function has the task to check for each valid ray whether it wants to accept or reject the corresponding hit. To reject a hit, the filter callback function just has to write 0 to the integer valid mask of the corresponding ray. To accept the hit, it just has to leave the valid mask set to -1. The filter function is further allowed to change the hit and decrease the tfar value of the ray but it should not modify other ray data nor any inactive components of the ray or hit.

When performing ray queries using rtcIntersect1, it is guaranteed that the packet size is 1 when the callback is invoked. When performing ray queries using the rtcIntersect4/8/16 functions, it is not generally guaranteed that the ray packet size (and order of rays inside the packet) passed to the callback matches the initial ray packet. However, under some circumstances these properties are guaranteed, and whether this is the case can be queried using rtcGetDeviceProperty. When performing ray queries using the stream API such as rtcIntersect1M, rtcIntersect1Mp, rtcIntersectNM, or rtcIntersectNp the order of rays and ray packet size of the callback function might change to either 1, 4, 8, or 16.

For many usage scenarios, repacking and re-ordering of rays does not cause difficulties in implementing the callback function. However, algorithms that need to extend the ray with additional data must use the rayID component of the ray to identify the original ray to access the per-ray data.

The implementation of the filter function can choose to implement a single code path that uses the ray access helper functions RTCRay_XXX and hit access helper functions RTCHit_XXX to access ray and hit data. Alternatively the code can branch to optimized implementations for specific sizes of N and cast the ray and hit inputs to the proper packet types.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcSetGeometryOccludedFilterFunction

rtcSetGeometryOccludedFilterFunction

NAME

rtcSetGeometryOccludedFilterFunction - sets the occlusion filter
  for the geometry

SYNOPSIS

#include <embree3/rtcore.h>

void rtcSetGeometryOccludedFilterFunction(
  RTCGeometry geometry,
  RTCFilterFunctionN filter
);

DESCRIPTION

The rtcSetGeometryOccludedFilterFunction function registers an occlusion filter callback function (filter argument) for the specified geometry (geometry argument).

Only a single callback function can be registered per geometry, and further invocations overwrite the previously set callback function. Passing NULL as function pointer disables the registered callback function.

The registered intersection filter function is invoked for every hit encountered during the rtcOccluded-type ray queries and can accept or reject that hit. The feature can be used to define a silhouette for a primitive and reject hits that are outside the silhouette. E.g. a tree leaf could be modeled with an alpha texture that decides whether hit points lie inside or outside the leaf.

Please see the description of the rtcSetGeometryIntersectFilterFunction for a description of the filter callback function.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcSetGeometryIntersectFilterFunction

rtcFilterIntersection

NAME

rtcFilterIntersection - invokes the intersection filter function

SYNOPSIS

#include <embree3/rtcore.h>

void rtcFilterIntersection(
  const struct RTCIntersectFunctionNArguments* args,
  const struct RTCFilterFunctionNArguments* filterArgs
);

DESCRIPTION

The rtcFilterIntersection function can be called inside an RTCIntersectFunctionN callback function to invoke the intersection filter registered to the geometry and stored inside the context. For this an RTCFilterFunctionNArguments structure must be created (see rtcSetGeometryIntersectFilterFunction) which basically consists of a valid mask, a hit packet to filter, the corresponding ray packet, and the packet size. After the invocation of rtcFilterIntersection, only rays that are still valid (valid mask set to -1) should update a hit.

EXIT STATUS

For performance reasons this function does not do any error checks, thus will not set any error flags on failure.

SEE ALSO

rtcFilterOcclusion, rtcSetGeometryIntersectFunction

rtcFilterOcclusion

NAME

rtcFilterOcclusion - invokes the occlusion filter function

SYNOPSIS

#include <embree3/rtcore.h>

void rtcFilterOcclusion(
  const struct RTCOccludedFunctionNArguments* args,
  const struct RTCFilterFunctionNArguments* filterArgs
);

DESCRIPTION

The rtcFilterOcclusion function can be called inside an RTCOccludedFunctionN callback function to invoke the occlusion filter registered to the geometry and stored inside the context. For this an RTCFilterFunctionNArguments structure must be created (see rtcSetGeometryIntersectFilterFunction) which basically consists of a valid mask, a hit packet to filter, the corresponding ray packet, and the packet size. After the invocation of rtcFilterOcclusion only rays that are still valid (valid mask set to -1) should signal an occlusion.

EXIT STATUS

For performance reasons this function does not do any error checks, thus will not set any error flags on failure.

SEE ALSO

rtcFilterIntersection, rtcSetGeometryOccludedFunction

rtcSetGeometryUserData

NAME

rtcSetGeometryUserData - sets the user-defined data pointer of the
  geometry

SYNOPSIS

#include <embree3/rtcore.h>

void rtcSetGeometryUserData(RTCGeometry geometry, void* userPtr);

DESCRIPTION

The rtcSetGeometryUserData function sets the user-defined data pointer (userPtr argument) for a geometry (geometry argument). This user data pointer is intended to be pointing to the application’s representation of the geometry, and is passed to various callback functions. The application can use this pointer inside the callback functions to access its geometry representation.

The rtcGetGeometryUserData function can be used to query an already set user data pointer of a geometry.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcGetGeometryUserData

rtcGetGeometryUserData

NAME

rtcGetGeometryUserData - returns the user data pointer
  of the geometry

SYNOPSIS

#include <embree3/rtcore.h>

void* rtcGetGeometryUserData(RTCGeometry geometry);

DESCRIPTION

The rtcGetGeometryUserData function queries the user data pointer previously set with rtcSetGeometryUserData. When rtcSetGeometryUserData was not called yet, NULL is returned.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcSetGeometryUserData

rtcSetGeometryUserPrimitiveCount

NAME

rtcSetGeometryUserPrimitiveCount - sets the number of primitives
  of a user-defined geometry

SYNOPSIS

#include <embree3/rtcore.h>

void rtcSetGeometryUserPrimitiveCount(
  RTCGeometry geometry,
  unsigned int userPrimitiveCount
);

DESCRIPTION

The rtcSetGeometryUserPrimitiveCount function sets the number of user-defined primitives (userPrimitiveCount parameter) of the specified user-defined geometry (geometry parameter).

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

RTC_GEOMETRY_TYPE_USER

rtcSetGeometryBoundsFunction

NAME

rtcSetGeometryBoundsFunction - sets a callback to query the
  bounding box of user-defined primitives

SYNOPSIS

#include <embree3/rtcore.h>

struct RTCBoundsFunctionArguments
{
  void* geometryUserPtr;
  unsigned int primID;
  unsigned int timeStep;
  struct RTCBounds* bounds_o;
};

typedef void (*RTCBoundsFunction)(
  const struct RTCBoundsFunctionArguments* args
);

void rtcSetGeometryBoundsFunction(
  RTCGeometry geometry,
  RTCBoundsFunction bounds,
  void* userPtr
);

DESCRIPTION

The rtcSetGeometryBoundsFunction function registers a bounding box callback function (bounds argument) with payload (userPtr argument) for the specified user geometry (geometry argument).

Only a single callback function can be registered per geometry, and further invocations overwrite the previously set callback function. Passing NULL as function pointer disables the registered callback function.

The registered bounding box callback function is invoked to calculate axis-aligned bounding boxes of the primitives of the user-defined geometry during spatial acceleration structure construction. The bounding box callback of RTCBoundsFunction type is invoked with a pointer to a structure of type RTCBoundsFunctionArguments which contains various arguments, such as: the user data of the geometry (geometryUserPtr member), the ID of the primitive to calculate the bounds for (primID member), the time step at which to calculate the bounds (timeStep member), and a memory location to write the calculated bound to (bounds_o member).

In a typical usage scenario one would store a pointer to the internal representation of the user geometry object using rtcSetGeometryUserData. The callback function can then read that pointer from the geometryUserPtr field and calculate the proper bounding box for the requested primitive and time, and store that bounding box to the destination structure (bounds_o member).

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

RTC_GEOMETRY_TYPE_USER

rtcSetGeometryIntersectFunction

NAME

rtcSetGeometryIntersectFunction - sets the callback function to
  intersect a user geometry

SYNOPSIS

#include <embree3/rtcore.h>

struct RTCIntersectFunctionNArguments
{
  int* valid;
  void* geometryUserPtr;
  unsigned int primID;
  struct RTCIntersectContext* context;
  struct RTCRayHitN* rayhit;
  unsigned int N;
};

typedef void (*RTCIntersectFunctionN)(
  const struct RTCIntersectFunctionNArguments* args
);

void rtcSetGeometryIntersectFunction(
  RTCGeometry geometry,
  RTCIntersectFunctionN intersect
);

DESCRIPTION

The rtcSetGeometryIntersectFunction function registers a ray/primitive intersection callback function (intersect argument) for the specified user geometry (geometry argument).

Only a single callback function can be registered per geometry and further invocations overwrite the previously set callback function. Passing NULL as function pointer disables the registered callback function.

The registered callback function is invoked by rtcIntersect-type ray queries to calculate the intersection of a ray packet of variable size with one user-defined primitive. The callback function of type RTCIntersectFunctionN gets passed a number of arguments through the RTCIntersectFunctionNArguments structure. The value N specifies the ray packet size, valid points to an array of integers that specify whether the corresponding ray is valid (-1) or invalid (0), the geometryUserPtr member points to the geometry user data previously set through rtcSetGeometryUserData, the context member points to the intersection context passed to the ray query, the rayhit member points to a ray and hit packet of variable size N, and the primID member identifies the primitive ID of the primitive to intersect.

The ray component of the rayhit structure contains valid data, in particular the tfar value is the current closest hit distance found. All data inside the hit component of the rayhit structure are undefined and should not be read by the function.

The task of the callback function is to intersect each active ray from the ray packet with the specified user primitive. If the user-defined primitive is missed by a ray of the ray packet, the function should return without modifying the ray or hit. If an intersection of the user-defined primitive with the ray was found in the valid range (from tnear to tfar), it should update the hit distance of the ray (tfar member) and the hit (u, v, Ng, instID, geomID, primID members). In particular, the currently intersected instance is stored in the instID field of the intersection context, which must be copied into the instID member of the hit.

As a primitive might have multiple intersections with a ray, the intersection filter function needs to be invoked by the user geometry intersection callback for each encountered intersection, if filtering of intersections is desired. This can be achieved through the rtcFilterIntersection call.

Within the user geometry intersect function, it is safe to trace new rays and create new scenes and geometries.

When performing ray queries using rtcIntersect1, it is guaranteed that the packet size is 1 when the callback is invoked. When performing ray queries using the rtcIntersect4/8/16 functions, it is not generally guaranteed that the ray packet size (and order of rays inside the packet) passed to the callback matches the initial ray packet. However, under some circumstances these properties are guaranteed, and whether this is the case can be queried using rtcGetDeviceProperty. When performing ray queries using the stream API such as rtcIntersect1M, rtcIntersect1Mp, rtcIntersectNM, or rtcIntersectNp the order of rays and ray packet size of the callback function might change to either 1, 4, 8, or 16.

For many usage scenarios, repacking and re-ordering of rays does not cause difficulties in implementing the callback function. However, algorithms that need to extend the ray with additional data must use the rayID component of the ray to identify the original ray to access the per-ray data.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcSetGeometryOccludedFunction, rtcSetGeometryUserData, rtcFilterIntersection

rtcSetGeometryOccludedFunction

NAME

rtcSetGeometryOccludedFunction - sets the callback function to
  test a user geometry for occlusion

SYNOPSIS

#include <embree3/rtcore.h>

struct RTCOccludedFunctionNArguments
{
  int* valid;
  void* geometryUserPtr;
  unsigned int primID;
  struct RTCIntersectContext* context;
  struct RTCRayN* ray;
  unsigned int N;
};

typedef void (*RTCOccludedFunctionN)(
  const struct RTCOccludedFunctionNArguments* args
);

void rtcSetGeometryOccludedFunction(
  RTCGeometry geometry,
  RTCOccludedFunctionN filter
);

DESCRIPTION

The rtcSetGeometryOccludedFunction function registers a ray/primitive occlusion callback function (filter argument) for the specified user geometry (geometry argument).

Only a single callback function can be registered per geometry, and further invocations overwrite the previously set callback function. Passing NULL as function pointer disables the registered callback function.

The registered callback function is invoked by rtcOccluded-type ray queries to test whether the rays of a packet of variable size are occluded by a user-defined primitive. The callback function of type RTCOccludedFunctionN gets passed a number of arguments through the RTCOccludedFunctionNArguments structure. The value N specifies the ray packet size, valid points to an array of integers which specify whether the corresponding ray is valid (-1) or invalid (0), the geometryUserPtr member points to the geometry user data previously set through rtcSetGeometryUserData, the context member points to the intersection context passed to the ray query, the ray member points to a ray packet of variable size N, and the primID member identifies the primitive ID of the primitive to test for occlusion.

The task of the callback function is to intersect each active ray from the ray packet with the specified user primitive. If the user-defined primitive is missed by a ray of the ray packet, the function should return without modifying the ray. If an intersection of the user-defined primitive with the ray was found in the valid range (from tnear to tfar), it should set the tfar member of the ray to -inf.

As a primitive might have multiple intersections with a ray, the occlusion filter function needs to be invoked by the user geometry occlusion callback for each encountered intersection, if filtering of intersections is desired. This can be achieved through the rtcFilterOcclusion call.

Within the user geometry occlusion function, it is safe to trace new rays and create new scenes and geometries.

When performing ray queries using rtcOccluded1, it is guaranteed that the packet size is 1 when the callback is invoked. When performing ray queries using the rtcOccluded4/8/16 functions, it is not generally guaranteed that the ray packet size (and order of rays inside the packet) passed to the callback matches the initial ray packet. However, under some circumstances these properties are guaranteed, and whether this is the case can be queried using rtcGetDeviceProperty. When performing ray queries using the stream API such as rtcOccluded1M, rtcOccluded1Mp, rtcOccludedNM, or rtcOccludedNp the order of rays and ray packet size of the callback function might change to either 1, 4, 8, or 16.

For many usage scenarios, repacking and re-ordering of rays does not cause difficulties in implementing the callback function. However, algorithms that need to extend the ray with additional data must use the rayID component of the ray to identify the original ray to access the per-ray data.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcSetGeometryIntersectFunction, rtcSetGeometryUserData, rtcFilterOcclusion

rtcSetGeometryInstancedScene

NAME

rtcSetGeometryInstancedScene - sets the instanced scene of
  an instance geometry

SYNOPSIS

#include <embree3/rtcore.h>

void rtcSetGeometryInstancedScene(
  RTCGeometry geometry,
  RTCScene scene
);

DESCRIPTION

The rtcSetGeometryInstancedScene function sets the instanced scene (scene argument) of the specified instance geometry (geometry argument).

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

RTC_GEOMETRY_TYPE_INSTANCE, rtcSetGeometryTransform

rtcSetGeometryTransform

NAME

rtcSetGeometryTransform - sets the transformation for a particular
  time step of an instance geometry

SYNOPSIS

#include <embree3/rtcore.h>

void rtcSetGeometryTransform(
  RTCGeometry geometry,
  unsigned int timeStep,
  enum RTCFormat format,
  const float* xfm
);

DESCRIPTION

The rtcSetGeometryTransform function sets the local-to-world affine transformation (xfm parameter) of an instance geometry (geometry parameter) for a particular time step (timeStep parameter). The transformation is specified as a 3×4 matrix (3×3 linear transformation plus translation), for which the following formats (format parameter) are supported:

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

RTC_GEOMETRY_TYPE_INSTANCE

rtcGetGeometryTransform

NAME

rtcGetGeometryTransform - returns the interpolated instance
  transformation for the specified time

SYNOPSIS

#include <embree3/rtcore.h>

void rtcGetGeometryTransform(
  RTCGeometry geometry,
  float time,
  enum RTCFormat format,
  void* xfm
);

DESCRIPTION

The rtcGetGeometryTransform function returns the interpolated local to world transformation (xfm parameter) of an instance geometry (geometry parameter) for a particular time (time parameter in range [0, 1]) in the specified format (format parameter).

Possible formats for the returned matrix are:

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

RTC_GEOMETRY_TYPE_INSTANCE, rtcSetGeometryTransform

rtcSetGeometryTessellationRate

NAME

rtcSetGeometryTessellationRate - sets the tessellation rate of the
  geometry

SYNOPSIS

#include <embree3/rtcore.h>

void rtcSetGeometryTessellationRate(
  RTCGeometry geometry,
  float tessellationRate
);

DESCRIPTION

The rtcSetGeometryTessellationRate function sets the tessellation rate (tessellationRate argument) for the specified geometry (geometry argument). The tessellation rate can only be set for flat curves and subdivision geometries. For curves, the tessellation rate specifies the number of ray-facing quads per curve segment. For subdivision surfaces, the tessellation rate specifies the number of quads along each edge.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

RTC_GEOMETRY_TYPE_CURVE, RTC_GEOMETRY_TYPE_SUBDIVISION

rtcSetGeometryTopologyCount

NAME

rtcSetGeometryTopologyCount - sets the number of topologies of
  a subdivision geometry

SYNOPSIS

#include <embree3/rtcore.h>

void rtcSetGeometryTopologyCount(
  RTCGeometry geometry,
  unsigned int topologyCount
);

DESCRIPTION

The rtcSetGeometryTopologyCount function sets the number of topologies (topologyCount parameter) for the specified subdivision geometry (geometry parameter). The number of topologies of a subdivision geometry must be greater or equal to 1.

To use multiple topologies, first the number of topologies must be specified, then the individual topologies can be configured using rtcSetGeometrySubdivisionMode and by setting an index buffer (RTC_BUFFER_TYPE_INDEX) using the topology ID as the buffer slot.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

RTC_GEOMETRY_TYPE_SUBDIVISION, rtcSetGeometrySubdivisionMode

rtcSetGeometrySubdivisionMode

NAME

rtcSetGeometrySubdivisionMode - sets the subdivision mode
  of a subdivision geometry

SYNOPSIS

#include <embree3/rtcore.h>

void rtcSetGeometrySubdivisionMode(
  RTCGeometry geometry,
  unsigned int topologyID,
  enum RTCSubdivisionMode mode
);

DESCRIPTION

The rtcSetGeometrySubdivisionMode function sets the subdivision mode (mode parameter) for the topology (topologyID parameter) of the specified subdivision geometry (geometry parameter).

The subdivision modes can be used to force linear interpolation for certain parts of the subdivision mesh:

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

RTC_GEOMETRY_TYPE_SUBDIVISION

rtcSetGeometryVertexAttributeTopology

NAME

rtcSetGeometryVertexAttributeTopology - binds a vertex
  attribute to a topology of the geometry

SYNOPSIS

#include <embree3/rtcore.h>

void rtcSetGeometryVertexAttributeTopology(
  RTCGeometry geometry,
  unsigned int vertexAttributeID,
  unsigned int topologyID
);

DESCRIPTION

The rtcSetGeometryVertexAttributeTopology function binds a vertex attribute buffer slot (vertexAttributeID argument) to a topology (topologyID argument) for the specified subdivision geometry (geometry argument). Standard vertex buffers are always bound to the default topology (topology 0) and cannot be bound differently. A vertex attribute buffer always uses the topology it is bound to when used in the rtcInterpolate and rtcInterpolateN calls.

A topology with ID i consists of a subdivision mode set through rtcSetGeometrySubdivisionMode and the index buffer bound to the index buffer slot i. This index buffer can assign indices for each face of the subdivision geometry that are different to the indices of the default topology. These new indices can for example be used to introduce additional borders into the subdivision mesh to map multiple textures onto one subdivision geometry.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcSetGeometrySubdivisionMode, rtcInterpolate, rtcInterpolateN

rtcSetGeometryDisplacementFunction

NAME

rtcSetGeometryDisplacementFunction - sets the displacement function
  for a subdivision geometry

SYNOPSIS

#include <embree3/rtcore.h>

struct RTCDisplacementFunctionNArguments
{
  void* geometryUserPtr;
  RTCGeometry geometry;
  unsigned int primID;
  unsigned int timeStep;
  const float* u;
  const float* v;
  const float* Ng_x;
  const float* Ng_y;
  const float* Ng_z;
  float* P_x;
  float* P_y;
  float* P_z;
  unsigned int N;
};

typedef void (*RTCDisplacementFunctionN)(
   const struct RTCDisplacementFunctionNArguments* args
);

void rtcSetGeometryDisplacementFunction(
  RTCGeometry geometry,
  RTCDisplacementFunctionN displacement
);

DESCRIPTION

The rtcSetGeometryDisplacementFunction function registers a displacement callback function (displacement argument) for the specified subdivision geometry (geometry argument).

Only a single callback function can be registered per geometry, and further invocations overwrite the previously set callback function. Passing NULL as function pointer disables the registered callback function.

The registered displacement callback function is invoked to displace points on the subdivision geometry during spatial acceleration structure construction, during the rtcCommitScene call.

The callback function of type RTCDisplacementFunctionN is invoked with a number of arguments stored inside the RTCDisplacementFunctionNArguments structure. The provided user data pointer of the geometry (geometryUserPtr member) can be used to point to the application’s representation of the subdivision mesh. A number N of points to displace are specified in a structure of array layout. For each point to displace, the local patch UV coordinates (u and v arrays), the normalized geometry normal (Ng_x, Ng_y, and Ng_z arrays), and the position (P_x, P_y, and P_z arrays) are provided. The task of the displacement function is to use this information and change the position data.

The geometry handle (geometry member) and primitive ID (primID member) of the patch to displace are additionally provided as well as the time step timeStep, which can be important if the displacement is time-dependent and motion blur is used.

All passed arrays must be aligned to 64 bytes and properly padded to make wide vector processing inside the displacement function easily possible.

Also see tutorial [Displacement Geometry] for an example of how to use the displacement mapping functions.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

RTC_GEOMETRY_TYPE_SUBDIVISION

rtcGetGeometryFirstHalfEdge

NAME

rtcGetGeometryFirstHalfEdge - returns the first half edge of a face

SYNOPSIS

#include <embree3/rtcore.h>

unsigned int rtcGetGeometryFirstHalfEdge(
  RTCGeometry geometry,
  unsigned int faceID
);

DESCRIPTION

The rtcGetGeometryFirstHalfEdge function returns the ID of the first half edge belonging to the specified face (faceID argument). For instance in the following example the first half edge of face f1 is e4.

[][imgHalfEdges]

This function can only be used for subdivision geometries. As all topologies of a subdivision geometry share the same face buffer the function does not depend on the topology ID.

Here f0 to f7 are 8 quadrilateral faces with 4 vertices each. The edges e0 to e23 of these faces are shown with their orientation. For each face the ID of the edges corresponds to the slots the face occupies in the index array of the geometry. E.g. as the indices of face f1 start at location 4 of the index array, the first edge is edge e4, the next edge e5, etc.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcGetGeometryFirstHalfEdge, rtcGetGeometryFace, rtcGetGeometryOppositeHalfEdge, rtcGetGeometryNextHalfEdge, rtcGetGeometryPreviousHalfEdge

rtcGetGeometryFace

NAME

rtcGetGeometryFace - returns the face of some half edge

SYNOPSIS

#include <embree3/rtcore.h>

unsigned int rtcGetGeometryFace(
  RTCGeometry geometry,
  unsigned int edgeID
);

DESCRIPTION

The rtcGetGeometryFace function returns the ID of the face the specified half edge (edgeID argument) belongs to. For instance in the following example the face f1 is returned for edges e4, e5, e6, and e7.

[][imgHalfEdges]

This function can only be used for subdivision geometries. As all topologies of a subdivision geometry share the same face buffer the function does not depend on the topology ID.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcGetGeometryFirstHalfEdge, rtcGetGeometryFace, rtcGetGeometryOppositeHalfEdge, rtcGetGeometryNextHalfEdge, rtcGetGeometryPreviousHalfEdge

rtcGetGeometryNextHalfEdge

NAME

rtcGetGeometryNextHalfEdge - returns the next half edge

SYNOPSIS

#include <embree3/rtcore.h>

unsigned int rtcGetGeometryNextHalfEdge(
  RTCGeometry geometry,
  unsigned int edgeID
);

DESCRIPTION

The rtcGetGeometryNextHalfEdge function returns the ID of the next half edge of the specified half edge (edgeID argument). For instance in the following example the next half edge of e10 is e11.

[][imgHalfEdges]

This function can only be used for subdivision geometries. As all topologies of a subdivision geometry share the same face buffer the function does not depend on the topology ID.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcGetGeometryFirstHalfEdge, rtcGetGeometryFace, rtcGetGeometryOppositeHalfEdge, rtcGetGeometryNextHalfEdge, rtcGetGeometryPreviousHalfEdge

rtcGetGeometryPreviousHalfEdge

NAME

rtcGetGeometryPreviousHalfEdge - returns the previous half edge

SYNOPSIS

#include <embree3/rtcore.h>

unsigned int rtcGetGeometryPreviousHalfEdge(
  RTCGeometry geometry,
  unsigned int edgeID
);

DESCRIPTION

The rtcGetGeometryPreviousHalfEdge function returns the ID of the previous half edge of the specified half edge (edgeID argument). For instance in the following example the previous half edge of e6 is e5.

[][imgHalfEdges]

This function can only be used for subdivision geometries. As all topologies of a subdivision geometry share the same face buffer the function does not depend on the topology ID.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcGetGeometryFirstHalfEdge, rtcGetGeometryFace, rtcGetGeometryOppositeHalfEdge, rtcGetGeometryNextHalfEdge, rtcGetGeometryPreviousHalfEdge

rtcGetGeometryOppositeHalfEdge

NAME

rtcGetGeometryOppositeHalfEdge - returns the opposite half edge

SYNOPSIS

#include <embree3/rtcore.h>

unsigned int rtcGetGeometryOppositeHalfEdge(
  RTCGeometry geometry,
  unsigned int topologyID,
  unsigned int edgeID
);

DESCRIPTION

The rtcGetGeometryOppositeHalfEdge function returns the ID of the opposite half edge of the specified half edge (edgeID argument) in the specified topology (topologyID argument). For instance in the following example the opposite half edge of e6 is e16.

[][imgHalfEdges]

An opposite half edge does not exist if the specified half edge has either no neighboring face, or more than 2 neighboring faces. In these cases the function just returns the same edge edgeID again.

This function can only be used for subdivision geometries. The function depends on the topology as the topologies of a subdivision geometry have different index buffers assigned.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcGetGeometryFirstHalfEdge, rtcGetGeometryFace, rtcGetGeometryOppositeHalfEdge, rtcGetGeometryNextHalfEdge, rtcGetGeometryPreviousHalfEdge

rtcInterpolate

NAME

rtcInterpolate - interpolates vertex attributes

SYNOPSIS

#include <embree3/rtcore.h>

struct RTCInterpolateArguments
{
  RTCGeometry geometry;
  unsigned int primID;
  float u;
  float v;
  enum RTCBufferType bufferType;
  unsigned int bufferSlot;
  float* P;
  float* dPdu;
  float* dPdv;
  float* ddPdudu;
  float* ddPdvdv;
  float* ddPdudv;
  unsigned int valueCount;
};

void rtcInterpolate(
  const struct RTCInterpolateArguments* args
);

DESCRIPTION

The rtcInterpolate function smoothly interpolates per-vertex data over the geometry. This interpolation is supported for triangle meshes, quad meshes, curve geometries, and subdivision geometries. Apart from interpolating the vertex attribute itself, it is also possible to get the first and second order derivatives of that value. This interpolation ignores displacements of subdivision surfaces and always interpolates the underlying base surface.

The rtcInterpolate call gets passed a number of arguments inside a structure of type RTCInterpolateArguments. For some geometry (geometry parameter) this function smoothly interpolates the per-vertex data stored inside the specified geometry buffer (bufferType and bufferSlot parameters) to the u/v location (u and v parameters) of the primitive (primID parameter). The number of floating point values to interpolate and store to the destination arrays can be specified using the valueCount parameter. As interpolation buffer, one can specify vertex buffers (RTC_BUFFER_TYPE_VERTEX) and vertex attribute buffers (RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) as well.

The rtcInterpolate call stores valueCount number of interpolated floating point values to the memory location pointed to by P. One can avoid storing the interpolated value by setting P to NULL.

The first order derivative of the interpolation by u and v are stored at the dPdu and dPdv memory locations. One can avoid storing first order derivatives by setting both dPdu and dPdv to NULL.

The second order derivatives are stored at the ddPdudu, ddPdvdv, and ddPdudv memory locations. One can avoid storing second order derivatives by setting these three pointers to NULL.

To use rtcInterpolate for a geometry, all changes to that geometry must be properly committed using rtcCommitGeometry.

All input buffers and output arrays must be padded to 16 bytes, as the implementation uses 16-byte SSE instructions to read and write into these buffers.

See tutorial [Interpolation] for an example of using the rtcInterpolate function.

EXIT STATUS

For performance reasons this function does not do any error checks, thus will not set any error flags on failure.

SEE ALSO

rtcInterpolateN

rtcInterpolateN

NAME

rtcInterpolateN - performs N interpolations of vertex attribute data

SYNOPSIS

#include <embree3/rtcore.h>

struct RTCInterpolateNArguments
{
  RTCGeometry geometry;
  const void* valid;
  const unsigned int* primIDs;
  const float* u;
  const float* v;
  unsigned int N;
  enum RTCBufferType bufferType;
  unsigned int bufferSlot;
  float* P;
  float* dPdu;
  float* dPdv;
  float* ddPdudu;
  float* ddPdvdv;
  float* ddPdudv;
  unsigned int valueCount;
};

void rtcInterpolateN(
  const struct RTCInterpolateNArguments* args
);

DESCRIPTION

The rtcInterpolateN is similar to rtcInterpolate, but performs N many interpolations at once. It additionally gets an array of u/v coordinates and a valid mask (valid parameter) that specifies which of these coordinates are valid. The valid mask points to N integers, and a value of -1 denotes valid and 0 invalid. If the valid pointer is NULL all elements are considers valid. The destination arrays are filled in structure of array (SOA) layout. The value N must be divisible by 4.

To use rtcInterpolateN for a geometry, all changes to that geometry must be properly committed using rtcCommitGeometry.

EXIT STATUS

For performance reasons this function does not do any error checks, thus will not set any error flags on failure.

SEE ALSO

rtcInterpolate

rtcNewBuffer

NAME

rtcNewBuffer - creates a new data buffer

SYNOPSIS

#include <embree3/rtcore.h>

RTCBuffer rtcNewBuffer(
  RTCDevice device,
  size_t byteSize
);

DESCRIPTION

The rtcNewBuffer function creates a new data buffer object of specified size in bytes (byteSize argument) that is bound to the specified device (device argument). The buffer object is reference counted with an initial reference count of 1. The returned buffer object can be released using the rtcReleaseBuffer API call. The specified number of bytes are allocated at buffer construction time and deallocated when the buffer is destroyed.

When the buffer will be used as a vertex buffer (RTC_BUFFER_TYPE_VERTEX and RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE), the last buffer element must be readable using 16-byte SSE load instructions, thus padding the last element is required for certain layouts. E.g. a standard float3 vertex buffer layout should add storage for at least one more float to the end of the buffer.

EXIT STATUS

On failure NULL is returned and an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcRetainBuffer, rtcReleaseBuffer

rtcNewSharedBuffer

NAME

rtcNewSharedBuffer - creates a new shared data buffer

SYNOPSIS

#include <embree3/rtcore.h>

RTCBuffer rtcNewSharedBuffer(
  RTCDevice device,
  void* ptr,
  size_t byteSize
);

DESCRIPTION

The rtcNewSharedBuffer function creates a new shared data buffer object bound to the specified device (device argument). The buffer object is reference counted with an initial reference count of 1. The buffer can be released using the rtcReleaseBuffer function.

At construction time, the pointer to the user-managed buffer data (ptr argument) including its size in bytes (byteSize argument) is provided to create the buffer. At buffer construction time no buffer data is allocated, but the buffer data provided be the application is used. The buffer data must remain valid for as long as the buffer may be used, and the user is responsible to free the buffer data when no longer required.

When the buffer will be used as a vertex buffer (RTC_BUFFER_TYPE_VERTEX and RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE), the last buffer element must be readable using 16-byte SSE load instructions, thus padding the last element is required for certain layouts. E.g. a standard float3 vertex buffer layout should add storage for at least one more float to the end of the buffer.

The data pointer (ptr argument) must be aligned to 4 bytes; otherwise the rtcNewSharedBuffer function will fail.

EXIT STATUS

On failure NULL is returned and an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcRetainBuffer, rtcReleaseBuffer

rtcRetainBuffer

NAME

rtcRetainBuffer - increments the buffer reference count

SYNOPSIS

#include <embree3/rtcore.h>

void rtcRetainBuffer(RTCBuffer buffer);

DESCRIPTION

Buffer objects are reference counted. The rtcRetainBuffer function increments the reference count of the passed buffer object (buffer argument). This function together with rtcReleaseBuffer allows to use the internal reference counting in a C++ wrapper class to handle the ownership of the object.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewBuffer, rtcReleaseBuffer

rtcReleaseBuffer

NAME

rtcReleaseBuffer - decrements the buffer reference count

SYNOPSIS

#include <embree3/rtcore.h>

void rtcReleaseBuffer(RTCBuffer buffer);

DESCRIPTION

Buffer objects are reference counted. The rtcReleaseBuffer function decrements the reference count of the passed buffer object (buffer argument). When the reference count falls to 0, the buffer gets destroyed.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewBuffer, rtcRetainBuffer

rtcGetBufferData

NAME

rtcGetBufferData - gets a pointer to the buffer data

SYNOPSIS

#include <embree3/rtcore.h>

void* rtcGetBufferData(RTCBuffer buffer);

DESCRIPTION

The rtcGetBufferData function returns a pointer to the buffer data of the specified buffer object (buffer argument).

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewBuffer

RTCRay

NAME

RTCRay - single ray structure

SYNOPSIS

#include <embree3/rtcore_ray.h>

struct RTC_ALIGN(16) RTCRay
{
  float org_x;        // x coordinate of ray origin
  float org_y;        // y coordinate of ray origin
  float org_z;        // z coordinate of ray origin
  float tnear;        // start of ray segment

  float dir_x;        // x coordinate of ray direction
  float dir_y;        // y coordinate of ray direction
  float dir_z;        // z coordinate of ray direction
  float time;         // time of this ray for motion blur

  float tfar;         // end of ray segment (set to hit distance)
  unsigned int mask;  // ray mask
  unsigned int id;    // ray ID
  unsigned int flags; // ray flags
};

DESCRIPTION

The RTCRay structure defines the ray layout for a single ray. The ray contains the origin (org_x, org_y, org_z members), direction vector (dir_x, dir_y, dir_z members), and ray segment (tnear and tfar members). The ray direction does not have to be normalized, and only the parameter range specified by the tnear/tfar interval is considered valid.

The ray segment must be in the range [0, ∞], thus ranges that start behind the ray origin are not allowed, but ranges can reach to infinity. For rays inside a ray stream, tfar < tnear identifies an inactive ray.

The ray further contains a motion blur time in the range [0, 1] (time member), a ray mask (mask member), a ray ID (id member), and ray flags (flags member). The ray mask can be used to mask out some geometries for some rays (see rtcSetGeometryMask for more details). The ray ID can be used to identify a ray inside a callback function, even if the order of rays inside a ray packet or stream has changed. The ray flags are reserved.

The embree3/rtcore_ray.h header additionally defines the same ray structure in structure of array (SOA) layout for API functions accepting ray packets of size 4 (RTCRay4 type), size 8 (RTCRay8 type), and size 16 (RTCRay16 type). The header additionally defines an RTCRayNt template for ray packets of an arbitrary compile-time size.

EXIT STATUS

SEE ALSO

RTCHit

RTCHit

NAME

RTCHit - single hit structure

SYNOPSIS

#include <embree3/rtcore.h>

struct RTCHit
{
  float Ng_x;          // x coordinate of geometry normal
  float Ng_y;          // y coordinate of geometry normal
  float Ng_z;          // z coordinate of geometry normal

  float u;             // barycentric u coordinate of hit
  float v;             // barycentric v coordinate of hit

  unsigned int primID; // geometry ID
  unsigned int geomID; // primitive ID
  unsigned int instID[RTC_MAX_INSTANCE_LEVEL_COUNT]; // instance ID
};

DESCRIPTION

The RTCHit type defines the type of a ray/primitive intersection result. The hit contains the unnormalized geometric normal in object space at the hit location (Ng_x, Ng_y, Ng_z members), the barycentric u/v coordinates of the hit (u and v members), as well as the primitive ID (primID member), geometry ID (geomID member), and instance ID (instID member) of the hit. The parametric intersection distance is not stored inside the hit, but stored inside the tfar member of the ray.

The embree3/rtcore_ray.h header additionally defines the same hit structure in structure of array (SOA) layout for hit packets of size 4 (RTCHit4 type), size 8 (RTCHit8 type), and size 16 (RTCHit16 type). The header additionally defines an RTCHitNt template for hit packets of an arbitrary compile-time size.

EXIT STATUS

SEE ALSO

RTCRay

RTCRayHit

NAME

RTCRayHit - combined single ray/hit structure

SYNOPSIS

#include <embree3/rtcore_ray.h>

struct RTCORE_ALIGN(16) RTCRayHit
{
  struct RTCRay ray;
  struct RTCHit hit;
};

DESCRIPTION

The RTCRayHit structure is used as input for the rtcIntersect-type functions and stores the ray to intersect and some hit fields that hold the intersection result afterwards.

The embree3/rtcore_ray.h header additionally defines the same ray/hit structure in structure of array (SOA) layout for API functions accepting ray packets of size 4 (RTCRayHit4 type), size 8 (RTCRayHit8 type), and size 16 (RTCRayHit16 type). The header additionally defines an RTCRayHitNt template to generate ray/hit packets of an arbitrary compile-time size.

EXIT STATUS

SEE ALSO

RTCRay, RTCHit

RTCRayN

NAME

RTCRayN - ray packet of runtime size

SYNOPSIS

#include <embree3/rtcore_ray.h>

struct RTCRayN;

float& RTCRayN_org_x(RTCRayN* ray, unsigned int N, unsigned int i);
float& RTCRayN_org_y(RTCRayN* ray, unsigned int N, unsigned int i);
float& RTCRayN_org_z(RTCRayN* ray, unsigned int N, unsigned int i);
float& RTCRayN_tnear(RTCRayN* ray, unsigned int N, unsigned int i);

float& RTCRayN_dir_x(RTCRayN* ray, unsigned int N, unsigned int i);
float& RTCRayN_dir_y(RTCRayN* ray, unsigned int N, unsigned int i);
float& RTCRayN_dir_z(RTCRayN* ray, unsigned int N, unsigned int i);
float& RTCRayN_time (RTCRayN* ray, unsigned int N, unsigned int i);

float&        RTCRayN_tfar (RTCRayN* ray, unsigned int N, unsigned int i);
unsigned int& RTCRayN_mask (RTCRayN* ray, unsigned int N, unsigned int i);
unsigned int& RTCRayN_id   (RTCRayN* ray, unsigned int N, unsigned int i);
unsigned int& RTCRayN_flags(RTCRayN* ray, unsigned int N, unsigned int i);

DESCRIPTION

When the ray packet size is not known at compile time (e.g. when Embree returns a ray packet in the RTCFilterFuncN callback function), Embree uses the RTCRayN type for ray packets. These ray packets can only have sizes of 1, 4, 8, or 16. No other packet size will be used.

You can either implement different special code paths for each of these possible packet sizes and cast the ray to the appropriate ray packet type, or implement one general code path that uses the RTCRayN_XXX helper functions to access the ray packet components.

These helper functions get a pointer to the ray packet (ray argument), the packet size (N argument), and returns a reference to a component (e.g. x-component of origin) of the the i-th ray of the packet (i argument).

EXIT STATUS

SEE ALSO

RTCHitN

RTCHitN

NAME

RTCHitN - hit packet of runtime size

SYNOPSIS

#include <embree3/rtcore.h>

struct HitN;

float& RTCHitN_Ng_x(RTCHitN* hit, unsigned int N, unsigned int i);
float& RTCHitN_Ng_y(RTCHitN* hit, unsigned int N, unsigned int i);
float& RTCHitN_Ng_z(RTCHitN* hit, unsigned int N, unsigned int i);

float& RTCHitN_u(RTCHitN* hit, unsigned int N, unsigned int i);
float& RTCHitN_v(RTCHitN* hit, unsigned int N, unsigned int i);

unsigned& RTCHitN_primID(RTCHitN* hit, unsigned int N, unsigned int i);
unsigned& RTCHitN_geomID(RTCHitN* hit, unsigned int N, unsigned int i);
unsigned& RTCHitN_instID(RTCHitN* hit, unsigned int N, unsigned int i, unsigned int l);

DESCRIPTION

When the hit packet size is not known at compile time (e.g. when Embree returns a hit packet in the RTCFilterFuncN callback function), Embree uses the RTCHitN type for hit packets. These hit packets can only have sizes of 1, 4, 8, or 16. No other packet size will be used.

You can either implement different special code paths for each of these possible packet sizes and cast the hit to the appropriate hit packet type, or implement one general code path that uses the RTCHitN_XXX helper functions to access hit packet components.

These helper functions get a pointer to the hit packet (hit argument), the packet size (N argument), and returns a reference to a component (e.g. x component of Ng) of the the i-th hit of the packet (i argument).

EXIT STATUS

SEE ALSO

RTCRayN

RTCRayHitN

NAME

RTCRayHitN - combined ray/hit packet of runtime size

SYNOPSIS

#include <embree3/rtcore_ray.h>

struct RTCRayHitN;

struct RTCRayN* RTCRayHitN_RayN(struct RTCRayHitN* rayhit, unsigned int N);
struct RTCHitN* RTCRayHitN_HitN(struct RTCRayHitN* rayhit, unsigned int N);

DESCRIPTION

When the packet size of a ray/hit structure is not known at compile time (e.g. when Embree returns a ray/hit packet in the RTCIntersectFunctionN callback function), Embree uses the RTCRayHitN type for ray packets. These ray/hit packets can only have sizes of 1, 4, 8, or 16. No other packet size will be used.

You can either implement different special code paths for each of these possible packet sizes and cast the ray/hit to the appropriate ray/hit packet type, or extract the RTCRayN and RTCHitN components using the rtcGetRayN and rtcGetHitN helper functions and use the RTCRayN_XXX and RTCHitN_XXX functions to access the ray and hit parts of the structure.

EXIT STATUS

SEE ALSO

RTCHitN

rtcInitIntersectContext

NAME

rtcInitIntersectContext - initializes the intersection context

SYNOPSIS

#include <embree3/rtcore.h>

enum RTCIntersectContextFlags
{
  RTC_INTERSECT_CONTEXT_FLAG_NONE,
  RTC_INTERSECT_CONTEXT_FLAG_INCOHERENT,
  RTC_INTERSECT_CONTEXT_FLAG_COHERENT,
};

struct RTCIntersectContext
{
  enum RTCIntersectContextFlags flags;
  RTCFilterFunctionN filter;
  unsigned int instID[RTC_MAX_INSTANCE_LEVEL_COUNT];
};

void rtcInitIntersectContext(
  struct RTCIntersectContext* context
);

DESCRIPTION

A per ray-query intersection context (RTCIntersectContext type) is supported that can be used to configure intersection flags (flags member), specify a filter callback function (filter member), specify the ID of the current instance (instID member), and to attach arbitrary data to the query (e.g. per ray data).

The rtcInitIntersectContext function initializes the context to default values and should be called to initialize every intersection context. This function gets inlined, which minimizes overhead and allows for compiler optimizations.

The intersection context flag can be used to tune the behavior of the traversal algorithm. Using the RTC_INTERSECT_CONTEXT_FLAG_INCOHERENT flags uses an optimized traversal algorithm for incoherent rays (default), while RTC_INTERSECT_CONTEXT_FLAG_COHERENT uses an optimized traversal algorithm for coherent rays (e.g. primary camera rays).

Best primary ray performance can be obtained by using the ray stream API and setting the intersect context flag to RTC_INTERSECT_CONTEXT_FLAG_COHERENT. For secondary rays, it is typically better to use the RTC_INTERSECT_CONTEXT_FLAG_INCOHERENT flag, unless the rays are known to be very coherent too (e.g. for primary transparency rays).

A filter function can be specified inside the context. This filter function is invoked as a second filter stage after the per-geometry intersect or occluded filter function is invoked. Only rays that passed the first filter stage are valid in this second filter stage. Having such a per ray-query filter function can be useful to implement modifications of the behavior of the query, such as collecting all hits or accumulating transparencies. The support for the context filter function must be enabled for a scene by using the RTC_SCENE_FLAG_CONTEXT_FILTER_FUNCTION scene flag.

It is guaranteed that the pointer to the intersection context passed to a ray query is directly passed to the registered callback functions. This way it is possible to attach arbitrary data to the end of the intersection context, such as a per-ray payload.

Please note that the ray pointer is not guaranteed to be passed to the callback functions, thus reading additional data from the ray pointer passed to callbacks is not possible.

EXIT STATUS

No error code is set by this function.

SEE ALSO

rtcIntersect1, rtcOccluded1

rtcIntersect1

NAME

rtcIntersect1 - finds the closest hit for a single ray

SYNOPSIS

#include <embree3/rtcore.h>

void rtcIntersect1(
  RTCScene scene,
  struct RTCIntersectContext* context,
  struct RTCRayHit* rayhit
);

DESCRIPTION

The rtcIntersect1 function finds the closest hit of a single ray with the scene (scene argument). The provided ray/hit structure (rayhit argument) contains the ray to intersect and some hit output fields that are filled when a hit is found.

The user has to initialize the ray origin (org ray member), ray direction (dir ray member), ray segment (tnear, tfar ray members), and set the ray flags to 0 (flags ray member). If the scene contains motion blur geometries, also the ray time (time ray member) must be initialized to a value in the range [0, 1]. If ray masks are enabled at compile time, the ray mask (mask ray member) must be initialized as well. The ray segment has to be in the range [0, ∞], thus ranges that start behind the ray origin are not valid, but ranges can reach to infinity. See Section RTCRay for the ray layout description.

The instance ID (instID hit member) and geometry ID (geomID hit member) of the hit data must be initialized to RTC_INVALID_GEOMETRY_ID (-1).

Further, an intersection context for the ray query function must be created and initialized (see rtcInitIntersectContext).

When no intersection is found, the ray/hit data is not updated. When an intersection is found, the hit distance is written into the tfar member of the ray and all hit data is set, such as unnormalized geometry normal in object space (Ng hit member), local hit coordinates (u, v hit member), instance ID (instID hit member), geometry ID (geomID hit member), and primitive ID (primID hit member). See Section RTCHit for the hit layout description.

If the instance ID was set (thus it is not equal to RTC_INVALID_GEOMETRY_ID), the instance ID corresponds to the geometry ID of the hit instance of the top-level scene, the geometry ID corresponds to the hit geometry inside the hit instanced scene, and the primitive ID corresponds to the n-th primitive of that geometry.

If the instance ID was not set (thus it is still equal to RTC_INVALID_GEOMETRY_ID), the geometry ID corresponds to the hit geometry inside the scene, and the primitive ID corresponds to the n-th primitive of that geometry.

The implementation makes no guarantees that primitives whose hit distance is exactly at (or very close to) tnear or tfar are hit or missed. If you want to exclude intersections at tnear just pass a slightly enlarged tnear, and if you want to include intersections at tfar pass a slightly enlarged tfar.

The intersection context (context argument) can specify flags to optimize traversal and a filter callback function to be invoked for every intersection. Further, the pointer to the intersection context is propagated to callback functions invoked during traversal and can thus be used to extend the ray with additional data. See Section RTCIntersectContext for more information.

The ray pointer passed to callback functions is not guaranteed to be identical to the original ray provided. To extend the ray with additional data to be accessed in callback functions, use the intersection context.

The ray/hit structure must be aligned to 16 bytes.

EXIT STATUS

For performance reasons this function does not do any error checks, thus will not set any error flags on failure.

SEE ALSO

rtcOccluded1, RTCRayHit, RTCRay, RTCHit

rtcOccluded1

NAME

rtcOccluded1 - finds any hit for a single ray

SYNOPSIS

#include <embree3/rtcore.h>

void rtcOccluded1(
  RTCScene scene,
  struct RTCIntersectContext* context,
  struct RTCRay* ray
);

DESCRIPTION

The rtcOccluded1 function checks for a single ray (ray argument) whether there is any hit with the scene (scene argument).

The user must initialize the ray origin (org ray member), ray direction (dir ray member), ray segment (tnear, tfar ray members), and must set the ray flags to 0 (flags ray member). If the scene contains motion blur geometries, also the ray time (time ray member) must be initialized to a value in the range [0, 1]. If ray masks are enabled at compile time, the ray mask (mask ray member) must be initialized as well. The ray segment must be in the range [0, ∞], thus ranges that start behind the ray origin are not valid, but ranges can reach to infinity. See Section RTCRay for the ray layout description.

When no intersection is found, the ray data is not updated. In case a hit was found, the tfar component of the ray is set to -inf.

The implementation makes no guarantees that primitives whose hit distance is exactly at (or very close to) tnear or tfar are hit or missed. If you want to exclude intersections at tnear just pass a slightly enlarged tnear, and if you want to include intersections at tfar pass a slightly enlarged tfar.

The intersection context (context argument) can specify flags to optimize traversal and a filter callback function to be invoked for every intersection. Further, the pointer to the intersection context is propagated to callback functions invoked during traversal and can thus be used to extend the ray with additional data. See Section RTCIntersectContext for more information.

The ray pointer passed to callback functions is not guaranteed to be identical to the original ray provided. To extend the ray with additional data to be accessed in callback functions, use the intersection context.

The ray must be aligned to 16 bytes.

EXIT STATUS

For performance reasons this function does not do any error checks, thus will not set any error flags on failure.

SEE ALSO

rtcOccluded1, RTCRay

rtcIntersect4/8/16

NAME

rtcIntersect4/8/16 - finds the closest hits for a ray packet

SYNOPSIS

#include <embree3/rtcore.h>

void rtcIntersect4(
  const int* valid,
  RTCScene scene,
  struct RTCIntersectContext* context,
  struct RTCRayHit4* rayhit
);

void rtcIntersect8(
  const int* valid,
  RTCScene scene,
  struct RTCIntersectContext* context,
  struct RTCRayHit8* rayhit
);

void rtcIntersect16(
  const int* valid,
  RTCScene scene,
  struct RTCIntersectContext* context,
  struct RTCRayHit16* rayhit
);

DESCRIPTION

The rtcIntersect4/8/16 functions finds the closest hits for a ray packet of size 4, 8, or 16 (rayhit argument) with the scene (scene argument). The ray/hit input contains a ray packet and hit packet. See Section rtcIntersect1 for a description of how to set up and trace rays.

A ray valid mask must be provided (valid argument) which stores one 32-bit integer (-1 means valid and 0 invalid) per ray in the packet. Only active rays are processed, and hit data of inactive rays is not changed.

The intersection context (context argument) can specify flags to optimize traversal and a filter callback function to be invoked for every intersection. Further, the pointer to the intersection context is propagated to callback functions invoked during traversal and can thus be used to extend the ray with additional data. See Section RTCIntersectContext for more information.

The ray pointer passed to callback functions is not guaranteed to be identical to the original ray provided. To extend the ray with additional data to be accessed in callback functions, use the intersection context.

The implementation of these functions is guaranteed to invoke callback functions always with the same ray packet size and ordering of rays as specified initially.

For rtcIntersect4 the ray packet must be aligned to 16 bytes, for rtcIntersect8 the alignment must be 32 bytes, and for rtcIntersect16 the alignment must be 64 bytes.

The rtcIntersect4, rtcIntersect8 and rtcIntersect16 functions may change the ray packet size and ray order when calling back into intersect filter functions or user geometry callbacks. Under some conditions the application can assume packets to stay intakt, which can determined by querying the RTC_DEVICE_PROPERTY_NATIVE_RAY4_SUPPORTED, RTC_DEVICE_PROPERTY_NATIVE_RAY8_SUPPORTED, RTC_DEVICE_PROPERTY_NATIVE_RAY16_SUPPORTED properties through the rtcGetDeviceProperty function. See rtcGetDeviceProperty for more information.

EXIT STATUS

For performance reasons this function does not do any error checks, thus will not set any error flags on failure.

SEE ALSO

rtcOccluded4/8/16

rtcOccluded4/8/16

NAME

rtcOccluded4/8/16 - finds any hits for a ray packet

SYNOPSIS

#include <embree3/rtcore.h>

void rtcOccluded4(
  const int* valid,
  RTCScene scene,
  struct RTCIntersectContext* context,
  struct RTCRay4* ray
);

void rtcOccluded8(
  const int* valid,
  RTCScene scene,
  struct RTCIntersectContext* context,
  struct RTCRay8* ray
);

void rtcOccluded16(
  const int* valid,
  RTCScene scene,
  struct RTCIntersectContext* context,
  struct RTCRay16* ray
);

DESCRIPTION

The rtcOccluded4/8/16 functions checks for each active ray of the ray packet of size 4, 8, or 16 (ray argument) whether there is any hit with the scene (scene argument). See Section rtcOccluded1 for a description of how to set up and trace occlusion rays.

A ray valid mask must be provided (valid argument) which stores one 32-bit integer (-1 means valid and 0 invalid) per ray in the packet. Only active rays are processed, and hit data of inactive rays is not changed.

The intersection context (context argument) can specify flags to optimize traversal and a filter callback function to be invoked for every intersection. Further, the pointer to the intersection context is propagated to callback functions invoked during traversal and can thus be used to extend the ray with additional data. See Section RTCIntersectContext for more information.

The ray pointer passed to callback functions is not guaranteed to be identical to the original ray provided. To extend the ray with additional data to be accessed in callback functions, use the intersection context.

The implementation of these functions is guaranteed to invoke callback functions always with the same ray packet size and ordering of rays as specified initially.

For rtcOccluded4 the ray packet must be aligned to 16 bytes, for rtcOccluded8 the alignment must be 32 bytes, and for rtcOccluded16 the alignment must be 64 bytes.

The rtcOccluded4, rtcOccluded8 and rtcOccluded16 functions may change the ray packet size and ray order when calling back into intersect filter functions or user geometry callbacks. Under some conditions the application can assume packets to stay intakt, which can determined by querying the RTC_DEVICE_PROPERTY_NATIVE_RAY4_SUPPORTED, RTC_DEVICE_PROPERTY_NATIVE_RAY8_SUPPORTED, RTC_DEVICE_PROPERTY_NATIVE_RAY16_SUPPORTED properties through the rtcGetDeviceProperty function. See rtcGetDeviceProperty for more information.

EXIT STATUS

For performance reasons this function does not do any error checks, thus will not set any error flags on failure.

SEE ALSO

rtcOccluded4/8/16

rtcIntersect1M

NAME

rtcIntersect1M - finds the closest hits for a stream of M single
  rays

SYNOPSIS

#include <embree3/rtcore.h>

void rtcIntersect1M(
  RTCScene scene,
  struct RTCIntersectContext* context,
  struct RTCRayHit* rayhit,
  unsigned int M,
  size_t byteStride
);

DESCRIPTION

The rtcIntersect1M function finds the closest hits for a stream of M single rays (rayhit argument) with the scene (scene argument). The rayhit argument points to an array of ray and hit data with specified byte stride (byteStride argument) between the ray/hit structures. See Section rtcIntersect1 for a description of how to set up and trace rays.

The intersection context (context argument) can specify flags to optimize traversal and a filter callback function to be invoked for every intersection. Further, the pointer to the intersection context is propagated to callback functions invoked during traversal and can thus be used to extend the ray with additional data. See Section RTCIntersectContext for more information.

The implementation of the stream ray query functions may re-order rays arbitrarily and re-pack rays into ray packets of different size. For this reason, callback functions may be invoked with an arbitrary packet size (of size 1, 4, 8, or 16) and different ordering as specified initially. For this reason, one may have to use the rayID component of the ray to identify the original ray, e.g. to access a per-ray payload.

A ray in a ray stream is considered inactive if its tnear value is larger than its tfar value.

The stream size M can be an arbitrary positive integer including 0. Each ray must be aligned to 16 bytes.

EXIT STATUS

For performance reasons this function does not do any error checks, thus will not set any error flags on failure.

SEE ALSO

rtcOccluded1M

rtcOccluded1M

NAME

rtcOccluded1M - finds any hits for a stream of M single rays

SYNOPSIS

#include <embree3/rtcore.h>

void rtcOccluded1M(
  RTCScene scene,
  struct RTCIntersectContext* context,
  struct RTCRay* ray,
  unsigned int M,
  size_t byteStride
);

DESCRIPTION

The rtcOccluded1M function checks whether there are any hits for a stream of M single rays (ray argument) with the scene (scene argument). The ray argument points to an array of rays with specified byte stride (byteStride argument) between the rays. See Section rtcOccluded1 for a description of how to set up and trace occlusion rays.

The intersection context (context argument) can specify flags to optimize traversal and a filter callback function to be invoked for every intersection. Further, the pointer to the intersection context is propagated to callback functions invoked during traversal and can thus be used to extend the ray with additional data. See Section RTCIntersectContext for more information.

The implementation of the stream ray query functions may re-order rays arbitrarily and re-pack rays into ray packets of different size. For this reason, callback functions may be invoked with an arbitrary packet size (of size 1, 4, 8, or 16) and different ordering as specified initially. For this reason, one may have to use the rayID component of the ray to identify the original ray, e.g. to access a per-ray payload.

A ray in a ray stream is considered inactive if its tnear value is larger than its tfar value.

The stream size M can be an arbitrary positive integer including 0. Each ray must be aligned to 16 bytes.

EXIT STATUS

For performance reasons this function does not do any error checks, thus will not set any error flags on failure.

SEE ALSO

rtcIntersect1M

rtcIntersect1Mp

NAME

rtcIntersect1Mp - finds the closest hits for a stream of M pointers
  to single rays

SYNOPSIS

#include <embree3/rtcore.h>

void rtcIntersect1Mp(
  RTCScene scene,
  struct RTCIntersectContext* context,
  struct RTCRayHit** rayhit,
  unsigned int M
);

DESCRIPTION

The rtcIntersect1Mp function finds the closest hits for a stream of M single rays (rayhit argument) with the scene (scene argument). The rayhit argument points to an array of pointers to the individual ray/hit structures. See Section rtcIntersect1 for a description of how to set up and trace a ray.

The intersection context (context argument) can specify flags to optimize traversal and a filter callback function to be invoked for every intersection. Further, the pointer to the intersection context is propagated to callback functions invoked during traversal and can thus be used to extend the ray with additional data. See Section RTCIntersectContext for more information.

The implementation of the stream ray query functions may re-order rays arbitrarily and re-pack rays into ray packets of different size. For this reason, callback functions may be invoked with an arbitrary packet size (of size 1, 4, 8, or 16) and different ordering as specified initially. For this reason, one may have to use the rayID component of the ray to identify the original ray, e.g. to access a per-ray payload.

A ray in a ray stream is considered inactive if its tnear value is larger than its tfar value.

The stream size M can be an arbitrary positive integer including 0. Each ray must be aligned to 16 bytes.

EXIT STATUS

For performance reasons this function does not do any error checks, thus will not set any error flags on failure.

SEE ALSO

rtcOccluded1Mp

rtcOccluded1Mp

NAME

rtcOccluded1Mp - find any hits for a stream of M pointers to
  single rays

SYNOPSIS

#include <embree3/rtcore.h>

void rtcOccluded1M(
  RTCScene scene,
  struct RTCIntersectContext* context,
  struct RTCRay** ray,
  unsigned int M
);

DESCRIPTION

The rtcOccluded1Mp function checks whether there are any hits for a stream of M single rays (ray argument) with the scene (scene argument). The ray argument points to an array of pointers to rays. Section rtcOccluded1 for a description of how to set up and trace a occlusion rays.

The intersection context (context argument) can specify flags to optimize traversal and a filter callback function to be invoked for every intersection. Further, the pointer to the intersection context is propagated to callback functions invoked during traversal and can thus be used to extend the ray with additional data. See Section RTCIntersectContext for more information.

The implementation of the stream ray query functions may re-order rays arbitrarily and re-pack rays into ray packets of different size. For this reason, callback functions may be invoked with an arbitrary packet size (of size 1, 4, 8, or 16) and different ordering as specified initially. For this reason, one may have to use the rayID component of the ray to identify the original ray, e.g. to access a per-ray payload.

A ray in a ray stream is considered inactive if its tnear value is larger than its tfar value.

The stream size M can be an arbitrary positive integer including 0. Each ray must be aligned to 16 bytes.

EXIT STATUS

For performance reasons this function does not do any error checks, thus will not set any error flags on failure.

SEE ALSO

rtcIntersect1Mp

rtcIntersectNM

NAME

rtcIntersectNM - finds the closest hits for a stream of M
  ray packets of size N

SYNOPSIS

#include <embree3/rtcore.h>

void rtcIntersectNM(
  RTCScene scene,
  struct RTCIntersectContext* context,
  struct RTCRayHitN* rayhit,
  unsigned int N,
  unsigned int M,
  size_t byteStride
);

DESCRIPTION

The rtcIntersectNM function finds the closest hits for a stream of M ray packets (rayhit argument) of size N with the scene (scene argument). The rays argument points to an array of ray and hit packets with specified byte stride (byteStride argument) between the ray/hit packets. See Section rtcIntersect1 for a description of how to set up and trace rays.

The intersection context (context argument) can specify flags to optimize traversal and a filter callback function to be invoked for every intersection. Further, the pointer to the intersection context is propagated to callback functions invoked during traversal and can thus be used to extend the ray with additional data. See Section RTCIntersectContext for more information.

The implementation of the stream ray query functions may re-order rays arbitrarily and re-pack rays into ray packets of different size. For this reason, callback functions may be invoked with an arbitrary packet size (of size 1, 4, 8, or 16) and different ordering as specified initially. For this reason, one may have to use the rayID component of the ray to identify the original ray, e.g. to access a per-ray payload.

A ray in a ray stream is considered inactive if its tnear value is larger than its tfar value.

The packet size N must be larger than 0, and the stream size M can be an arbitrary positive integer including 0. Each ray must be aligned to 16 bytes.

EXIT STATUS

For performance reasons this function does not do any error checks, thus will not set any error flags on failure.

SEE ALSO

rtcOccludedNM

rtcOccludedNM

NAME

rtcOccludedNM - finds any hits for a stream of M ray packets of
  size N

SYNOPSIS

#include <embree3/rtcore.h>

void rtcOccludedNM(
  RTCScene scene,
  struct RTCIntersectContext* context,
  struct RTCRayN* ray,
  unsigned int N,
  unsigned int M,
  size_t byteStride
);

DESCRIPTION

The rtcOccludedNM function checks whether there are any hits for a stream of M ray packets (ray argument) of size N with the scene (scene argument). The ray argument points to an array of ray packets with specified byte stride (byteStride argument) between the ray packets. See Section rtcOccluded1 for a description of how to set up and trace occlusion rays.

The intersection context (context argument) can specify flags to optimize traversal and a filter callback function to be invoked for every intersection. Further, the pointer to the intersection context is propagated to callback functions invoked during traversal and can thus be used to extend the ray with additional data. See Section RTCIntersectContext for more information.

The implementation of the stream ray query functions may re-order rays arbitrarily and re-pack rays into ray packets of different size. For this reason, callback functions may be invoked with an arbitrary packet size (of size 1, 4, 8, or 16) and different ordering as specified initially. For this reason, one may have to use the rayID component of the ray to identify the original ray, e.g. to access a per-ray payload.

A ray in a ray stream is considered inactive if its tnear value is larger than its tfar value.

The packet size N must be larger than 0, and the stream size M can be an arbitrary positive integer including 0. Each ray must be aligned to 16 bytes.

EXIT STATUS

For performance reasons this function does not do any error checks, thus will not set any error flags on failure.

SEE ALSO

rtcIntersectNM

rtcIntersectNp

NAME

rtcIntersectNp - finds the closest hits for a SOA ray stream of
  size N

SYNOPSIS

#include <embree3/rtcore.h>

void rtcIntersectNp(
  RTCScene scene,
  struct RTCIntersectContext* context,
  struct RTCRayHitNp* rayhit,
  unsigned int N
);

DESCRIPTION

The rtcIntersectNp function finds the closest hits for a SOA ray stream (rays argument) of size N (basically a large ray packet) with the scene (scene argument). The rayhit argument points to two structures of pointers with one pointer for each ray and hit component. Each of these pointers points to an array with the ray or hit component data for each ray or hit. This way the individual components of the SOA ray stream do not need to be stored sequentially in memory, which makes it possible to have large varying size ray packets in SOA layout. See Section rtcIntersect1 for a description of how to set up and trace rays.

The intersection context (context argument) can specify flags to optimize traversal and a filter callback function to be invoked for every intersection. Further, the pointer to the intersection context is propagated to callback functions invoked during traversal and can thus be used to extend the ray with additional data. See Section RTCIntersectContext for more information.

The implementation of the stream ray query functions may re-order rays arbitrarily and re-pack rays into ray packets of different size. For this reason, callback functions may be invoked with an arbitrary packet size (of size 1, 4, 8, or 16) and different ordering as specified initially. For this reason, one may have to use the rayID component of the ray to identify the original ray, e.g. to access a per-ray payload.

A ray in a ray stream is considered inactive if its tnear value is larger than its tfar value.

The stream size N can be an arbitrary positive integer including 0. Each ray component array must be aligned to 16 bytes.

EXIT STATUS

For performance reasons this function does not do any error checks, thus will not set any error flags on failure.

SEE ALSO

rtcOccludedNp

rtcOccludedNp

NAME

rtcOccludedNp - finds any hits for a SOA ray stream of size N

SYNOPSIS

#include <embree3/rtcore.h>

void rtcOccludedNp(
  RTCScene scene,
  struct RTCIntersectContext* context,
  struct RTCRayNp* ray,
  unsigned int N
);

DESCRIPTION

The rtcOccludedNp function checks whether there are any hits for a SOA ray stream (ray argument) of size N (basically a large ray packet) with the scene (scene argument). The ray argument points to a structure of pointers with one pointer for each ray component. Each of these pointers points to an array with the ray component data for each ray. This way the individual components of the SOA ray stream do not need to be stored sequentially in memory, which makes it possible to have large varying size ray packets in SOA layout. See Section rtcOccluded1 for a description of how to set up and trace occlusion rays.

The intersection context (context argument) can specify flags to optimize traversal and a filter callback function to be invoked for every intersection. Further, the pointer to the intersection context is propagated to callback functions invoked during traversal and can thus be used to extend the ray with additional data. See Section RTCIntersectContext for more information.

The implementation of the stream ray query functions may re-order rays arbitrarily and re-pack rays into ray packets of different size. For this reason, callback functions may be invoked with an arbitrary packet size (of size 1, 4, 8, or 16) and different ordering as specified initially. For this reason, one may have to use the rayID component of the ray to identify the original ray, e.g. to access a per-ray payload.

A ray in a ray stream is considered inactive if its tnear value is larger than its tfar value.

The stream size N can be an arbitrary positive integer including 0. Each ray component array must be aligned to 16 bytes.

EXIT STATUS

For performance reasons this function does not do any error checks, thus will not set any error flags on failure.

SEE ALSO

rtcIntersectNp

rtcNewBVH

NAME

rtcNewBVH - creates a new BVH object

SYNOPSIS

#include <embree3/rtcore.h>

RTCBVH rtcNewBVH(RTCDevice device);

DESCRIPTION

This function creates a new BVH object and returns a handle to this BVH. The BVH object is reference counted with an initial reference count of 1. The handle can be released using the rtcReleaseBVH API call.

The BVH object can be used to build a BVH in a user-specified format over user-specified primitives. See the documentation of the rtcBuildBVH call for more details.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcRetainBVH, rtcReleaseBVH, rtcBuildBVH

rtcRetainBVH

NAME

rtcRetainBVH - increments the BVH reference count

SYNOPSIS

#include <embree3/rtcore.h>

void rtcRetainBVH(RTCBVH bvh);

DESCRIPTION

BVH objects are reference counted. The rtcRetainBVH function increments the reference count of the passed BVH object (bvh argument). This function together with rtcReleaseBVH allows to use the internal reference counting in a C++ wrapper class to handle the ownership of the object.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewBVH, rtcReleaseBVH

rtcReleaseBVH

NAME

rtcReleaseBVH - decrements the BVH reference count

SYNOPSIS

#include <embree3/rtcore.h>

void rtcReleaseBVH(RTCBVH bvh);

DESCRIPTION

BVH objects are reference counted. The rtcReleaseBVH function decrements the reference count of the passed BVH object (bvh argument). When the reference count falls to 0, the BVH gets destroyed.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewBVH, rtcRetainBVH

rtcBuildBVH

NAME

rtcBuildBVH - builds a BVH

SYNOPSIS

#include <embree3/rtcore.h>

struct RTC_ALIGN(32) RTCBuildPrimitive
{
  float lower_x, lower_y, lower_z; 
  unsigned int geomID;
  float upper_x, upper_y, upper_z;
  unsigned int primID;
};

typedef void* (*RTCCreateNodeFunction) (
  RTCThreadLocalAllocator allocator,
  unsigned int childCount,
  void* userPtr
);

typedef void (*RTCSetNodeChildrenFunction) (
  void* nodePtr,
  void** children,
  unsigned int childCount,
  void* userPtr
);

typedef void (*RTCSetNodeBoundsFunction) (
  void* nodePtr,
  const struct RTCBounds** bounds,
  unsigned int childCount,
  void* userPtr
);

typedef void* (*RTCCreateLeafFunction) (
  RTCThreadLocalAllocator allocator,
  const struct RTCBuildPrimitive* primitives,
  size_t primitiveCount,
  void* userPtr
);

typedef void (*RTCSplitPrimitiveFunction) (
  const struct RTCBuildPrimitive* primitive,
  unsigned int dimension,
  float position,
  struct RTCBounds* leftBounds,
  struct RTCBounds* rightBounds,
  void* userPtr
);

typedef bool (*RTCProgressMonitorFunction)(
  void* userPtr, double n
);

enum RTCBuildFlags
{
  RTC_BUILD_FLAG_NONE,
  RTC_BUILD_FLAG_DYNAMIC
};

struct RTCBuildArguments
{
  size_t byteSize;

  enum RTCBuildQuality buildQuality;
  enum RTCBuildFlags buildFlags;
  unsigned int maxBranchingFactor;
  unsigned int maxDepth;
  unsigned int sahBlockSize;
  unsigned int minLeafSize;
  unsigned int maxLeafSize;
  float traversalCost;
  float intersectionCost;

  RTCBVH bvh;
  struct RTCBuildPrimitive* primitives;
  size_t primitiveCount;
  size_t primitiveArrayCapacity;
  
  RTCCreateNodeFunction createNode;
  RTCSetNodeChildrenFunction setNodeChildren;
  RTCSetNodeBoundsFunction setNodeBounds;
  RTCCreateLeafFunction createLeaf;
  RTCSplitPrimitiveFunction splitPrimitive;
  RTCProgressMonitorFunction buildProgress;
  void* userPtr;
};

struct RTCBuildArguments rtcDefaultBuildArguments();

void* rtcBuildBVH(
  const struct RTCBuildArguments* args
);

DESCRIPTION

The rtcBuildBVH function can be used to build a BVH in a user-defined format over arbitrary primitives. All arguments to the function are provided through the RTCBuildArguments structure. The first member of that structure must be set to the size of the structure in bytes (bytesSize member) which allows future extensions of the structure. It is recommended to initialize the build arguments structure using the rtcDefaultBuildArguments function.

The rtcBuildBVH function gets passed the BVH to build (bvh member), the array of primitives (primitives member), the capacity of that array (primitiveArrayCapacity member), the number of primitives stored inside the array (primitiveCount member), callback function pointers, and a user-defined pointer (userPtr member) that is passed to all callback functions when invoked. The primitives array can be freed by the application after the BVH is built. All callback functions are typically called from multiple threads, thus their implementation must be thread-safe.

Four callback functions must be registered, which are invoked during build to create BVH nodes (createNode member), to set the pointers to all children (setNodeChildren member), to set the bounding boxes of all children (setNodeBounds member), and to create a leaf node (createLeaf member).

The function pointer to the primitive split function (splitPrimitive member) may be NULL, however, then no spatial splitting in high quality mode is possible. The function pointer used to report the build progress (buildProgress member) is optional and may also be NULL.

Further, some build settings are passed to configure the BVH build. Using the build quality settings (buildQuality member), one can select between a faster, low quality build which is good for dynamic scenes, and a standard quality build for static scenes. One can also specify the desired maximum branching factor of the BVH (maxBranchingFactor member), the maximum depth the BVH should have (maxDepth member), the block size for the SAH heuristic (sahBlockSize member), the minimum and maximum leaf size (minLeafSize and maxLeafSize member), and the estimated costs of one traversal step and one primitive intersection (traversalCost and intersectionCost members). When enabling the RTC_BUILD_FLAG_DYNAMIC build flags (buildFlags member), re-build performance for dynamic scenes is improved at the cost of higher memory requirements.

To spatially split primitives in high quality mode, the builder needs extra space at the end of the build primitive array to store splitted primitives. The total capacity of the build primitive array is passed using the primitiveArrayCapacity member, and should be about twice the number of primitives when using spatial splits.

The RTCCreateNodeFunc and RTCCreateLeafFunc callbacks are passed a thread local allocator object that should be used for fast allocation of nodes using the rtcThreadLocalAlloc function. We strongly recommend using this allocation mechanism, as alternative approaches like standard malloc can be over 10× slower. The allocator object passed to the create callbacks may be used only inside the current thread. Memory allocated using rtcThreadLocalAlloc is automatically freed when the RTCBVH object is deleted. If you use your own memory allocation scheme you have to free the memory yourself when the RTCBVH object is no longer used.

The RTCCreateNodeFunc callback additionally gets the number of children for this node in the range from 2 to maxBranchingFactor (childCount argument).

The RTCSetNodeChildFunc callback function gets a pointer to the node as input (nodePtr argument), an array of pointers to the children (childPtrs argument), and the size of this array (childCount argument).

The RTCSetNodeBoundsFunc callback function gets a pointer to the node as input (nodePtr argument), an array of pointers to the bounding boxes of the children (bounds argument), and the size of this array (childCount argument).

The RTCCreateLeafFunc callback additionally gets an array of primitives as input (primitives argument), and the size of this array (primitiveCount argument). The callback should read the geomID and primID members from the passed primitives to construct the leaf.

The RTCSplitPrimitiveFunc callback is invoked in high quality mode to split a primitive (primitive argument) at the specified position (position argument) and dimension (dimension argument). The callback should return bounds of the clipped left and right parts of the primitive (leftBounds and rightBounds arguments).

The RTCProgressMonitorFunction callback function is called with the estimated completion rate n in the range [0, 1]. Returning true from the callback lets the build continue; returning false cancels the build.

EXIT STATUS

On failure an error code is set that can be queried using rtcDeviceGetError.

SEE ALSO

rtcNewBVH

Performance Recommendations

MXCSR control and status register

It is strongly recommended to have the Flush to Zero and Denormals are Zero mode of the MXCSR control and status register enabled for each thread before calling the rtcIntersect-type and rtcOccluded-type functions. Otherwise, under some circumstances special handling of denormalized floating point numbers can significantly reduce application and Embree performance. When using Embree together with the Intel® Threading Building Blocks, it is sufficient to execute the following code at the beginning of the application main thread (before the creation of the tbb::task_scheduler_init object):

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

If using a different tasking system, make sure each rendering thread has the proper mode set.

Thread Creation and Affinity Settings

Tasking systems like TBB create worker threads on demand, which will add a runtime overhead for the very first rtcCommitScene call. In case you want to benchmark the scene build time, you should start the threads at application startup. You can let Embree start TBB threads by passing start_threads=1 to the cfg parameter of rtcNewDevice.

On machines with a high thread count (e.g. dual-socket Xeon or Xeon Phi machines), affinitizing TBB worker threads increases build and rendering performance. You can let Embree affinitize TBB worker threads by passing set_affinity=1 to the cfg parameter of rtcNewDevice. By default, threads are not affinitized by Embree with the exception of Xeon Phi Processors where they are affinitized by default.

All Embree tutorials automatically start and affinitize TBB worker threads by passing start_threads=1,set_affinity=1 to rtcNewDevice.

Fast Coherent Rays

For getting the highest performance for highly coherent rays, e.g. primary or hard shadow rays, it is recommended to use packets or streams of single rays/packets with setting the RTC_INTERSECT_CONTEXT_FLAG_COHERENT flag in the RTCIntersectContext passed to the rtcIntersect/rtcOccluded calls. The total number of rays in a coherent stream of ray packets should be around 64, e.g. 8 times 8-wide packets, or 4 times 16-wide packets. The rays inside each packet should be grouped as coherent as possible.

Huge Page Support

It is recommended to use huge pages under Linux to increase rendering performance. Embree supports 2MB huge pages under Windows, Linux, and macOS. Under Linux huge page support is enabled by default, and under Windows and macOS disabled by default. Huge page support can be enabled in Embree by passing hugepages=1 to rtcNewDevice or disabled by passing hugepages=0 to rtcNewDevice.

We recommend using 2MB huge pages with Embree under Linux as this improves ray tracing performance by about 5-10%. Under Windows using huge pages requires the application to run in elevated mode which is a security issue, thus likely not an option for most use cases. Under macOS huge pages are rarely available as memory tends to get quickly fragmented, thus we do not recommend using huge pages on macOS.

Huge Pages under Linux

Linux supports transparent huge pages and explicit huge pages. To enable transparent huge page support under Linux, execute the following as root:

echo always > /sys/kernel/mm/transparent_hugepage/enabled

When transparent huge pages are enabled, the kernel tries to merge 4KB pages to 2MB pages when possible as a background job. Many Linux distributions have transparent huge pages enabled by default. See the following webpage for more information on transparent huge pages under Linux. In this mode each application, including your rendering application based on Embree, will automatically tend to use huge pages.

Using transparent huge pages, the transitioning from 4KB to 2MB pages might take some time. For that reason Embree also supports allocating 2MB pages directly when a huge page pool is configured. Such a pool can be configured by writing some number of huge pages to allocate to /proc/sys/vm/nr_overcommit_hugepages as root user. E.g. to configure 2GB of address space for huge page allocation, execute the following as root:

echo 1000 > /proc/sys/vm/nr_overcommit_hugepages

See the following webpage for more information on huge pages under Linux.

Huge Pages under Windows

To use huge pages under Windows, the current user must have the “Lock pages in memory” (SeLockMemoryPrivilege) assigned. This can be configured through the “Local Security Policy” application, by adding a user to “Local Policies” -> “User Rights Assignment” -> “Lock pages in memory”. You have to log out and in again for this change to take effect.

Further, your application must be executed as an elevated process (“Run as administrator”) and the “SeLockMemoryPrivilege” must be explicitly enabled by your application. Example code on how to enable this privilege can be found in the “common/sys/alloc.cpp” file of Embree. Alternatively, Embree will try to enable this privilege when passing enable_selockmemoryprivilege=1 to rtcNewDevice. Further, huge pages should be enabled in Embree by passing hugepages=1 to rtcNewDevice.

When the system has been running for a while, physical memory gets fragmented, which can slow down the allocation of huge pages significantly under Windows.

Huge Pages under macOS

To use huge pages under macOS you have to pass hugepages=1 to rtcNewDevice to enable that feature in Embree.

When the system has been running for a while, physical memory gets quickly fragmented, and causes huge page allocations to fail. For this reason, huge pages are not very useful under macOS in practice.

Avoid store-to-load forwarding issues with single rays

We recommend to use a single SSE store to set up the org and tnear components, and a single SSE store to set up the dir and time components of a single ray (RTCRay type). Storing these values using scalar stores causes a store-to-load forwarding penalty because Embree is reading these components using SSE loads later on.