Rendering skies

Description

This tutorial demonstrates how to use REDsdk and its physical sky model to render any kind of background sky at day or night.

The REDsdk's physical sky model is available through the RED::ISkyLightShape interface. So, prior to building a sky model, you need to create a RED light instance. This is achieved through the RED::Factory:

// Create the sky light.
sky = RED::Factory::CreateInstance( CID_REDLightShape );
if( sky == NULL )
  RC_TEST( RED_ALLOC_FAILURE );

RED::ISkyLightShape* isky = sky->As< RED::ISkyLightShape >();

The sky light can then be used to edit the physical sky model, set a background texture of the sky, set the light and moon directions from astronomical models. Here, we'll focus on creating a background texture of a physical sky:

// Set the background image up.
RED::Object* bg_tex = NULL;

RC_TEST( isky->SetPhysicalModel( 1.0, height, 1.0, turbidity, albedo, aerosols_albedo, asymmtery_factor,
  sun_dir, sun_radius_scale, sun_mult,
  moon_dir, moon_radius_scale, moon_mult, 
  stars_mult, saturation, iresmgr->GetState() ) );

RC_TEST( isky->CreatePhysicalSkyTexture( bg_tex, true, 0, false, true, true, iresmgr->GetState() ) );

RED::Object* vrl;
RC_TEST( iwindow->GetDefaultVRL( vrl ) );

RED::IViewpointRenderList* ivrl = vrl->As< RED::IViewpointRenderList >();
RC_TEST( ivrl->SetBackgroundImages( NULL, RED::Matrix::IDENTITY, bg_tex, RED::Matrix::IDENTITY, true, iresmgr->GetState() ) );

The created texture can be of two different kind: a cube image or a composite image. A cube image is created at a given resolution while the composite image is interpreted, on-the-fly, at the caller resolution. The former is then the perfect choice to create light textures (the one used by the light to determine its colour) or indirect background textures (those seen through reflections or refractions). The latter is recommended to be used as the direct background texture (the one seen directly by the observer) as it renders nicely at any resolution.

In this tutorial, we set a composite image as it responds immediately to the user inputs (no time is needed to compute the full texture off-line).

Physical sky images are, most of the time, outside from the displayable range of intensities. They can also vary very slowly over intensity values and a good buffer precision is needed to handled them correctly. Therefore, we now set the pipeline up with full colour range precision by enabling HDR rendering in float buffers and turn on tone mapping for correct display:

// Turn on HDR.
RED::IOptions* iwinopt = window->As< RED::IOptions >();
RC_TEST( iwinopt->SetOptionValue( RED::OPTIONS_WINDOW_HDR, 2, iresmgr->GetState() ) );

// The rendering of a physical sky in a composite image only works using software rendering.
// Turning on a ray-tracing option ensures that the engine will perform software rendering if needed.
RC_TEST( iwinopt->SetOptionValue( RED::OPTIONS_RAY_PRIMARY, true, iresmgr->GetState() ) );

// Turn on tone mapping.
RED::PostProcess& pp = iviewpoint->GetPostProcessSettings();
pp.SetToneMapping( RED::TMO_EXPOSURE );
pp.SetExposure( (float)exposure );
pp.SetGamma( (float)gammaview );

That's it! The rest of the tutorial in only about handling the UI interactions and updating the sky model according to them.