{"id":13574625,"url":"https://github.com/RenderKit/ospray","last_synced_at":"2025-04-04T15:31:36.522Z","repository":{"id":37514435,"uuid":"10827518","full_name":"RenderKit/ospray","owner":"RenderKit","description":"An Open, Scalable, Portable, Ray Tracing Based Rendering Engine for High-Fidelity Visualization","archived":false,"fork":false,"pushed_at":"2025-01-08T16:07:29.000Z","size":32498,"stargazers_count":1043,"open_issues_count":55,"forks_count":188,"subscribers_count":67,"default_branch":"devel","last_synced_at":"2025-03-29T18:02:11.738Z","etag":null,"topics":["c-plus-plus","ospray","path-tracer","ray-tracing","rendering","visualization"],"latest_commit_sha":null,"homepage":"http://ospray.org","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RenderKit.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-06-20T19:16:51.000Z","updated_at":"2025-03-25T09:55:53.000Z","dependencies_parsed_at":"2024-09-20T16:51:37.902Z","dependency_job_id":"c7b85e82-1748-4268-81b0-6612dad7be08","html_url":"https://github.com/RenderKit/ospray","commit_stats":{"total_commits":8253,"total_committers":95,"mean_commits":86.87368421052632,"dds":0.6824185144795831,"last_synced_commit":"66fa8108485a8a92ff31ad2e06081bbaf391bc26"},"previous_names":["renderkit/ospray","ospray/ospray"],"tags_count":67,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RenderKit%2Fospray","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RenderKit%2Fospray/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RenderKit%2Fospray/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RenderKit%2Fospray/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RenderKit","download_url":"https://codeload.github.com/RenderKit/ospray/tar.gz/refs/heads/devel","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247202830,"owners_count":20900847,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c-plus-plus","ospray","path-tracer","ray-tracing","rendering","visualization"],"created_at":"2024-08-01T15:00:53.129Z","updated_at":"2025-04-04T15:31:31.512Z","avatar_url":"https://github.com/RenderKit.png","language":"C++","funding_links":[],"categories":["Table of Contents"],"sub_categories":["Data Visualization and Rendering"],"readme":"OSPRay\n======\n\nThis is release v3.3.0 (devel) of Intel® OSPRay. For changes and new\nfeatures see the [changelog](CHANGELOG.md). Visit http://www.ospray.org\nfor more information.\n\nOSPRay Overview\n===============\n\nIntel® OSPRay is an **o**pen source, **s**calable, and **p**ortable\n**ray** tracing engine for high-performance, high-fidelity visualization\non Intel Architecture CPUs, Intel Xe GPUs, and Aarch64/ARM64 CPUs.\nOSPRay is part of the [Intel Rendering Toolkit (Render\nKit)](https://software.intel.com/en-us/rendering-framework) and is\nreleased under the permissive [Apache 2.0\nlicense](http://www.apache.org/licenses/LICENSE-2.0).\n\nThe purpose of OSPRay is to provide an open, powerful, and easy-to-use\nrendering library that allows one to easily build applications that use\nray tracing based rendering for interactive applications (including both\nsurface- and volume-based visualizations). OSPRay runs on anything from\nlaptops, to workstations, to compute nodes in HPC systems.\n\nOSPRay internally builds on top of Intel\n[Embree](https://www.embree.org/), Intel [Open\nVKL](https://www.openvkl.org/), and Intel [Open Image\nDenoise](https://www.openimagedenoise.org/). The CPU implementation is\nbased on Intel [ISPC (Implicit SPMD Program\nCompiler)](https://ispc.github.io/) and fully exploits modern\ninstruction sets like Intel SSE4, AVX, AVX2, AVX-512 and NEON to achieve\nhigh rendering performance. Hence, a CPU with support for at least\nSSE4.1 is required to run OSPRay on x86_64 architectures, or a CPU with\nsupport for NEON is required to run OSPRay on ARM64 architectures.\n\nOSPRay’s GPU implementation (beta status) is based on the\n[SYCL](https://www.khronos.org/sycl/) cross-platform programming\nlanguage implemented by [Intel oneAPI Data Parallel C++\n(DPC++)](https://www.intel.com/content/www/us/en/developer/tools/oneapi/data-parallel-c-plus-plus.html)\nand currently supports Intel Arc™ GPUs on Linux and Windows, and Intel\nData Center GPU Flex and Max Series on Linux, exploiting ray tracing\nhardware support.\n\nOSPRay Support and Contact\n--------------------------\n\nOSPRay is under active development, and though we do our best to\nguarantee stable release versions a certain number of bugs,\nas-yet-missing features, inconsistencies, or any other issues are still\npossible. For any such requests or findings please use [OSPRay’s GitHub\nIssue Tracker](https://github.com/RenderKit/OSPRay/issues) (or, if you\nshould happen to have a fix for it, you can also send us a pull\nrequest).\n\nTo receive release announcements simply [“Watch” the OSPRay\nrepository](https://github.com/RenderKit/OSPRay) on GitHub.\n\nBuilding and Finding OSPRay\n===========================\n\nThe latest OSPRay sources are always available at the [OSPRay GitHub\nrepository](http://github.com/RenderKit/ospray). The default `master`\nbranch should always point to the latest bugfix release.\n\nPrerequisites\n-------------\n\nOSPRay currently supports Linux, Mac OS X, and Windows. In addition,\nbefore you can build OSPRay you need the following prerequisites:\n\n- You can clone the latest OSPRay sources via:\n\n  ``` sh\n  git clone https://github.com/RenderKit/ospray.git\n  ```\n\n- To build OSPRay you need [CMake](http://www.cmake.org), any form of\n  C++11 compiler (we recommend using GCC, but also support Clang, MSVC,\n  and [Intel® C++ Compiler\n  (icc)](https://software.intel.com/en-us/c-compilers)), and standard\n  Linux development tools.\n\n- Additionally you require a copy of the [Intel® Implicit SPMD Program\n  Compiler (ISPC)](http://ispc.github.io), version 1.23.0 or later.\n  Please obtain a release of ISPC from the [ISPC downloads\n  page](https://ispc.github.io/downloads.html). If ISPC is not found by\n  CMake its location can be hinted with the variable `ISPC_EXECUTABLE`.\n\n- OSPRay builds on top of the [Intel Rendering Toolkit (Render Kit)\n  common library (rkcommon)](https://www.github.com/RenderKit/rkcommon).\n  The library provides abstractions for tasking, aligned memory\n  allocation, vector math types, among others. For users who also need\n  to build rkcommon, we recommend the default the Intel [Threading\n  Building Blocks (TBB)](https://www.threadingbuildingblocks.org/) as\n  tasking system for performance and flexibility reasons. TBB must be\n  built from source when targeting ARM CPUs, or can be built from source\n  as part of the [superbuild](#cmake-superbuild). Alternatively you can\n  set CMake variable `RKCOMMON_TASKING_SYSTEM` to `OpenMP` or\n  `Internal`.\n\n- OSPRay also heavily uses Intel [Embree](https://www.embree.org/),\n  installing version 4.3.3 or newer is required. If Embree is not found\n  by CMake its location can be hinted with the variable `embree_DIR`.\n\n- OSPRay supports volume rendering (enabled by default via\n  `OSPRAY_ENABLE_VOLUMES`), which heavily uses Intel [Open\n  VKL](https://www.openvkl.org/), version 2.0.1 or newer is required. If\n  Open VKL is not found by CMake its location can be hinted with the\n  variable `openvkl_DIR`, or disable `OSPRAY_ENABLE_VOLUMES`.\n\n- OSPRay also provides an optional module implementing the `denoiser`\n  image operation, which is enabled by `OSPRAY_MODULE_DENOISER`. This\n  module requires Intel [Open Image\n  Denoise](https://www.openimagedenoise.org/) in version 2.3.0 or newer.\n  You may need to hint the location of the library with the CMake\n  variable `OpenImageDenoise_DIR`.\n\n- For the optional MPI modules (enabled by `OSPRAY_MODULE_MPI`), which\n  provide the `mpiOffload` and `mpiDistributed` devices, you need an MPI\n  library and [Google Snappy](https://github.com/google/snappy).\n\n- The optional example application, the test suit and benchmarks need\n  some version of OpenGL and GLFW as well as\n  [GoogleTest](https://github.com/google/googletest) and [Google\n  Benchmark](https://github.com/google/benchmark/)\n\nDepending on your Linux distribution you can install these dependencies\nusing `yum` or `apt-get`. Some of these packages might already be\ninstalled or might have slightly different names.\n\nType the following to install the dependencies using `yum`:\n\n``` sh\nsudo yum install cmake.x86_64\nsudo yum install tbb.x86_64 tbb-devel.x86_64\n```\n\nType the following to install the dependencies using `apt-get`:\n\n``` sh\nsudo apt-get install cmake-curses-gui\nsudo apt-get install libtbb-dev\n```\n\nUnder Mac OS X these dependencies can be installed using\n[MacPorts](http://www.macports.org/):\n\n``` sh\nsudo port install cmake tbb\n```\n\nUnder Windows please directly use the appropriate installers for\n[CMake](https://cmake.org/download/),\n[TBB](https://github.com/oneapi-src/oneTBB/releases),\n[ISPC](https://ispc.github.io/downloads.html) (for your Visual Studio\nversion) and [Embree](https://github.com/RenderKit/embree/releases/).\n\n### Additional Prerequisites for GPU Build\n\nTo build OSPRay’s GPU module you need\n\n- a SYCL compiler, either the open source [oneAPI DPC++ Compiler\n  2023-10-26](https://github.com/intel/llvm/releases/tag/nightly-2023-10-26)\n  or the latest [Intel oneAPI DPC++/C++\n  Compiler](https://www.intel.com/content/www/us/en/developer/articles/tool/oneapi-standalone-components.html#dpcpp-cpp)\n- a recent [CMake](http://www.cmake.org), version 3.25.3 or higher\n\nCMake Superbuild\n----------------\n\nFor convenience, OSPRay provides a CMake Superbuild script which will\npull down OSPRay’s dependencies and build OSPRay itself. By default, the\nresult is an install directory, with each dependency in its own\ndirectory.\n\nRun with:\n\n``` sh\nmkdir build\ncd build\ncmake [\u003cOSPRAY_SOURCE_DIR\u003e/scripts/superbuild]\ncmake --build .\n```\n\nOn Windows make sure to select a 64 bit generator, e.g.\n\n``` sh\ncmake -G \"Visual Studio 17 2022\" [\u003cOSPRAY_SOURCE_DIR\u003e/scripts/superbuild]\n```\n\nThe resulting `install` directory (or the one set with\n`CMAKE_INSTALL_PREFIX`) will have everything in it, with one\nsubdirectory per dependency.\n\nCMake options to note (all have sensible defaults):\n\nCMAKE_INSTALL_PREFIX  \nwill be the root directory where everything gets installed.\n\nBUILD_JOBS  \nsets the number given to `make -j` for parallel builds.\n\nINSTALL_IN_SEPARATE_DIRECTORIES  \ntoggles installation of all libraries in separate or the same directory.\n\nBUILD_OPENVKL  \nwhether to enable volume rendering via Open VKL\n\nBUILD_EMBREE_FROM_SOURCE  \nset to OFF will download a pre-built version of Embree.\n\nBUILD_OIDN_FROM_SOURCE  \nset to OFF will download a pre-built version of Open Image Denoise.\n\nOIDN_VERSION  \ndetermines which version of Open Image Denoise to pull down.\n\nBUILD_OSPRAY_MODULE_MPI  \nset to ON to build OSPRay’s MPI module for data-replicated and\ndistributed parallel rendering on multiple nodes.\n\nBUILD_GPU_SUPPORT  \nenables beta GPU support, fetching the SYCL variants of the dependencies\nand builds `OSPRAY_MODULE_GPU`\n\nBUILD_TBB_FROM_SOURCE  \nset to ON to build TBB from source (required for ARM support). The\ndefault setting is OFF.\n\nFor the full set of options, run:\n\n``` sh\nccmake [\u003cOSPRAY_SOURCE_DIR\u003e/scripts/superbuild]\n```\n\nor\n\n``` sh\ncmake-gui [\u003cOSPRAY_SOURCE_DIR\u003e/scripts/superbuild]\n```\n\n### Cross-Compilation with the Superbuild\n\nThe superbuild can be passed a [CMake Toolchain\nfile](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html)\nto configure for cross-compilation. This is done by passing the\ntoolchain file when running cmake. When cross compiling it is also\nlikely that you’ll want to build TBB and Embree from source to ensure\nthey’re built for the correct target, rather than the target the Github\nbinaries are built for. It may also be necessary to disable specific\nISAs for the target by passing `BUILD_ISA_\u003cISA_NAME\u003e=OFF` as well.\n\n``` sh\nmkdir build\ncd build\ncmake --toolchain [toolchain_file.cmake] [path/to/this/directory]\n    -DBUILD_TBB_FROM_SOURCE=ON \\\n    -DBUILD_EMBREE_FROM_SOURCE=ON \\\n    \u003cother arguments\u003e\n```\n\nWhile OSPRay supports ARM natively, it may be desirable to cross-compile\nit for `x86_64` to run in Rosetta depending on the application\nintegrating OSPRay. This can be done using the toolchain file\n`toolchains/macos-rosetta.cmake`, and by disabling all non-SSE ISAs when\nbuilding. This can also be done by launching an `x86_64` bash shell and\nthen compiling as usual in this environment, which will cause the\ncompilation chain to target `x86_64`. The `BUILD_ISA_\u003cISA NAME\u003e=OFF`\nflags should be passed to disable all ISAs besides SSE4 for Rosetta:\n\n``` sh\narch -x86_64 bash\nmkdir build\ncd build\ncmake [path/to/this/directory]\n    -DBUILD_TBB_FROM_SOURCE=ON \\\n    -DBUILD_EMBREE_FROM_SOURCE=ON \\\n    -DBUILD_ISA_AVX=OFF \\\n    -DBUILD_ISA_AVX2=OFF \\\n    -DBUILD_ISA_AVX512=OFF \\\n    \u003cother arguments\u003e\n```\n\nStandard CMake Build\n--------------------\n\n### Compiling OSPRay on Linux and Mac OS X\n\nAssuming the above requisites are all fulfilled, building OSPRay through\nCMake is easy:\n\n- Create a build directory, and go into it\n\n  ``` sh\n  mkdir ospray/build\n  cd ospray/build\n  ```\n\n  (We do recommend having separate build directories for different\n  configurations such as release, debug, etc.).\n\n- The compiler CMake will use will default to whatever the `CC` and\n  `CXX` environment variables point to. Should you want to specify a\n  different compiler, run cmake manually while specifying the desired\n  compiler. The default compiler on most linux machines is `gcc`, but it\n  can be pointed to `clang` instead by executing the following:\n\n  ``` sh\n  cmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang ..\n  ```\n\n  CMake will now use Clang instead of GCC. If you are OK with using the\n  default compiler on your system, then simply skip this step. Note that\n  the compiler variables cannot be changed after the first `cmake` or\n  `ccmake` run.\n\n- Open the CMake configuration dialog\n\n  ``` sh\n  ccmake ..\n  ```\n\n- Make sure to properly set build mode and enable the components you\n  need, etc.; then type ’c’onfigure and ’g’enerate. When back on the\n  command prompt, build it using\n\n  ``` sh\n  make\n  ```\n\n- You should now have `libospray.[so,dylib]` as well as a set of\n  [example applications](#tutorials).\n\n### Compiling OSPRay on Windows\n\nOn Windows using the CMake GUI (`cmake-gui.exe`) is the most convenient\nway to configure OSPRay and to create the Visual Studio solution files:\n\n- Browse to the OSPRay sources and specify a build directory (if it does\n  not exist yet CMake will create it).\n\n- Click “Configure” and select as generator the Visual Studio version\n  you have; OSPRay needs “Visual Studio 15 2017 Win64” or newer, 32  \n  bit builds are not supported, e.g., “Visual Studio 17 2022”.\n\n- If the configuration fails because some dependencies could not be\n  found then follow the instructions given in the error message, e.g.,\n  set the variable `embree_DIR` to the folder where Embree was installed\n  and `openvkl_DIR` to where Open VKL was installed.\n\n- Optionally change the default build options, and then click “Generate”\n  to create the solution and project files in the build directory.\n\n- Open the generated `OSPRay.sln` in Visual Studio, select the build\n  configuration and compile the project.\n\nAlternatively, OSPRay can also be built without any GUI, entirely on the\nconsole. In the Visual Studio command prompt type:\n\n``` sh\ncd path\\to\\ospray\nmkdir build\ncd build\ncmake -G \"Visual Studio 17 2022\" [-D VARIABLE=value] ..\ncmake --build . --config Release\n```\n\nUse `-D` to set variables for CMake, e.g., the path to Embree with\n“`-D embree_DIR=\\path\\to\\embree`”.\n\nYou can also build only some projects with the `--target` switch.\nAdditional parameters after “`--`” will be passed to `msbuild`. For\nexample, to build in parallel only the OSPRay library without the\nexample applications use\n\n``` sh\ncmake --build . --config Release --target ospray -- /m\n```\n\nFinding an OSPRay Install with CMake\n------------------------------------\n\nClient applications using OSPRay can find it with CMake’s\n`find_package()` command. For example,\n\n``` sh\nfind_package(ospray 3.0.0 REQUIRED)\n```\n\nfinds OSPRay via OSPRay’s configuration file `osprayConfig.cmake`[^1].\nOnce found, the following is all that is required to use OSPRay:\n\n``` sh\ntarget_link_libraries(${client_target} ospray::ospray)\n```\n\nThis will automatically propagate all required include paths, linked\nlibraries, and compiler definitions to the client CMake target (either\nan executable or library).\n\nAdvanced users may want to link to additional targets which are exported\nin OSPRay’s CMake config, which includes all installed modules. All\ntargets built with OSPRay are exported in the `ospray::` namespace,\ntherefore all targets locally used in the OSPRay source tree can be\naccessed from an install. For example, `ospray_module_cpu` can be\nconsumed directly via the `ospray::ospray_module_cpu` target. All\ntargets have their libraries, includes, and definitions attached to them\nfor public consumption (please [report\nbugs](#ospray-support-and-contact) if this is broken!).\n\nDocumentation\n=============\n\nThe following [API\ndocumentation](https://www.ospray.org/OSPRay_readme_devel.pdf \"OSPRay Documentation\")\nof OSPRay can also be found as a [pdf\ndocument](https://www.ospray.org/OSPRay_readme_devel.pdf \"OSPRay Documentation\").\n\nFor a deeper explanation of the concepts, design, features and\nperformance of OSPRay also have a look at the IEEE Vis 2016 paper\n“[OSPRay – A CPU Ray Tracing Framework for Scientific\nVisualization](https://www.ospray.org/talks/IEEEVis2016_OSPRay_paper.pdf)”\n(49MB, or get the [smaller\nversion](https://www.ospray.org/talks/IEEEVis2016_OSPRay_paper_small.pdf)\n1.8MB). The [slides of the\ntalk](https://www.ospray.org/talks/IEEEVis2016_OSPRay_talk.pdf) (5.2MB)\nare also available.\n\nOSPRay API\n==========\n\nTo access the OSPRay API you first need to include the OSPRay header\n\n``` cpp\n#include \"ospray/ospray.h\"\n```\n\nwhere the API is compatible with C99 and C++.\n\nInitialization and Shutdown\n---------------------------\n\nTo use the API, OSPRay must be initialized with a “device”. A device is\nthe object which implements the API. Creating and initializing a device\ncan be done in either of two ways: command line arguments using\n`ospInit` or manually instantiating a device and setting parameters on\nit.\n\n### Command Line Arguments\n\nThe first is to do so by giving OSPRay the command line from `main()` by\ncalling\n\n``` cpp\nOSPError ospInit(int *argc, const char **argv);\n```\n\nOSPRay parses (and removes) its known command line parameters from your\napplication’s `main` function. For an example see the\n[tutorial](#osptutorial). For possible error codes see section [Error\nHandling and Status Messages](#error-handling-and-status-messages). It\nis important to note that the arguments passed to `ospInit` are\nprocessed in order they are listed. The following parameters (which are\nprefixed by convention with “`--osp:`”) are understood:\n\n| Parameter                                   | Description                                                                                                                                                                                                                  |\n|:--------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `--osp:debug`                               | enables various extra checks and debug output, and disables multi-threading                                                                                                                                                  |\n| `--osp:num-threads=\u003cn\u003e`                     | use `n` threads instead of per default using all detected hardware threads                                                                                                                                                   |\n| `--osp:log-level=\u003cstr\u003e`                     | set logging level; valid values (in order of severity) are `none`, `error`, `warning`, `info`, and `debug`                                                                                                                   |\n| `--osp:warn-as-error`                       | send `warning` and `error` messages through the error callback, otherwise send `warning` messages through the message callback; must have sufficient `logLevel` to enable warnings                                           |\n| `--osp:verbose`                             | shortcut for `--osp:log-level=info` and enable debug output on `cout`, error output on `cerr`                                                                                                                                |\n| `--osp:vv`                                  | shortcut for `--osp:log-level=debug` and enable debug output on `cout`, error output on `cerr`                                                                                                                               |\n| `--osp:load-modules=\u003cname\u003e[,...]`           | load one or more modules during initialization; equivalent to calling `ospLoadModule(name)`                                                                                                                                  |\n| `--osp:log-output=\u003cdst\u003e`                    | convenience for setting where status messages go; valid values for `dst` are `cerr` and `cout`                                                                                                                               |\n| `--osp:error-output=\u003cdst\u003e`                  | convenience for setting where error messages go; valid values for `dst` are `cerr` and `cout`                                                                                                                                |\n| `--osp:device=\u003cname\u003e`                       | use `name` as the type of device for OSPRay to create; e.g., `--osp:device=cpu` gives you the default `cpu` device; Note if the device to be used is defined in a module, remember to pass `--osp:load-modules=\u003cname\u003e` first |\n| `--osp:set-affinity=\u003cn\u003e`                    | if `1`, bind software threads to hardware threads; `0` disables binding; default is `0`                                                                                                                                      |\n| `--osp:device-params=\u003cparam\u003e:\u003cvalue\u003e[,...]` | set one or more other device parameters; equivalent to calling `ospDeviceSet*(param, value)`                                                                                                                                 |\n\nCommand line parameters accepted by OSPRay’s `ospInit`.\n\n### Manual Device Instantiation\n\nThe second method of initialization is to explicitly create the device\nand possibly set parameters. This method looks almost identical to how\nother [objects](#objects) are created and used by OSPRay (described in\nlater sections). The first step is to create the device with\n\n``` cpp\nOSPDevice ospNewDevice(const char *type);\n```\n\nwhere the `type` string maps to a specific device implementation. OSPRay\nalways provides the “`cpu`” device, which maps to a fast, local CPU\nimplementation. Other devices can also be added through additional\nmodules, such as distributed MPI device implementations. See next\nChapter for details.\n\nOnce a device is created, you can call\n\n``` cpp\nvoid ospDeviceSetParam(OSPObject, const char *id, OSPDataType type, const void *mem);\n```\n\nto set parameters on the device. The semantics of setting parameters is\nexactly the same as `ospSetParam`, which is documented below in the\n[parameters](#parameters) section. The following parameters can be set\non all devices:\n\n| Type   | Name                    | Description                                                                                                                                                                        |\n|:-------|:------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| int    | numThreads              | number of threads which OSPRay should use                                                                                                                                          |\n| bool   | disableMipMapGeneration | disable the default generation of MIP maps for textures (e.g., to save the additional memory needed)                                                                               |\n| uint   | logLevel                | logging level; valid values (in order of severity) are `OSP_LOG_NONE`, `OSP_LOG_ERROR`, `OSP_LOG_WARNING`, `OSP_LOG_INFO`, and `OSP_LOG_DEBUG`                                     |\n| string | logOutput               | convenience for setting where status messages go; valid values are `cerr` and `cout`                                                                                               |\n| string | errorOutput             | convenience for setting where error messages go; valid values are `cerr` and `cout`                                                                                                |\n| bool   | debug                   | set debug mode; equivalent to `logLevel=debug` and `numThreads=1`                                                                                                                  |\n| bool   | warnAsError             | send `warning` and `error` messages through the error callback, otherwise send `warning` messages through the message callback; must have sufficient `logLevel` to enable warnings |\n| bool   | setAffinity             | bind software threads to hardware threads if set to 1; 0 disables binding omitting the parameter will let OSPRay choose                                                            |\n\nParameters shared by all devices.\n\nOnce parameters are set on the created device, the device must be\ncommitted with\n\n``` cpp\nvoid ospDeviceCommit(OSPDevice);\n```\n\nTo use the newly committed device, you must call\n\n``` cpp\nvoid ospSetCurrentDevice(OSPDevice);\n```\n\nThis then sets the given device as the object which will respond to all\nother OSPRay API calls.\n\nDevice handle lifetimes are managed with two calls, the first which\nincrements the internal reference count to the given `OSPDevice`\n\n``` cpp\nvoid ospDeviceRetain(OSPDevice)\n```\n\nand the second which decrements the reference count\n\n``` cpp\nvoid ospDeviceRelease(OSPDevice)\n```\n\nUsers can change parameters on the device after initialization (from\neither method above), by calling\n\n``` cpp\nOSPDevice ospGetCurrentDevice();\n```\n\nThis function returns the handle to the device currently used to respond\nto OSPRay API calls, where users can set/change parameters and recommit\nthe device. If changes are made to the device that is already set as the\ncurrent device, it does not need to be set as current again. Note this\nAPI call will increment the ref count of the returned device handle, so\napplications must use `ospDeviceRelease` when finished using the handle\nto avoid leaking the underlying device object. If there is no current\ndevice set, this will return an invalid `NULL` handle.\n\nWhen a device is created, its reference count is initially `1`. When a\ndevice is set as the current device, it internally has its reference\ncount incremented. Note that `ospDeviceRetain` and `ospDeviceRelease`\nshould only be used with reference counts that the application tracks:\nremoving reference held by the current set device should be handled by\n`ospShutdown`. Thus, `ospDeviceRelease` should only decrement the\nreference counts that come from `ospNewDevice`, `ospGetCurrentDevice`,\nand the number of explicit calls to `ospDeviceRetain`.\n\nOSPRay allows applications to query runtime properties of a device in\norder to do enhanced validation of what device was loaded at runtime.\nThe following function can be used to get these device-specific\nproperties (attributes about the device, not parameter values)\n\n``` cpp\nint64_t ospDeviceGetProperty(OSPDevice, OSPDeviceProperty);\n```\n\nIt returns an integer value of the queried property and the following\nproperties can be provided as parameter:\n\n``` cpp\nOSP_DEVICE_VERSION\nOSP_DEVICE_VERSION_MAJOR\nOSP_DEVICE_VERSION_MINOR\nOSP_DEVICE_VERSION_PATCH\nOSP_DEVICE_SO_VERSION\n```\n\n### Environment Variables\n\nOSPRay’s generic device parameters can be overridden via environment\nvariables for easy changes to OSPRay’s behavior without needing to\nchange the application (variables are prefixed by convention with\n“`OSPRAY_`”):\n\n| Variable             | Description                                                                                                |\n|:---------------------|:-----------------------------------------------------------------------------------------------------------|\n| OSPRAY_NUM_THREADS   | equivalent to `--osp:num-threads`                                                                          |\n| OSPRAY_LOG_LEVEL     | equivalent to `--osp:log-level`                                                                            |\n| OSPRAY_LOG_OUTPUT    | equivalent to `--osp:log-output`                                                                           |\n| OSPRAY_ERROR_OUTPUT  | equivalent to `--osp:error-output`                                                                         |\n| OSPRAY_DEBUG         | equivalent to `--osp:debug`                                                                                |\n| OSPRAY_WARN_AS_ERROR | equivalent to `--osp:warn-as-error`                                                                        |\n| OSPRAY_SET_AFFINITY  | equivalent to `--osp:set-affinity`                                                                         |\n| OSPRAY_LOAD_MODULES  | equivalent to `--osp:load-modules`, can be a comma separated list of modules which will be loaded in order |\n| OSPRAY_DEVICE        | equivalent to `--osp:device:`                                                                              |\n\nEnvironment variables interpreted by OSPRay.\n\nNote that these environment variables take precedence over values\nspecified through `ospInit` or manually set device parameters.\n\n### Error Handling and Status Messages\n\nThe following errors are currently used by OSPRay:\n\n| Name                  | Description                                                                  |\n|:----------------------|:-----------------------------------------------------------------------------|\n| OSP_NO_ERROR          | no error occurred                                                            |\n| OSP_UNKNOWN_ERROR     | an unknown error occurred                                                    |\n| OSP_INVALID_ARGUMENT  | an invalid argument was specified                                            |\n| OSP_INVALID_OPERATION | the operation is not allowed for the specified object                        |\n| OSP_OUT_OF_MEMORY     | there is not enough memory to execute the command                            |\n| OSP_UNSUPPORTED_CPU   | the CPU is not supported (minimum ISA is SSE4.1 on x86_64 and NEON on ARM64) |\n| OSP_VERSION_MISMATCH  | a module could not be loaded due to mismatching version                      |\n\nPossible error codes, i.e., valid named constants of type `OSPError`.\n\nThese error codes are either directly return by some API functions, or\nare recorded to be later queried by the application via\n\n``` cpp\nOSPError ospDeviceGetLastErrorCode(OSPDevice);\n```\n\nA more descriptive error message can be queried by calling\n\n``` cpp\nconst char* ospDeviceGetLastErrorMsg(OSPDevice);\n```\n\nAlternatively, the application can also register a callback function of\ntype\n\n``` cpp\ntypedef void (*OSPErrorCallback)(void *userData, OSPError, const char* errorDetails);\n```\n\nvia\n\n``` cpp\nvoid ospDeviceSetErrorCallback(OSPDevice, OSPErrorCallback, void *userData);\n```\n\nto get notified when errors occur.\n\nApplications may be interested in messages which OSPRay emits, whether\nfor debugging or logging events. Applications can call\n\n``` cpp\nvoid ospDeviceSetStatusCallback(OSPDevice, OSPStatusCallback, void *userData);\n```\n\nin order to register a callback function of type\n\n``` cpp\ntypedef void (*OSPStatusCallback)(void *userData, const char* messageText);\n```\n\nwhich OSPRay will use to emit status messages. By default, OSPRay uses a\ncallback which does nothing, so any output desired by an application\nwill require that a callback is provided. Note that callbacks for C++\n`std::cout` and `std::cerr` can be alternatively set through `ospInit`\nor the `OSPRAY_LOG_OUTPUT` environment variable.\n\nApplications can clear either callback by passing `NULL` instead of an\nactual function pointer.\n\n### Loading OSPRay Extensions at Runtime\n\nOSPRay’s functionality can be extended via plugins (which we call\n“modules”), which are implemented in shared libraries. To load module\n`name` from `libospray_module_\u003cname\u003e.so` (on Linux and Mac OS X) or\n`ospray_module_\u003cname\u003e.dll` (on Windows) use\n\n``` cpp\nOSPError ospLoadModule(const char *name);\n```\n\nModules are searched in OS-dependent paths. `ospLoadModule` returns\n`OSP_NO_ERROR` if the plugin could be successfully loaded.\n\n### Shutting Down OSPRay\n\nWhen the application is finished using OSPRay (typically on application\nexit), the OSPRay API should be finalized with\n\n``` cpp\nvoid ospShutdown();\n```\n\nThis API call ensures that the current device is cleaned up\nappropriately. Due to static object allocation having non-deterministic\nordering, it is recommended that applications call `ospShutdown` before\nthe calling application process terminates.\n\nObjects\n-------\n\nAll entities of OSPRay (the [renderer](#renderers), [volumes](#volumes),\n[geometries](#geometries), [lights](#lights), [cameras](#cameras), …)\nare a logical specialization of `OSPObject` and share common mechanism\nto deal with parameters and lifetime.\n\nAn important aspect of object parameters is that parameters do not get\npassed to objects immediately. Instead, parameters are not visible at\nall to objects until they get explicitly committed to a given object via\na call to\n\n``` cpp\nvoid ospCommit(OSPObject);\n```\n\nat which time all previously additions or changes to parameters are\nvisible at the same time. If a user wants to change the state of an\nexisting object (e.g., to change the origin of an already existing\ncamera) it is perfectly valid to do so, as long as the changed\nparameters are recommitted.\n\nThe commit semantic allow for batching up multiple small changes, and\nspecifies exactly when changes to objects will occur. This can impact\nperformance and consistency for devices crossing a PCI bus or across a\nnetwork.\n\nNote that OSPRay uses reference counting to manage the lifetime of all\nobjects, so one cannot explicitly “delete” any object. Instead, to\nindicate that the application does not need and does not access the\ngiven object anymore, call\n\n``` cpp\nvoid ospRelease(OSPObject);\n```\n\nThis decreases its reference count and if the count reaches `0` the\nobject will automatically get deleted. Passing `NULL` is not an error.\nNote that every handle returned via the API needs to be released when\nthe object is no longer needed, to avoid memory leaks.\n\nSometimes applications may want to have more than one reference to an\nobject, where it is desirable for the application to increment the\nreference count of an object. This is done with\n\n``` cpp\nvoid ospRetain(OSPObject);\n```\n\nIt is important to note that this is only necessary if the application\nwants to call `ospRelease` on an object more than once: objects which\ncontain other objects as parameters internally increment/decrement ref\ncounts and should not be explicitly done by the application.\n\n### Parameters\n\nParameters allow to configure the behavior of and to pass data to\nobjects. However, objects do *not* have an explicit interface for\nreasons of high flexibility and a more stable compile-time API. Instead,\nparameters are passed separately to objects in an arbitrary order, and\nunknown parameters will simply be ignored (though a warning message will\nbe posted). The following function allows adding various types of\nparameters with name `id` to a given object:\n\n``` cpp\nvoid ospSetParam(OSPObject, const char *id, OSPDataType type, const void *mem);\n```\n\nThe valid parameter names for all `OSPObject`s and what types are valid\nare discussed in future sections.\n\nNote that `mem` must always be a pointer *to* the object, otherwise\naccidental type casting can occur. This is especially true for pointer\ntypes (`OSP_VOID_PTR` and `OSPObject` handles), as they will implicitly\ncast to `void *`, but be incorrectly interpreted. To help with some of\nthese issues, there also exist variants of `ospSetParam` for specific\ntypes, such as `ospSetInt` and `ospSetVec3f` in the OSPRay utility\nlibrary (found in `ospray_util.h`). Note that half precision float\nparameters `OSP_HALF, OSP_VEC[234]H` are not supported.\n\nUsers can also remove parameters that have been explicitly set from\n`ospSetParam`. Any parameters which have been removed will go back to\ntheir default value during the next commit unless a new parameter was\nset after the parameter was removed. To remove a parameter, use\n\n``` cpp\nvoid ospRemoveParam(OSPObject, const char *id);\n```\n\n### Data\n\nOSPRay consumes data arrays from the application using a specific object\ntype, `OSPData`. There are several components to describing a data\narray: element type, 1/2/3 dimensional striding, and whether the array\nis shared with the application or copied into opaque, OSPRay-owned\nmemory.\n\nShared data arrays require that the application’s array memory outlives\nthe lifetime of the created `OSPData`, as OSPRay is referring to\napplication memory. Where this is not preferable, applications use\nopaque arrays to allow the `OSPData` to own the lifetime of the array\nmemory. However, opaque arrays dictate the cost of copying data into it,\nwhich should be kept in mind.\n\nThus, the most efficient way to specify a data array from the\napplication is to created a shared data array, which is done with\n\n``` cpp\nOSPData ospNewSharedData(const void *sharedData,\n    OSPDataType,\n    uint64_t numItems1,\n    int64_t byteStride1 = 0,\n    uint64_t numItems2 = 1,\n    int64_t byteStride2 = 0,\n    uint64_t numItems3 = 1,\n    int64_t byteStride3 = 0,\n    OSPDeleterCallback = NULL,\n    void *userData = NULL);\n```\n\nThe call returns an `OSPData` handle to the created array. The calling\nprogram guarantees that the `sharedData` pointer will remain valid for\nthe duration that this data array is being used. The number of elements\n`numItems` must be positive (there cannot be an empty data object). The\ndata is arranged in three dimensions, with specializations to two or one\ndimension (if some `numItems` are 1). The distance between consecutive\nelements (per dimension) is given in bytes with `byteStride` and can\nalso be negative. If `byteStride` is zero it will be determined\nautomatically (e.g., as `sizeof(type)`). Strides do not need to be\nordered, i.e., `byteStride2` can be smaller than `byteStride1`, which is\nequivalent to a transpose. However, if the stride should be calculated,\nthen an ordering in dimensions is assumed to disambiguate, i.e.,\n`byteStride1 \u003c byteStride2 \u003c byteStride3`.\n\nAn application can pass ownership of shared data to OSPRay (for example,\nwhen it temporarily created a modified version of its data only to make\nit compatible with OSPRay) by providing a deleter function that OSPRay\nwill call whenever the time comes to deallocate the shared buffer. The\ndeleter function has the following signature:\n\n``` cpp\ntypedef void (*OSPDeleterCallback)(const void *userData, const void *sharedData);\n```\n\nwhere `sharedData` will receive the address of the buffer and `userData`\nwill receive whatever additional state the function needs to perform the\ndeletion (both provided to `ospNewSharedData` when sharing the data with\nOSPRay).\n\nThe enum type `OSPDataType` describes the different element types that\ncan be represented in OSPRay; valid constants are listed in the table\nbelow.\n\n| Type / Name                  | Description                                                                                  |\n|:-----------------------------|:---------------------------------------------------------------------------------------------|\n| OSP_DEVICE                   | API device object reference                                                                  |\n| OSP_DATA                     | data reference                                                                               |\n| OSP_OBJECT                   | generic object reference                                                                     |\n| OSP_CAMERA                   | camera object reference                                                                      |\n| OSP_FRAMEBUFFER              | framebuffer object reference                                                                 |\n| OSP_FUTURE                   | future object reference                                                                      |\n| OSP_LIGHT                    | light object reference                                                                       |\n| OSP_MATERIAL                 | material object reference                                                                    |\n| OSP_TEXTURE                  | texture object reference                                                                     |\n| OSP_RENDERER                 | renderer object reference                                                                    |\n| OSP_WORLD                    | world object reference                                                                       |\n| OSP_GROUP                    | group object reference                                                                       |\n| OSP_INSTANCE                 | instance object reference                                                                    |\n| OSP_GEOMETRY                 | geometry object reference                                                                    |\n| OSP_GEOMETRIC_MODEL          | geometric model object reference                                                             |\n| OSP_VOLUME                   | volume object reference                                                                      |\n| OSP_VOLUMETRIC_MODEL         | volumetric model object reference                                                            |\n| OSP_TRANSFER_FUNCTION        | transfer function object reference                                                           |\n| OSP_IMAGE_OPERATION          | image operation object reference                                                             |\n| OSP_STRING                   | C-style zero-terminated character string                                                     |\n| OSP_BOOL                     | 8 bit boolean                                                                                |\n| OSP_CHAR, OSP_VEC\\[234\\]C    | 8 bit signed character scalar and \\[234\\]-element vector                                     |\n| OSP_UCHAR, OSP_VEC\\[234\\]UC  | 8 bit unsigned character scalar and \\[234\\]-element vector                                   |\n| OSP_SHORT, OSP_VEC\\[234\\]S   | 16 bit unsigned integer scalar and \\[234\\]-element vector                                    |\n| OSP_USHORT, OSP_VEC\\[234\\]US | 16 bit unsigned integer scalar and \\[234\\]-element vector                                    |\n| OSP_INT, OSP_VEC\\[234\\]I     | 32 bit signed integer scalar and \\[234\\]-element vector                                      |\n| OSP_UINT, OSP_VEC\\[234\\]UI   | 32 bit unsigned integer scalar and \\[234\\]-element vector                                    |\n| OSP_LONG, OSP_VEC\\[234\\]L    | 64 bit signed integer scalar and \\[234\\]-element vector                                      |\n| OSP_ULONG, OSP_VEC\\[234\\]UL  | 64 bit unsigned integer scalar and \\[234\\]-element vector                                    |\n| OSP_HALF, OSP_VEC\\[234\\]H    | 16 bit half precision floating-point scalar and \\[234\\]-element vector (IEEE 754 `binary16`) |\n| OSP_FLOAT, OSP_VEC\\[234\\]F   | 32 bit single precision floating-point scalar and \\[234\\]-element vector                     |\n| OSP_DOUBLE, OSP_VEC\\[234\\]D  | 64 bit double precision floating-point scalar and \\[234\\]-element vector                     |\n| OSP_BOX\\[1234\\]I             | 32 bit integer box (lower + upper bounds)                                                    |\n| OSP_BOX\\[1234\\]F             | 32 bit single precision floating-point box (lower + upper bounds)                            |\n| OSP_LINEAR\\[23\\]F            | 32 bit single precision floating-point linear transform (\\[23\\] vectors)                     |\n| OSP_AFFINE\\[23\\]F            | 32 bit single precision floating-point affine transform (linear transform plus translation)  |\n| OSP_QUATF                    | 32 bit single precision floating-point quaternion, in $(i, j, k, w)$ layout                  |\n| OSP_VOID_PTR                 | raw memory address (only found in module extensions)                                         |\n\nValid named constants for `OSPDataType`.\n\nIf the elements of the array are handles to objects, then their\nreference counter is incremented.\n\nAn opaque `OSPData` with memory allocated by OSPRay is created with\n\n``` cpp\nOSPData ospNewData(OSPDataType,\n    uint64_t numItems1,\n    uint64_t numItems2 = 1,\n    uint64_t numItems3 = 1);\n```\n\nTo allow for (partial) copies or updates of data arrays use\n\n``` cpp\nvoid ospCopyData(const OSPData source,\n    OSPData destination,\n    uint64_t destinationIndex1 = 0,\n    uint64_t destinationIndex2 = 0,\n    uint64_t destinationIndex3 = 0);\n```\n\nwhich will copy the whole[^2] content of the `source` array into\n`destination` at the given location `destinationIndex`. The\n`OSPDataType`s of the data objects must match. The region to be copied\nmust be valid inside the destination, i.e., in all dimensions,\n`destinationIndex + sourceSize \u003c= destinationSize`. The affected region\n`[destinationIndex, destinationIndex + sourceSize)` is marked as dirty,\nwhich may be used by OSPRay to only process or update that sub-region\n(e.g., updating an acceleration structure). If the destination array is\nshared with OSPData by the application (created with\n`ospNewSharedData`), then\n\n- the source array must be shared as well (thus `ospCopyData` cannot be\n  used to read opaque data)\n- if source and destination memory overlaps (aliasing), then behavior is\n  undefined\n- except if source and destination regions are identical (including\n  matching strides), which can be used by application to mark that\n  region as dirty (instead of the whole `OSPData`)\n\nTo add a data array as parameter named `id` to another object call also\nuse\n\n``` cpp\nvoid ospSetObject(OSPObject, const char *id, OSPData);\n```\n\nVolumes\n-------\n\nVolumes are volumetric data sets with discretely sampled values in 3D\nspace, typically a 3D scalar field. To create a new volume object of\ngiven type `type` use\n\n``` cpp\nOSPVolume ospNewVolume(const char *type);\n```\n\nNote that OSPRay’s implementation forwards `type` directly to Open VKL,\nallowing new Open VKL volume types to be usable within OSPRay without\nthe need to change (or even recompile) OSPRay.\n\n### Structured Regular Volume\n\nStructured volumes only need to store the values of the samples, because\ntheir addresses in memory can be easily computed from a 3D position. A\ncommon type of structured volumes are regular grids.\n\nStructured regular volumes are created by passing the type string\n“`structuredRegular`” to `ospNewVolume`. Structured volumes are\nrepresented through an `OSPData` 3D array `data` (which may or may not\nbe shared with the application). The voxel data must be laid out in\nxyz-order[^3] and can be compact (best for performance) or can have a\nstride between voxels, specified through the `byteStride1` parameter\nwhen creating the `OSPData`. Only 1D strides are supported, additional\nstrides between scanlines (2D, `byteStride2`) and slices (3D,\n`byteStride3`) are not.\n\nThe parameters understood by structured volumes are summarized in the\ntable below.\n\n| Type    | Name           |                    Default | Description                                                                                                         |\n|:--------|:---------------|---------------------------:|:--------------------------------------------------------------------------------------------------------------------|\n| vec3f   | gridOrigin     |                $(0, 0, 0)$ | origin of the grid in object-space                                                                                  |\n| vec3f   | gridSpacing    |                $(1, 1, 1)$ | size of the grid cells in object-space                                                                              |\n| OSPData | data           |                            | the actual voxel 3D [data](#data)                                                                                   |\n| bool    | cellCentered   |                      false | whether the data is provided per cell (as opposed to per vertex)                                                    |\n| uint    | filter         | `OSP_VOLUME_FILTER_LINEAR` | filter used for reconstructing the field, also allowed is `OSP_VOLUME_FILTER_NEAREST` and `OSP_VOLUME_FILTER_CUBIC` |\n| uint    | gradientFilter |           same as `filter` | filter used during gradient computations                                                                            |\n| float   | background     |                      `NaN` | value that is used when sampling an undefined region outside the volume domain                                      |\n\nConfiguration parameters for structured regular volumes.\n\nThe size of the volume is inferred from the size of the 3D array `data`,\nas is the type of the voxel values (currently supported are:\n`OSP_UCHAR`, `OSP_SHORT`, `OSP_USHORT`, `OSP_HALF`, `OSP_FLOAT`, and\n`OSP_DOUBLE`). Data can be provided either per cell or per vertex (the\ndefault), selectable via the `cellCentered` parameter (which will also\naffect the computed bounding box).\n\n### Structured Spherical Volume\n\nStructured spherical volumes are also supported, which are created by\npassing a type string of “`structuredSpherical`” to `ospNewVolume`. The\ngrid dimensions and parameters are defined in terms of radial distance\n$r$, inclination angle $\\theta$, and azimuthal angle $\\phi$, conforming\nwith the ISO convention for spherical coordinate systems. The coordinate\nsystem and parameters understood by structured spherical volumes are\nsummarized below.\n\n\u003cfigure\u003e\n\u003cimg\nsrc=\"https://ospray.github.io/images/structured_spherical_coords.svg\"\nstyle=\"width:60.0%\"\nalt=\"Coordinate system of structured spherical volumes.\" /\u003e\n\u003cfigcaption aria-hidden=\"true\"\u003eCoordinate system of structured spherical\nvolumes.\u003c/figcaption\u003e\n\u003c/figure\u003e\n\n\n\n| Type    | Name           |                     Default | Description                                                                                                     |\n|:--------|:---------------|----------------------------:|:----------------------------------------------------------------------------------------------------------------|\n| vec3f   | gridOrigin     |                 $(0, 0, 0)$ | origin of the grid in units of $(r, \\theta, \\phi)$; angles in degrees                                           |\n| vec3f   | gridSpacing    | $(1, 180/dim.y, 360/dim.z)$ | size of the grid cells in units of $(r, \\theta, \\phi)$, per default covering the full sphere; angles in degrees |\n| OSPData | data           |                             | the actual voxel 3D [data](#data)                                                                               |\n| uint    | filter         |  `OSP_VOLUME_FILTER_LINEAR` | filter used for reconstructing the field, also allowed is `OSP_VOLUME_FILTER_NEAREST`                           |\n| uint    | gradientFilter |            same as `filter` | filter used during gradient computations                                                                        |\n| float   | background     |                       `NaN` | value that is used when sampling an undefined region outside the volume domain                                  |\n\nConfiguration parameters for structured spherical volumes.\n\nThe dimensions $(r, \\theta, \\phi)$ of the volume are inferred from the\nsize of the 3D array `data`, as is the type of the voxel values\n(currently supported are: `OSP_UCHAR`, `OSP_SHORT`, `OSP_USHORT`,\n`OSP_HALF`, `OSP_FLOAT`, and `OSP_DOUBLE`).\n\nThese grid parameters support flexible specification of spheres,\nhemispheres, spherical shells, spherical wedges, and so forth. The grid\nextents (computed as\n`[gridOrigin, gridOrigin + (dimensions - 1) * gridSpacing]`) however\nmust be constrained such that:\n\n- $r \\geq 0$\n- $0 \\leq \\theta \\leq 180$\n- $0 \\leq \\phi \\leq 360$\n\n### Adaptive Mesh Refinement (AMR) Volume\n\nOSPRay currently supports block-structured (Berger-Colella) AMR volumes.\nVolumes are specified as a list of blocks, which exist at levels of\nrefinement in potentially overlapping regions. Blocks exist in a tree\nstructure, with coarser refinement level blocks containing finer blocks.\nThe cell width is equal for all blocks at the same refinement level,\nthough blocks at a coarser level have a larger cell width than finer\nlevels.\n\nThere can be any number of refinement levels and any number of blocks at\nany level of refinement. An AMR volume type is created by passing the\ntype string “`amr`” to `ospNewVolume`.\n\nBlocks are defined by three parameters: their bounds, the refinement\nlevel in which they reside, and the scalar data contained within each\nblock.\n\nNote that cell widths are defined *per refinement level*, not per block.\n\n| Type        | Name         |           Default | Description                                                                                                            |\n|:------------|:-------------|------------------:|:-----------------------------------------------------------------------------------------------------------------------|\n| uint        | method       | `OSP_AMR_CURRENT` | `OSPAMRMethod` sampling method. Supported methods are:                                                                 |\n|             |              |                   | `OSP_AMR_CURRENT`                                                                                                      |\n|             |              |                   | `OSP_AMR_FINEST`                                                                                                       |\n|             |              |                   | `OSP_AMR_OCTANT`                                                                                                       |\n| float\\[\\]   | cellWidth    |              NULL | array of each level’s cell width                                                                                       |\n| box3i\\[\\]   | block.bounds |              NULL | [data](#data) array of grid sizes (in voxels) for each AMR block                                                       |\n| int\\[\\]     | block.level  |              NULL | array of each block’s refinement level                                                                                 |\n| OSPData\\[\\] | block.data   |              NULL | [data](#data) array of OSPData containing the actual scalar voxel data, only `OSP_FLOAT` is supported as `OSPDataType` |\n| vec3f       | gridOrigin   |       $(0, 0, 0)$ | origin of the grid                                                                                                     |\n| vec3f       | gridSpacing  |       $(1, 1, 1)$ | size of the grid cells                                                                                                 |\n| float       | background   |             `NaN` | value that is used when sampling an undefined region outside the volume domain                                         |\n\nConfiguration parameters for AMR volumes.\n\nLastly, note that the `gridOrigin` and `gridSpacing` parameters act just\nlike the structured volume equivalent, but they only modify the root\n(coarsest level) of refinement.\n\nIn particular, OSPRay’s / Open VKL’s AMR implementation was designed to\ncover Berger-Colella \\[1\\] and Chombo \\[2\\] AMR data. The `method`\nparameter above determines the interpolation method used when sampling\nthe volume.\n\nOSP_AMR_CURRENT  \nfinds the finest refinement level at that cell and interpolates through\nthis “current” level\n\nOSP_AMR_FINEST  \nwill interpolate at the closest existing cell in the volume-wide finest\nrefinement level regardless of the sample cell’s level\n\nOSP_AMR_OCTANT  \ninterpolates through all available refinement levels at that cell. This\nmethod avoids discontinuities at refinement level boundaries at the cost\nof performance\n\nDetails and more information can be found in the publication for the\nimplementation \\[3\\].\n\n1.  M.J. Berger and P. Colella, “Local adaptive mesh refinement for\n    shock hydrodynamics.” Journal of Computational Physics 82.1 (1989):\n    64-84. DOI: 10.1016/0021-9991(89)90035-1\n2.  M. Adams, P. Colella, D.T. Graves, J.N. Johnson, N.D. Keen, T.J.\n    Ligocki, D.F. Martin. P.W. McCorquodale, D. Modiano. P.O. Schwartz,\n    T.D. Sternberg, and B. Van Straalen, “Chombo Software Package for\n    AMR Applications – Design Document”, Lawrence Berkeley National\n    Laboratory Technical Report LBNL-6616E.\n3.  I. Wald, C. Brownlee, W. Usher, and A. Knoll, “CPU volume rendering\n    of adaptive mesh refinement data”. SIGGRAPH Asia 2017 Symposium on\n    Visualization – SA ’17, 18(8), 1–8. DOI: 10.1145/3139295.3139305\n\n### Unstructured Volume\n\nUnstructured volumes can have their topology and geometry freely\ndefined. Geometry can be composed of tetrahedral, hexahedral, wedge or\npyramid cell types. The data format used is compatible with VTK and\nconsists of multiple arrays: vertex positions and values, vertex\nindices, cell start indices, cell types, and cell values. An\nunstructured volume type is created by passing the type string\n“`unstructured`” to `ospNewVolume`.\n\nSampled cell values can be specified either per-vertex (`vertex.data`)\nor per-cell (`cell.data`). If both arrays are set, `cell.data` takes\nprecedence.\n\nSimilar to a mesh, each cell is formed by a group of indices into the\nvertices. For each vertex, the corresponding (by array index) data value\nwill be used for sampling when rendering, if specified. The index order\nfor a tetrahedron is the same as `VTK_TETRA`: bottom triangle\ncounterclockwise, then the top vertex.\n\nFor hexahedral cells, each hexahedron is formed by a group of eight\nindices into the vertices and data values. Vertex ordering is the same\nas `VTK_HEXAHEDRON`: four bottom vertices counterclockwise, then top\nfour counterclockwise.\n\nFor wedge cells, each wedge is formed by a group of six indices into the\nvertices and data values. Vertex ordering is the same as `VTK_WEDGE`:\nthree bottom vertices counterclockwise, then top three counterclockwise.\n\nFor pyramid cells, each cell is formed by a group of five indices into\nthe vertices and data values. Vertex ordering is the same as\n`VTK_PYRAMID`: four bottom vertices counterclockwise, then the top\nvertex.\n\nTo maintain VTK data compatibility, the `index` array may be specified\nwith cell sizes interleaved with vertex indices in the following format:\n$n, id_1, ..., id_n, m, id_1, ..., id_m$. This alternative `index` array\nlayout can be enabled through the `indexPrefixed` flag (in which case,\nthe `cell.type` parameter must be omitted).\n\n| Type                    | Name               | Default | Description                                                                                                                                             |\n|:------------------------|:-------------------|--------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------|\n| vec3f\\[\\]               | vertex.position    |         | [data](#data) array of vertex positions                                                                                                                 |\n| float\\[\\]               | vertex.data        |         | [data](#data) array of vertex data values to be sampled                                                                                                 |\n| uint32\\[\\] / uint64\\[\\] | index              |         | [data](#data) array of indices (into the vertex array(s)) that form cells                                                                               |\n| bool                    | indexPrefixed      |   false | indicates that the `index` array is compatible to VTK, where the indices of each cell are prefixed with the number of vertices                          |\n| uint32\\[\\] / uint64\\[\\] | cell.index         |         | [data](#data) array of locations (into the index array), specifying the first index of each cell                                                        |\n| float\\[\\]               | cell.data          |         | [data](#data) array of cell data values to be sampled                                                                                                   |\n| uint8\\[\\]               | cell.type          |         | [data](#data) array of cell types (VTK compatible), only set if `indexPrefixed = false`. Supported types are:                                           |\n|                         |                    |         | `OSP_TETRAHEDRON`                                                                                                                                       |\n|                         |                    |         | `OSP_HEXAHEDRON`                                                                                                                                        |\n|                         |                    |         | `OSP_WEDGE`                                                                                                                                             |\n|                         |                    |         | `OSP_PYRAMID`                                                                                                                                           |\n| bool                    | hexIterative       |   false | hexahedron interpolation method, defaults to fast non-iterative version which could have rendering inaccuracies may appear if hex is not parallelepiped |\n| bool                    | precomputedNormals |   false | whether to accelerate by precomputing, at a cost of 12 bytes/face                                                                                       |\n| float                   | background         |   `NaN` | value that is used when sampling an undefined region outside the volume domain                                                                          |\n\nConfiguration parameters for unstructured volumes.\n\n### VDB Volume\n\nVDB volumes implement a data structure that is very similar to the data\nstructure outlined in Museth \\[1\\], they are created by passing the type\nstring “`vdb`” to `ospNewVolume`.\n\nThe data structure is a hierarchical regular grid at its core: Nodes are\nregular grids, and each grid cell may either store a constant value\n(this is called a tile), or child pointers. Nodes in VDB trees are wide:\nNodes on the first level have a resolution of 32\u003csup\u003e3\u003c/sup\u003e voxels, on\nthe next level 16\u003csup\u003e3\u003c/sup\u003e, and on the leaf level 8\u003csup\u003e3\u003c/sup\u003e\nvoxels. All nodes on a given level have the same resolution. This makes\nit easy to find the node containing a coordinate using shift operations\n(see \\[1\\]). VDB leaf nodes are implicit in OSPRay / Open VKL: they are\nstored as pointers to user-provided data.\n\n\u003cfigure\u003e\n\u003cimg src=\"https://ospray.github.io/images/vdb_structure.png\"\nstyle=\"width:80.0%\" alt=\"Topology of VDB volumes.\" /\u003e\n\u003cfigcaption aria-hidden=\"true\"\u003eTopology of VDB volumes.\u003c/figcaption\u003e\n\u003c/figure\u003e\n\n\n\nVDB volumes interpret input data as constant cells (which are then\npotentially filtered). This is in contrast to `structuredRegular`\nvolumes, which have a vertex-centered interpretation.\n\nThe VDB implementation in OSPRay / Open VKL follows the following goals:\n\n- Efficient data structure traversal on vector architectures.\n- Enable the use of industry-standard `.vdb` files created through the\n  OpenVDB library.\n- Compatibility with OpenVDB on a leaf data level, so that `.vdb` file\n  may be loaded with minimal overhead.\n\nVDB volumes have the following parameters:\n\n| Type        | Name             | Description                                                                                                                                                                                                                                                                                                                          |\n|:------------|:-----------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| int         | maxSamplingDepth | do not descend further than to this depth during sampling, the maximum value and the default is 3                                                                                                                                                                                                                                    |\n| uint32\\[\\]  | node.level       | level on which each input node exists, may be 1, 2 or 3 (levels are counted from the root level = 0 down)                                                                                                                                                                                                                            |\n| vec3i\\[\\]   | node.origin      | the node origin index (per input node)                                                                                                                                                                                                                                                                                               |\n| OSPData\\[\\] | node.data        | [data](#data) arrays with the node data (per input node). Nodes that are tiles are expected to have single-item arrays. Leaf-nodes with grid data expected to have compact 3D arrays in zyx layout (z changes most quickly) with the correct number of voxels for the `level`. Only `OSP_FLOAT` is supported as field `OSPDataType`. |\n| OSPData     | nodesPackedDense | optionally provided instead of `node.data`, a single array of all dense node data in a contiguous zyx layout, provided in the same order as the corresponding `node.*` parameters                                                                                                                                                    |\n| OSPData     | nodesPackedTile  | optionally provided instead of `node.data`, a single array of all tile node data in a contiguous layout, provided in the same order as the corresponding `node.*` parameters                                                                                                                                                         |\n| uint32\\[\\]  | node.format      | for each input node, whether it is of format `OSP_VOLUME_FORMAT_DENSE_ZYX` (and thus stored in `nodesPackedDense`), or `OSP_VOLUME_FORMAT_TILE` (stored in `nodesPackedTile`)                                                                                                                                                        |\n| uint        | filter           | filter used for reconstructing the field, default is `OSP_VOLUME_FILTER_LINEAR`, alternatively `OSP_VOLUME_FILTER_NEAREST`, or `OSP_VOLUME_FILTER_CUBIC`.                                                                                                                                                                            |\n| uint        | gradientFilter   | filter used for reconstructing the field during gradient computations, default same as `filter`                                                                                                                                                                                                                                      |\n| float       | background       | value that is used when sampling an undefined region outside the volume domain, default `NaN`                                                                                                                                                                                                                                        |\n\nConfiguration parameters for VDB volumes.\n\nThe `nodesPackedDense` and `nodesPackedTile` together with `node.format`\nparameters may be provided instead of `node.data`; this packed data\nlayout may provide better performance.\n\n1.  Museth, K. VDB: High-Resolution Sparse Volumes with Dynamic\n    Topology. ACM Transactions on Graphics 32(3), 2013. DOI:\n    10.1145/2487228.2487235\n\n### Particle Volume\n\nParticle volumes consist of a set of points in space. Each point has a\nposition, a radius, and a weight typically associated with an attribute.\nParticle volumes are created by passing the type string “`particle`” to\n`ospNewVolume`.\n\nA radial basis function defines the contribution of that particle.\nCurrently, we use the Gaussian radial basis function\n$$\\phi(P) = w \\exp\\left(-\\frac{(P - p)^2}{2 r^2}\\right),$$ where $P$ is\nthe particle position, $p$ is the sample position, $r$ is the radius and\n$w$ is the weight. At each sample, the scalar field value is then\ncomputed as the sum of each radial basis function $\\phi$, for each\nparticle that overlaps it.\n\nThe OSPRay / Open VKL implementation is similar to direct evaluation of\nsamples in Reda et al. \\[2\\]. It uses an Embree-built BVH with a custom\ntraversal, similar to the method in \\[1\\].\n\n| Type      | Name                    | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                    |\n|:----------|:------------------------|--------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| vec3f\\[\\] | particle.position       |         | [data](#data) array of particle positions                                                                                                                                                                                                                                                                                                                                                                      |\n| float\\[\\] | particle.radius         |         | [data](#data) array of particle radii                                                                                                                                                                                                                                                                                                                                                                          |\n| float\\[\\] | particle.weight         |    NULL | optional [data](#data) array of particle weights, specifying the height of the kernel.                                                                                                                                                                                                                                                                                                                         |\n| float     | radiusSupportFactor     |     3.0 | The multiplier of the particle radius required for support. Larger radii ensure smooth results at the cost of performance. In the Gaussian kernel, the radius is one standard deviation ($\\sigma$), so a value of 3 corresponds to $3 \\sigma$.                                                                                                                                                                 |\n| float     | clampMaxCumulativeValue |       0 | The maximum cumulative value possible, set by user. All cumulative values will be clamped to this, and further traversal (RBF summation) of particle contributions will halt when this value is reached. A value of zero or less turns this off.                                                                                                                                                               |\n| bool      | estimateValueRanges     |    true | Enable heuristic estimation of value ranges which are used in internal acceleration structures as well as for determining the volume’s overall value range. When set to `false`, the user *must* specify `clampMaxCumulativeValue`, and all value ranges will be assumed \\[0–`clampMaxCumulativeValue`\\]. Disabling this switch may improve volume commit time, but will make volume rendering less efficient. |\n\nConfiguration parameters for particle volumes.\n\n1.  A. Knoll, I. Wald, P. Navratil, A. Bowen, K. Reda, M.E., Papka,\n    and K. Gaither, “RBF Volume Ray Casting on Multicore and Manycore\n    CPUs”, 2014, Computer Graphics Forum, 33: 71–80.\n    doi:10.1111/cgf.12363\n\n2.  K. Reda, A. Knoll, K. Nomura, M. E. Papka, A. E. Johnson and J.\n    Leigh, “Visualizing large-scale atomistic simulations in\n    ultra-resolution immersive environments”, 2013 IEEE Symposium on\n    Large-Scale Data Analysis and Visualization (LDAV), Atlanta, GA,\n    2013, pp. 59–65.\n\n### Transfer Function\n\nTransfer functions map the scalar values of volumes to color and opacity\nand thus they can be used to visually emphasize certain features of the\nvolume. To create a new transfer function of given type `type` use\n\n``` cpp\nOSPTransferFunction ospNewTransferFunction(const char *type);\n```\n\nThe returned handle can be assigned to a volumetric model (described\nbelow) as parameter “`transferFunction`” using `ospSetObject`.\n\nOne type of transfer function that is supported by OSPRay is the linear\ntransfer function, which interpolates between given equidistant colors\nand opacities. It is create by passing the string “`piecewiseLinear`” to\n`ospNewTransferFunction` and it is controlled by these parameters:\n\n| Type      | Name    | Description                                   |\n|:----------|:--------|:----------------------------------------------|\n| vec3f\\[\\] | color   | [data](#data) array of colors (linear RGB)    |\n| float\\[\\] | opacity | [data](#data) array of opacities              |\n| box1f     | value   | domain (scalar range) this function maps from |\n\nParameters accepted by the linear transfer function.\n\nThe arrays `color` and `opacity` can be of different length.\n\n### VolumetricModels\n\nVolumes in OSPRay are given volume rendering appearance information\nthrough VolumetricModels. This decouples the physical representation of\nthe volume (and possible acceleration structures it contains) to\nrendering-specific parameters (where more than one set may exist\nconcurrently). To create a volume instance, call\n\n``` cpp\nOSPVolumetricModel ospNewVolumetricModel(OSPVolume);\n```\n\nThe passed volume can be `NULL` as long as the volume to be used is\npassed as a parameter. If both a volume is specified on object creation\nand as a parameter, the parameter value is used. If the parameter value\nis later removed, the volume object passed on object creation is again\nused.\n\n| Type                | Name             | Default | Description                                                                                                                          |\n|:--------------------|:-----------------|--------:|:-------------------------------------------------------------------------------------------------------------------------------------|\n| OSPVolume           | volume           |         | optional [volume](#volumes) object this model references                                                                             |\n| OSPTransferFunction | transferFunction |         | [transfer function](#transfer-function) to use                                                                                       |\n| float               | densityScale     |     1.0 | makes volumes uniformly thinner or thicker                                                                                           |\n| float               | anisotropy       |     0.0 | anisotropy of the (Henyey-Greenstein) phase function in \\[-1–1\\] ([path tracer](#path-tracer) only), default to isotropic scattering |\n| uint32              | id               |     -1u | optional user ID, for [framebuffer](#framebuffer) channel `OSP_FB_ID_OBJECT`                                                         |\n\nParameters understood by VolumetricModel.\n\nGeometries\n----------\n\nGeometries in OSPRay are objects that describe intersectable surfaces.\nTo create a new geometry object of given type `type` use\n\n``` cpp\nOSPGeometry ospNewGeometry(const char *type);\n```\n\nNote that in the current implementation geometries are limited to a\nmaximum of 2\u003csup\u003e32\u003c/sup\u003e primitives.\n\n### Mesh\n\nA mesh consisting of either triangles or quads is created by calling\n`ospNewGeometry` with type string “`mesh`”. Once created, a mesh\nrecognizes the following parameters:\n\n| Type                    | Name                   | Description                                                                                                          |\n|:------------------------|:-----------------------|:---------------------------------------------------------------------------------------------------------------------|\n| vec3f\\[\\]               | vertex.position        | [data](#data) array of vertex positions, overridden by `motion.*` arrays                                             |\n| vec3f\\[\\]               | normal                 | [data](#data) array of face-varying normals, overridden by `motion.*` arrays                                         |\n| vec3f\\[\\]               | vertex.normal          | [data](#data) array of vertex-varying normals, overridden by `motion.*` arrays                                       |\n| vec4f\\[\\] / vec3f\\[\\]   | color                  | [data](#data) array of face-varying colors (linear RGBA/RGB)                                                         |\n| vec4f\\[\\] / vec3f\\[\\]   | vertex.color           | [data](#data) array of vertex-varying colors (linear RGBA/RGB)                                                       |\n| vec2f\\[\\]               | texcoord               | [data](#data) array of face-varying texture coordinates                                                              |\n| vec2f\\[\\]               | vertex.texcoord        | [data](#data) array of vertex-varying texture coordinates                                                            |\n| vec3ui\\[\\] / vec4ui\\[\\] | index                  | [data](#data) array of (either triangle or quad) indices (into the vertex array(s))                                  |\n| bool                    | quadSoup               | when no explicit `index` is given, indicates whether to assume a ‘soup’ of quads instead of triangles, default false |\n| vec3f\\[\\]\\[\\]           | motion.vertex.position | [data](#data) array of vertex position arrays (uniformly distributed keys for deformation motion blur)               |\n| vec3f\\[\\]\\[\\]           | motion.normal          | [data](#data) array of face-varying normal arrays (uniformly distributed keys for deformation motion blur)           |\n| vec3f\\[\\]\\[\\]           | motion.vertex.normal   | [data](#data) array of vertex-varying normal arrays (uniformly distributed keys for deformation motion blur)         |\n| box1f                   | time                   | time associated with first and last key in `motion.*` arrays (for deformation motion blur), default \\[0, 1\\]         |\n\nParameters defining a mesh geometry.\n\nThe data type of index arrays differentiates between the underlying\ngeometry, triangles are used for a index with `vec3ui` type and quads\nfor `vec4ui` type. Quads are internally handled as a pair of two\ntriangles, thus mixing triangles and quads is supported by encoding some\ntriangle as a quad with the last two vertex indices being identical\n(`w=z`).\n\nThe `vertex.position` array is mandatory to create a valid mesh.\n\nThe `index` array is optional. If none is provided, a ‘triangle soup’ is\nassumed, i.e., each three consecutive vertices form one triangle; unless\nthe boolean `quadSoup` is set to true, then a ‘quad soup’ is assumed\ni.e., each four subsequent vertices form one quad. If the size of the\n`vertex.position` array is not a multiple of three for triangles or four\nfor quads, the remainder vertices are ignored.\n\nFace-varying attributes (`normal`, `motion.normal`, `color`, `texcoord`)\nmap unique values to each vertex of a primitive/face (triangle or quad),\nthus attributes can be different for the same vertex that is shared by\nmultiple primitives. Essentially, face-varying attributes are a\n‘attribute soup’ and behave similar to the implicit index, the size of\nthe array must be at least three times the number of triangles or four\ntimes the number of quads, respectively. Face-varying attributes take\nprecedence over the respective vertex attributes (`vertex.normal`,\n`motion.vertex.normal`, `vertex.color`, `vertex.texcoord`) when both\narrays of the same attribute are present.\n\n### Subdivision\n\nA mesh consisting of subdivision surfaces, created by specifying a\ngeometry of type “`subdivision`”. Once created, a subdivision recognizes\nthe following parameters:\n\n| Type      | Name                | Description                                                                                                           |\n|:----------|:--------------------|:----------------------------------------------------------------------------------------------------------------------|\n| vec3f\\[\\] | vertex.position     | [data](#data) array of vertex positions                                                                               |\n| vec4f\\[\\] | color               | optional [data](#data) array of face-varying colors (linear RGBA)                                                     |\n| vec4f\\[\\] | vertex.color        | optional [data](#data) array of vertex-varying colors (linear RGBA)                                                   |\n| vec2f\\[\\] | texcoord            | optional [data](#data) array of vertex-varying texture coordinates                                                    |\n| vec2f\\[\\] | vertex.texcoord     | optional [data](#data) array of vertex-varying texture coordinates                                                    |\n| float     | level               | global level of tessellation, default 5                                                                               |\n| uint\\[\\]  | index               | [data](#data) array of indices (into the vertex array(s))                                                             |\n| float\\[\\] | index.level         | optional [data](#data) array of per-edge levels of tessellation, overrides global level                               |\n| uint\\[\\]  | face                | optional [data](#data) array holding the number of indices/edges (3 to 15) per face, defaults to 4 (a pure quad mesh) |\n| vec2i\\[\\] | edgeCrease.index    | optional [data](#data) array of edge crease indices                                                                   |\n| float\\[\\] | edgeCrease.weight   | optional [data](#data) array of edge crease weights                                                                   |\n| uint\\[\\]  | vertexCrease.index  | optional [data](#data) array of vertex crease indices                                                                 |\n| float\\[\\] | vertexCrease.weight | optional [data](#data) array of vertex crease weights                                                                 |\n| uint      | mode                | `OSPSubdivisionMode` subdivision edge boundary mode, supported modes are:                                             |\n|           |                     | `OSP_SUBDIVISION_NO_BOUNDARY`                                                                                         |\n|           |                     | `OSP_SUBDIVISION_SMOOTH_BOUNDARY` (default)                                                                           |\n|           |                     | `OSP_SUBDIVISION_PIN_CORNERS`                                                                                         |\n|           |                     | `OSP_SUBDIVISION_PIN_BOUNDARY`                                                                                        |\n|           |                     | `OSP_SUBDIVISION_PIN_ALL`                                                                                             |\n\nParameters defining a Subdivision geometry.\n\nThe `vertex` and `index` arrays are mandatory to create a valid\nsubdivision surface. If no `face` array is present then a pure quad mesh\nis assumed (the number of indices must be a multiple of 4). Optionally\nsupported are edge and vertex creases.\n\n### Spheres\n\nA geometry consisting of individual spheres, each of which can have an\nown radius, is created by calling `ospNewGeometry` with type string\n“`sphere`”. The spheres will not be tessellated but rendered\nprocedurally and are thus perfectly round. To allow a variety of sphere\nrepresentations in the application this geometry allows a flexible way\nof specifying the data of center position and radius within a\n[data](#data) array:\n\n| Type      | Name            | Default | Description                                                               |\n|:----------|:----------------|--------:|:--------------------------------------------------------------------------|\n| vec3f\\[\\] | sphere.position |         | [data](#data) array of center positions                                   |\n| float\\[\\] | sphere.radius   |    NULL | optional [data](#data) array of the per-sphere radius                     |\n| vec3f\\[\\] | sphere.normal   |    NULL | optional [data](#data) array of normals (only for “oriented disc”)        |\n| vec2f\\[\\] | sphere.texcoord |    NULL | optional [data](#data) array of texture coordinates (constant per sphere) |\n| float     | radius          |    0.01 | default radius for all spheres (if `sphere.radius` is not set)            |\n| uint      | type            |         | `OSPSphereType` for rendering the sphere. Supported types are:            |\n|           |                 |         | `OSP_SPHERE` (default)                                                    |\n|           |                 |         | `OSP_DISC`                                                                |\n|           |                 |         | `OSP_ORIENTED_DISC`                                                       |\n\nParameters defining a spheres geometry.\n\n### Curves\n\nA geometry consisting of multiple curves is created by calling\n`ospNewGeometry` with type string “`curve`”. The parameters defining\nthis geometry are listed in the table below.\n\n| Type       | Name                   | Description                                                                      |\n|:-----------|:-----------------------|:---------------------------------------------------------------------------------|\n| vec4f\\[\\]  | vertex.position_radius | [data](#data) array of vertex position and per-vertex radius                     |\n| vec2f\\[\\]  | vertex.texcoord        | [data](#data) array of per-vertex texture coordinates                            |\n| vec4f\\[\\]  | vertex.color           | [data](#data) array of corresponding vertex colors (linear RGBA)                 |\n| vec3f\\[\\]  | vertex.normal          | [data](#data) array of curve normals (only for “ribbon” curves)                  |\n| vec4f\\[\\]  | vertex.tangent         | [data](#data) array of curve tangents (only for “hermite” curves)                |\n| uint32\\[\\] | index                  | [data](#data) array of indices to the first vertex or tangent of a curve segment |\n| uint       | type                   | `OSPCurveType` for rendering the curve. Supported types are:                     |\n|            |                        | `OSP_FLAT`                                                                       |\n|            |                        | `OSP_ROUND`                                                                      |\n|            |                        | `OSP_RIBBON`                                                                     |\n|            |                        | `OSP_DISJOINT`                                                                   |\n| uint       | basis                  | `OSPCurveBasis` for defining the curve. Supported bases are:                     |\n|            |                        | `OSP_LINEAR`                                                                     |\n|            |                        | `OSP_BEZIER`                                                                     |\n|            |                        | `OSP_BSPLINE`                                                                    |\n|            |                        | `OSP_HERMITE`                                                                    |\n|            |                        | `OSP_CATMULL_ROM`                                                                |\n\nParameters defining a curves geometry.\n\nPositions in `vertex.position_radius` parameter supports per-vertex\nvarying radii with data type `vec4f[]` and instantiate Embree curves\ninternally for the relevant type/basis mapping.\n\nThe following section describes the properties of different curve basis’\nand how they use the data provided in data buffers:\n\nOSP_LINEAR  \nThe indices point to the first of 2 consecutive control points in the\nvertex buffer. The first control point is the start and the second\ncontrol point the end of the line segment. The curve goes through all\ncontrol points listed in the vertex buffer.\n\nOSP_BEZIER  \nThe indices point to the first of 4 consecutive control points in the\nvertex buffer. The first control point represents the start point of the\ncurve, and the 4th control point the end point of the curve. The Bézier\nbasis is interpolating, thus the curve does go exactly through the first\nand fourth control vertex.\n\nOSP_BSPLINE  \nThe indices point to the first of 4 consecutive control points in the\nvertex buffer. This basis is not interpolating, thus the curve does in\ngeneral not go through any of the control points directly. Using this\nbasis, 3 control points can be shared for two continuous neighboring\ncurve segments, e.g., the curves $(p0, p1, p2, p3)$ and\n$(p1, p2, p3, p4)$ are C1 continuous. This feature make this basis a\ngood choice to construct continuous multi-segment curves, as memory\nconsumption can be kept minimal.\n\nOSP_HERMITE  \nIt is necessary to have both vertex buffer and tangent buffer for using\nthis basis. The indices point to the first of 2 consecutive points in\nthe vertex buffer, and the first of 2 consecutive tangents in the\ntangent buffer. This basis is interpolating, thus does exactly go\nthrough the first and second control point, and the first order\nderivative at the begin and end matches exactly the value specified in\nthe tangent buffer. When connecting two segments continuously, the end\npoint and tangent of the previous segment can be shared.\n\nOSP_CATMULL_ROM  \nThe indices point to the first of 4 consecutive control points in the\nvertex buffer. If $(p0, p1, p2, p3)$ represent the points then this\nbasis goes through $p1$ and $p2$, with tangents as $(p2-p0)/2$ and\n$(p3-p1)/2$.\n\nThe following section describes the properties of different curve types’\nand how they define the geometry of a curve:\n\nOSP_FLAT  \nThis type enables faster rendering as the curve is rendered as a\nconnected sequence of ray facing quads.\n\nOSP_ROUND  \nThis type enables rendering a real geometric surface for the curve which\nallows closeup views. This mode renders a sweep surface by sweeping a\nvarying radius circle tangential along the curve.\n\nOSP_RIBBON  \nThe type enables normal orientation of the curve and requires a normal\nbuffer be specified along with vertex buffer. The curve is rendered as a\nflat band whose center approximately follows the provided vertex buffer\nand whose normal orientation approximately follows the provided normal\nbuffer. Not supported for basis `OSP_LINEAR`.\n\nOSP_DISJOINT  \nOnly supported for basis `OSP_LINEAR`; the segments are open and not\nconnected at the joints, i.e., the curve segments are either individual\ncones or cylinders.\n\n### Boxes\n\nOSPRay can directly render axis-aligned bounding boxes without the need\nto convert them to quads or triangles. To do so create a boxes geometry\nby calling `ospNewGeometry` with type string “`box`”.\n\n| Type      | Name | Description                  |\n|:----------|:-----|:-----------------------------|\n| box3f\\[\\] | box  | [data](#data) array of boxes |\n\nParameters defining a boxes geometry.\n\n### Planes\n\nOSPRay can directly render planes defined by plane equation coefficients\nin its implicit form $ax + by + cz + d = 0$. By default planes are\ninfinite but their extents can be limited by defining optional bounding\nboxes. A planes geometry can be created by calling `ospNewGeometry` with\ntype string “`plane`”.\n\n| Type      | Name               | Description                                              |\n|:----------|:-------------------|:---------------------------------------------------------|\n| vec4f\\[\\] | plane.coefficients | [data](#data) array of plane coefficients $(a, b, c, d)$ |\n| box3f\\[\\] | plane.bounds       | optional [data](#data) array of bounding boxes           |\n\nParameters defining a planes geometry.\n\n### Isosurfaces\n\nOSPRay can directly render multiple isosurfaces of a volume without\nfirst tessellating them. To do so create an isosurfaces geometry by\ncalling `ospNewGeometry` with type string “`isosurface`”. The appearance\ninformation of the surfaces is set through the Geometric Model.\nPer-isosurface colors can be set by passing per-primitive colors to the\nGeometric Model, in order of the isosurface array.\n\n| Type      | Name     | Description                                        |\n|:----------|:---------|:---------------------------------------------------|\n| float     | isovalue | single isovalues                                   |\n| float\\[\\] | isovalue | [data](#data) array of isovalues                   |\n| OSPVolume | volume   | handle of the [Volume](#volumes) to be isosurfaced |\n\nParameters defining an isosurfaces geometry.\n\n### GeometricModels\n\nGeometries are matched with surface appearance information through\nGeometricModels. These take a geometry, which defines the surface\nrepresentation, and applies either full-object or per-primitive color\nand material information. To create a geometric model, call\n\n``` cpp\nOSPGeometricModel ospNewGeometricModel(OSPGeometry);\n```\n\nThe passed geometry can be `NULL` as long as the geometry to be used is\npassed as a parameter. If both a geometry is specified on object\ncreation and as a parameter, the parameter value is used. If the\nparameter value is later removed, the geometry object passed on object\ncreation is again used.\n\nColor and material are fetched with the primitive ID of the hit (clamped\nto the valid range, thus a single color or material is fine), or mapped\nfirst via the `index` array (if present). All parameters are optional,\nhowever, some renderers (notably the [path tracer](#path-tracer))\nrequire a material to be set. Materials are either handles of\n`OSPMaterial`, or indices into the `material` array on the\n[renderer](#renderers), which allows to build a [world](#world) which\ncan be used by different types of renderers.\n\nAn `invertNormals` flag allows to invert (shading) normal vectors of the\nrendered geometry. That is particularly useful for clipping. By changing\nnormal vectors orientation one can control whether inside or outside of\nthe clipping geometry is being removed. For example, a clipping geometry\nwith normals oriented outside clips everything what’s inside.\n\n| Type                                                | Name          | Description                                                                                                                                          |\n|:----------------------------------------------------|:--------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------|\n| OSPGeometry                                         | geometry      | optional [geometry](#geometries) object this model references                                                                                        |\n| OSPMaterial / OSPMaterial\\[\\] / uint32 / uint32\\[\\] | material      | optional ([data](#data) array of per-primitive) [material](#materials), may be an index into the `material` parameter on the renderer (if it exists) |\n| vec4f / vec4f\\[\\]                                   | color         | optional ([data](#data) array of per-primitive) color assigned to the geometry (linear RGBA)                                                         |\n| uint8\\[\\]                                           | index         | optional [data](#data) array of per-primitive indices into `color` and `material`                                                                    |\n| bool                                                | invertNormals | inverts all shading normals (Ns), default false                                                                                                      |\n| uint32                                              | id            | optional user ID, for [framebuffer](#framebuffer) channel `OSP_FB_ID_OBJECT`, default -1u                                                            |\n\nParameters understood by GeometricModel.\n\nLights\n------\n\nTo create a new light source of given type `type` use\n\n``` cpp\nOSPLight ospNewLight(const char *type);\n```\n\nAll light sources accept the following parameters:\n\n| Type  | Name              | Default | Description                                                                                                                       |\n|:------|:------------------|--------:|:----------------------------------------------------------------------------------------------------------------------------------|\n| vec3f | color             |   white | color of the light (linear RGB)                                                                                                   |\n| float | intensity         |       1 | intensity of the light (a factor)                                                                                                 |\n| uint  | intensityQuantity |         | `OSPIntensityQuantity` to set the radiometric quantity represented by `intensity`. The default value depends on the light source. |\n| bool  | visible           |    true | whether the light can be directly seen                                                                                            |\n\nParameters accepted by all lights.\n\nIn OSPRay the `intensity` parameter of a light source can correspond to\ndifferent types of radiometric quantities. The type of the value\nrepresented by a light’s `intensity` parameter is set using\n`intensityQuantity`, which accepts values from the enum type\n`OSPIntensityQuantity`. The supported types of `OSPIntensityQuantity`\ndiffer between the different light sources (see documentation of each\nspecific light source).\n\n| Name                              | Description                                                                                                                            |\n|:----------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------|\n| OSP_INTENSITY_QUANTITY_POWER      | the overall amount of light energy emitted by the light source into the scene, unit is W                                               |\n| OSP_INTENSITY_QUANTITY_INTENSITY  | the overall amount of light emitted by the light in a given direction, unit is W/sr                                                    |\n| OSP_INTENSITY_QUANTITY_RADIANCE   | the amount of light emitted by a point on the light source in a given direction, unit is W/sr/m\u003csup\u003e2\u003c/sup\u003e                            |\n| OSP_INTENSITY_QUANTITY_IRRADIANCE | the amount of light arriving at a surface point, assuming the light is oriented towards to the surface, unit is W/m\u003csup\u003e2\u003c/sup\u003e        |\n| OSP_INTENSITY_QUANTITY_SCALE","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRenderKit%2Fospray","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FRenderKit%2Fospray","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRenderKit%2Fospray/lists"}