Denoising with Intel Open Image Denoise

In addition to its own image denoiser, HOOPS Luminate integrates Intel® Open Image Denoise (https://www.openimagedenoise.org/) natively.

Like the native denoiser, it allows to remove noise produced by the many samplings done during the rendering operations.

The denoising filter is applied on the image buffer during the post process steps.

Enabling Open Image Denoise is done with the RED::IOptions interface setting the RED::OPTIONS_RAY_ENABLE_OPEN_IMAGE_DENOISE value to true.

Note

Only one denoiser should be activated at a time. Either the native one or the Open Image Denoise one.

For Open Image Denoise being used, please make sure that its libraries are included next to the HOOPS Luminate library files:

  • OpenImageDenoise.dll and tbb12.dll for Windows;

  • libOpenImageDenoise.dylib and libtbb.dylib for MacOS;

  • libOpenImageDenoise.so and libtbb.so for Linux.

When calling RED::IWindow::FrameTracing, only the color buffer is provided to the filter. When calling RED::IWindow::FrameTracingImages with diffuse and normal layers (RED::RenderLayer::LT_DIFFUSE and RED::RenderLayer::LT_NORMAL), those two layers are also provided to the filter, improving its result.

Enabling Intel Open Image Denoise

Here is how to activate the denoising using Intel Open Image Denoise:

  • first, make sure the libraries are beside HOOPS Luminate libraries

  • then enable it like this:

// 1. Get the options interface from a viewpoint or the window.
RED::IOptions* options = viewpoint->As< RED::IOptions >();

// 2. Enable Open Image Denoise.
RC_TEST( options->SetOptionValue( RED::OPTIONS_RAY_ENABLE_OPEN_IMAGE_DENOISE, true, iresmgr->GetState() ) );

// 3. That's all!

If RED::IWindow::FrameTracingImageLayers is used instead of the classical RED::IWindow::FrameTracing, the diffuse and normal layers are used to improve the denoising.

// Denoising is improved by providing diffuse and normal buffers with RED::IWindow::FrameTracingImageLayers
RED::Object *imageColor, *imageDepth, *imageDiffuse, *imageNormal;
RC_TEST( iresmgr->CreateImage2D( imageColor, iresmgr->GetState() ) );
RC_TEST( iresmgr->CreateImage2D( imageDepth, iresmgr->GetState() ) );
RC_TEST( iresmgr->CreateImage2D( imageDiffuse, iresmgr->GetState() ) );
RC_TEST( iresmgr->CreateImage2D( imageNormal, iresmgr->GetState() ) );

RED_RC rc;
RED::Vector< RED::RenderLayer > render_layers;
// Color and depth layers are mandatory.
RED::RenderLayer layer1( RED::RenderLayer::LT_COLOR, imageColor, viewpoint, rc );
RC_TEST( rc );
RC_TEST( render_layers.push_back( layer1 ) );

RED::RenderLayer layer2( RED::RenderLayer::LT_DEPTH, imageDepth, viewpoint, rc );
RC_TEST( rc );
RC_TEST( render_layers.push_back( layer2 ) );

// Diffuse and normal layers are optional and improve the denoising.
RED::RenderLayer layer3( RED::RenderLayer::LT_DIFFUSE, imageDiffuse, viewpoint, rc );
RC_TEST( rc );
RC_TEST( render_layers.push_back( layer3 ) );

RED::RenderLayer layer4( RED::RenderLayer::LT_NORMAL, imageNormal, viewpoint, rc );
RC_TEST( rc );
RC_TEST( render_layers.push_back( layer4 ) );

// Rendering:
bool complete = false;
while( !complete )
{
    window->FrameTracingImageLayers( complete, render_layers );
}