Skip to content

RenderKit/openpgl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Intel® Open Path Guiding Library

This is release v0.7.0 of Intel® Open PGL. For changes and new features, see the changelog. Visit http://www.openpgl.org for more information.

Overview

The Intel® Open Path Guiding Library (Intel® Open PGL) implements a set of representations and training algorithms needed to integrate path guiding into a renderer. Open PGL offers implementations of current state-of-the-art path guiding methods, which increase the sampling quality and, therefore, the efficiency of a renderer. The goal of Open PGL is to provide implementations that are well tested and robust enough to be used in a production environment.

The representation of the guiding field is learned during rendering and updated on a per-frame basis using radiance/importance samples generated during rendering. At each vertex of a random path/walk, the guiding field is queried for a local distribution (e.g., incident radiance), guiding local sampling decisions (e.g., directions).

Currently supported path guiding methods include: guiding directional sampling decisions on surfaces and inside volumes based on a learned incident radiance distribution or its product with BSDF components (i.e., cosine lobe) or phase functions (i.e., single lobe HG).

Open PGL offers a C API and a C++ wrapper API for higher-level abstraction. The current implementation is optimized for the latest Intel® processors with support for SSE, AVX, AVX2, and AVX-512 instructions.

Open PGL is part of the Intel® oneAPI Rendering Toolkit and has been released under the permissive Apache 2.0 license.

Example rendering without and with Open PGL
Path traced image of a variation of the Nishita Sky Demo scene from Blender Studio (CC0) without and with using Open PGL to guide directional samples (i.e., on surfaces and inside the water volume).

Disclaimer

The current version of Open PGL is still in a pre v1.0 stage and should be used with caution in any production related environment. The API specification is still in flux and might change with upcoming releases.

Latest Updates

The full version history can be found here

Open PGL 0.7.0

  • New (Experimental) Features:

    • Radiance Caching (RC):
      • If RC is enabled, the guiding structure (i.e., Field) learns an approximation of multiple radiance quantities (in linear RGB), such as outgoing and incoming radiance, irradiance, fluence, and in-scattered radiance. These quantities can be queried using the SurfaceSamplingDistribution and VolumeSamplingDistribution classes. RC support can be enabled using the OPENPGL_EF_RADIANCE_CACHES CMake option. Note: Since the RC quantities are Monte-Carlo estimates, zero-value samples (ZeroValueSampleData) that are generated during rendering/training have to be passed/stored in the SampleStorage as well.
    • Guided/Adjoint-driven Russian Roulette (GRR):
      • The information stored in radiance caches can be used to optimize stochastic path termination decisions (a.k.a. Russian roulette) to avoid a significant increase in variance (i.e., noise) caused by early terminations, which can occur when using standard throughput-based RR strategies. We, therefore, added to example implementation for guided (openpgl::cpp::util::GuidedRussianRoulette(...)) and standard (openpgl::cpp::util::StandardThroughputBasedRussianRoulette(...)) RR, which can be found in the openpgl/cpp/RussianRoulette.h header.
    • Image-space guiding buffer (ISGB):
      • The ISGB can be used to store and approximate per-pixel guiding information (e.g., a pixel estimate used in guided Russian roulette). The ISGB class (openpgl::cpp::util::ImageSpaceGuidingBuffer) is defined in the openpgl/cpp/ImageSpaceGuidingBuffer.h header file. The support can be enabled using the OPENPGL_EF_IMAGE_SPACE_GUIDING_BUFFER CMake option.
  • API changes:

    • pgl_direction: A new wrapper type for directional data. When using C++ pgl_direction can directly be assigned by and to pgl_vec3f.
    • pgl_spectrum: A new wrapper type for spetral (i.e., linear RGB) data. When using C++ pgl_spectrum can directly be assigned by and to pgl_vec3f.
    • SampleData:
      • New enum EDirectLight flag that identifies if the radiance stored in this sample comes directly from an emitter (e.g., emissive surface, volume, or light source).
      • direction: Changes the type pgl_vec3f to pgl_direction.
    • ZeroValueSampleData: This new structure is a simplified and more compact representation of the SampleData struct representing a zero-value sample. It contains the following members:
      • position: The position of the sample (type pgl_point3f).
      • direction: The incoming direction of the sample (type pgl_direction).
      • volume: If the sample is a volume sample (type bool).
    • SampleStorage: To add, query, and get the number of ZeroValueSampleData, the following functions were added.
      • AddZeroValueSample and AddZeroValueSamples: These functions add one or multiple ZeroValueSampleData.
      • GetSizeZeroValueSurface and GetSizeZeroValueVolume: These functions return the number of collected/stored surface or volume Ze1roValueSampleData.
      • GetZeroValueSampleSurface and GetZeroValueSampleVolume: Return a given ZeroValueSampleData from either the surface or volume storage.
  • API changes (OPENPGL_EF_RADIANCE_CACHES=ON): When the RC feature is enabled, additional functions and members are available for the following structures:

    • SurfaceSamplingDistribution:
      • IncomingRadiance: The incoming radiance estimate arriving at the current cache position from a specific direction.
      • OutgoingRadiance: The outgoing radiance at the current cache position to a specific direction.
      • Irradiance: The irradiance at the current cache position and for a given surface normal.
    • VolumeSamplingDistribution:
      • IncomingRadiance: The incoming radiance estimate arriving at the current cache position from a specific direction.
      • OutgoingRadiance: The outgoing radiance at the current cache position to a specific direction.
      • InscatteredRadiance: The in-scattered radiance at the current cache position to a specific direction and for a given HG mean cosine.
      • Fluence: The volume fluence at the current cache position.
    • SampleData:
      • radianceIn: The incoming radiance arriving at the sample position from direction (type pgl_spectrum).
      • radianceInMISWeight: The MIS weight of the radianceIn if the source of it is a light source, if not it is 1.0 (type float).
      • directionOut: The outgoing direction of the sample (type pgl_direction).
      • radianceOut: The outgoing radiance estimate of the sample (type pgl_direction).

    ZeroValueSampleData: - directionOut: The outgoing direction of the sample (type pgl_direction).

  • API changes (OPENPGL_EF_IMAGE_SPACE_GUIDING_BUFFER=ON): When the ISGB feature is enabled, additional functions and members are available for the following structures:

    • ImageSpaceGuidingBuffer: This is the main structure for storing image-space, per-pixel guiding information approximated from pixel samples. -AddSample: Add a pixel sample of type ImageSpaceGuidingBuffer::Sample to the buffer.
      • Update: Updates the image-space guiding information/approximations from the previously collected samples (e.g., denoises the pixel contribution estimates using OIDN). For efficiency reasons, it makes sense not to update the buffer after every rendering progression but in an exponential fashion (e.g., at progression 2^0,2^1,…,2^N).
      • IsReady: If the ISGB is ready (i.e., at least one Update step was performed).
      • GetPixelContributionEstimate: Returns the pixel contibution estimate for a given pixel, which can be used, for example, for guided RR.
      • Reset: Resets the ISGB.
    • ImageSpaceGuidingBuffer::Sample: This structure is used to store information about a per-pixel sample that is passed to the ISGB.
      • contribution: The contribution estimate of the pixel value of a given sample (type pgl_vec3f).
      • albedo: The albedo of the surface or the volume at the first scattering event (type pgl_vec3f).
      • normal: The normal at the first surface scattering event or the ray dairection towards the camers if the first event is a volume event (type pgl_vec3f).
      • flags: Bit encoded information about the sample (e.g., if the first scattering event is a volume event Sample::EVolumeEvent).
  • Optimizations:

    • Compression for spectral and directional: To reduce the size of the SampleData and ZeroValueSampleData data types it is possible to enable 32-Bit compression, which is mainly adviced when enabling the RC feature via OPENPGL_EF_RADIANCE_CACHES=ON.
      • OPENPGL_DIRECTION_COMPRESSION: Enables 32-Bit compression for pgl_direction.
      • OPENPGL_RADIANCE_COMPRESSION: Enables 32-Bit compression for pgl_spectrum.
  • Bugfixes:

    • Numerical accuracy problem during sampling when using parametric mixtures.
  • Platform support:

    • Added support for Windows on ARM (by Anthony Roberts PR17). Note: Requires using LLVM and clang-cl.exe as C and C++ compiler.

Support and Contact

Open PGL is under active development. Though we do our best to guarantee stable release versions, a certain number of bugs, as-yet-missing features, inconsistencies, or any other issues are still possible. Should you find any such issues, please report them immediately via Open PGL’s GitHub Issue Tracker (or, if you should happen to have a fix for it, you can also send us a pull request).

Reference

@misc{openpgl,
   Author = {Herholz, Sebastian and Dittebrandt, Addis},
   Year = {2022},
   Note = {http://www.openpgl.org},
   Title = {Intel{\textsuperscript{\tiny\textregistered}}
 Open Path Guiding Library}
}

Building Open PGL from source

The latest Open PGL sources are always available at the Open PGL GitHub repository. The default main branch should always point to the latest tested bugfix release.

Prerequisites

Open PGL currently supports Linux, Windows and MacOS. In addition, before building Open PGL you need the following prerequisites:

  • You can clone the latest Open PGL sources via:

    git clone https://github.com/RenderKit/openpgl.git
    
  • To build Open PGL you need CMake, any form of C++11 compiler (we recommend using GCC, but also support Clang and MSVC), and standard Linux development tools.

  • Open PGL depends on TBB, which is available at the TBB GitHub repository.

  • Open PGL depends on OIDN, if the Image-space Guiding Buffer feature is enabled, which is available at the OIDN GitHub repository.

Depending on your Linux distribution, you can install these dependencies using yum or apt-get. Some of these packages might already be installed or might have slightly different names.

CMake Superbuild

For convenience, Open PGL provides a CMake Superbuild script which will pull down Open PGL’s dependencies and build Open PGL itself. The result is an install directory including all dependencies.

Run with:

    mkdir build
    cd build
    cmake ../superbuild
    cmake  --build .

The resulting install directory (or the one set with CMAKE_INSTALL_PREFIX) will have everything in it, with one subdirectory per dependency.

CMake options to note (all have sensible defaults):

  • CMAKE_INSTALL_PREFIX: The root directory where everything gets installed to.
  • BUILD_JOBS: Sets the number given to make -j for parallel builds.
  • BUILD_STATIC: Builds Open PGL as static library (default OFF).
  • BUILD_TOOLS: Builds Open PGL’s tools (default OFF).
  • BUILD_DEPENDENCIES_ONLY: Only builds Open PGL’s dependencies (default OFF).
  • BUILD_TBB: Builds or downloads TBB (default ON).
  • BUILD_TBB_FROM_SOURCE: Specifies whether TBB should be built from source or the releases on GitHub should be used. This must be ON when compiling for ARM (default OFF).
  • BUILD_OIDN: Builds or downloads Intel’s Open Image Denoise (OIDN) (default ON).
  • BUILD_OIDN_FROM_SOURCE: Builds OIDN from source. This must be ON when compiling for ARM. (default ON).
  • DOWNLOAD_ISPC: Downloads Intel’s ISPC compiler which is needed to build OIDN (default ON when building OIDN from source).

For the full set of options, run ccmake [<PGL_ROOT>/superbuild].

Standard CMake build

Assuming the above prerequisites are all fulfilled, building Open PGL through CMake is easy:

Create a build directory, and go into it:

    mkdir build
    cd build

Configure the Open PGL build using:

    cmake -DCMAKE_INSTALL_PREFIX=[openpgl_install] ..
  • CMake options to note (all have sensible defaults):

    • CMAKE_INSTALL_PREFIX: The root directory where everything gets installed to.

    • OPENPGL_BUILD_STATIC: Builds Open PGL as a static or shared library (default OFF).

    • OPENPGL_ISA_AVX512: Compiles Open PGL with AVX-512 support (default OFF).

    • OPENPGL_ISA_NEON and OPENPGL_ISA_NEON2X: Compiles Open PGL with NEON or double pumped NEON support (default OFF).

    • OPENPGL_LIBRARY_NAME: Specifies the name of the Open PGL library file created. By default the name openpgl is used.

    • OPENPGL_BUILD_STATIC: Builds Open PGL as static library (default OFF).

    • OPENPGL_BUILD_TOOLS: Builds additional tools such as: openpgl_bench and openpgl_debug for benchmarking and debuging guiding caches (default OFF).

    • OPENPGL_EF_RADIANCE_CACHES: Enables the experimental radiance caching feature (default OFF).

    • OPENPGL_EF_IMAGE_SPACE_GUIDING_BUFFER: Enables the experimental image-space guiding buffer feature (default OFF).

    • OPENPGL_DIRECTION_COMPRESSION: Enables the 32Bit compression for directional data stored in pgl_direction (default OFF).

    • OPENPGL_RADIANCE_COMPRESSION: Enables the 32Bit compression for RGB data stored in pgl_spectrum (default OFF).

    • OPENPGL_TBB_ROOT: Location of the TBB installation.

    • OPENPGL_TBB_COMPONENT: The name of the TBB component/library (default tbb).

Build and install Open PGL using:

    cmake build
    cmake install

Including Open PGL into a project

Including into CMake build scripts.

To include Open PGL into a project which is using CMake as a build system, one can simply use the CMake configuration files provided by Open PGL.

To make CMake aware of Open PGL’s CMake configuration scripts the openpgl_DIR has to be set to their location during configuration:

cmake -Dopenpgl_DIR=[openpgl_install]/lib/cmake/openpgl-0.7.0 ..

After that, adding OpenPGL to a CMake project/target is done by first finding Open PGL using find_package() and then adding the openpgl:openpgl targets to the project/target:

# locating Open PGL library and headers 
find_package(openpgl REQUIRED)

# setting up project/target
...
add_executable(myProject ...)
...

# adding Open PGL to the project/target
target_include_directories(myProject openpgl::openpgl)

target_link_libraries(myProject openpgl::openpgl)

Including Open PGL API headers

Open PGL offers two types of APIs.

The C API is C99 conform and is the basis for interacting with Open PGL. To use the C API of Open PGL, one only needs to include the following header:

#include <openpgl/openpgl.h>

The C++ API is a header-based wrapper of the C API, which offers a more comfortable, object-oriented way of using Open PGL. To use the C++ API of Open PGL, one only needs to include the following header:

#include <openpgl/cpp/OpenPGL.h>

Open PGL API

The API specification of Open PGL is currently still in a “work in progress” stage and might change with the next releases - depending on the community feedback and library evolution.

We, therefore, only give here a small overview of the C++ class structures and refer to the individual class header files for detailed information.

Device

#include <openpgl/cpp/Device.h>

The Device class is a key component of OpenPGL. It defines the backend used by Open PGL. OpenPGL supports different CPU backends using SSE, AVX, or AVX-512 optimizations.

Note: support for different GPU backends is planned in future releases.

Field

#include <openpgl/cpp/Field.h>

The Field class is a key component of Open PGL. An instance of this class holds the spatio-directional guiding information (e.g., approximation of the incoming radiance field) for a scene. The Field is responsible for storing, learning, and accessing the guiding information. This information can be the incidence radiance field learned from several training iterations across the whole scene. The Field holds separate approximations for surface and volumetric radiance distributions, which can be accessed separately. The representation of a scene’s radiance distribution is usually separated into a positional and directional representation using a spatial subdivision structure. Each spatial leaf node (a.k.a. Region) contains a directional representation for the local incident radiance distribution.

SurfaceSamplingDistribution

#include <openpgl/cpp/SurfaceSamplingDistribution.h>

The SurfaceSamplingDistribution class represents the guiding distribution used for sampling directions on surfaces. The sampling distribution is often proportional to the incoming radiance distribution or its product with components of a BSDF model (e.g., cosine term). The class supports functions for sampling and PDF evaluations.

VolumeSamplingDistribution

#include <openpgl/cpp/VolumeSamplingDistribution.h>

The VolumeSamplingDistribution class represents the guiding distribution used for sampling directions inside volumes. The sampling distribution is often proportional to the incoming radiance distribution or its product with the phase function (e.g., single lobe HG). The class supports functions for sampling and PDF evaluations.

SampleData

#include <openpgl/cpp/SampleData.h>

The SampleData struct represents a radiance sample (e.g., position, direction, value). Radiance samples are generated during rendering and are used to train/update the guiding field (e.g., after each rendering progression). A SampleData object is created at each vertex of a random walk/path. To collect the data at a specific vertex, the whole path (from its endpoint to the current vertex) must be considered, and information (e.g., radiance) must be backpropagated.

SampleStorage

#include <openpgl/cpp/SampleStorage.h>

The SampleStorage class is a storage container collecting all SampleData generated during rendering. It stores the (radiance/photon) samples generated during rendering. The implementation is thread save and supports concurrent adding of samples from multiple threads. As a result, only one instance of this container is needed per rendering process. The stored samples are later used by the Field class to train/learn the guiding field (i.e., radiance field) for a scene.

PathSegmentStorage

#include <openpgl/cpp/PathSegmentStorage.h>

The PathSegmentStorage is a utility class to help generate multiple SampleData objects during the path/random walk generation process. For the construction of a path/walk, each new PathSegment is stored in the PathSegmentStorage. When the walk is finished or terminated, the -radiance- SampleData is generated using a backpropagation process. The resulting samples are then be passed to the global SampleDataStorage.

Note: The PathSegmentStorage is just a utility class meaning its usage is not required. It is possible to for the users to use their own method for generating SampleData objects during rendering.

PathSegment

#include <openpgl/cpp/PathSegment.h>

The PathSegment struct stores all required information for a path segment (e.g., position, direction, PDF, BSDF evaluation). A list of succeeding segments (stored in a PathSegmentStorage) is used to generate SampleData for training the guiding field.

Projects that make use of Open PGL

TBA

Projects that are closely related to Open PGL