Environmental mapping

Introduction

Environmental mapping is often used in real-time to approximate reflections. With REDsdk, you gain access to three environmental mapping modes. Each one will be described here.

Description

In this tutorial, a sphere with a reflective material is created amongst various other geometries. Sphere reflections are first faked with a latitude/longitude texture used in a cube image:

// Load the environmental texture.
RED::Object* envmap;
RC_TEST( iresmgr->CreateImage2D( envmap, iresmgr->GetState() ) );
RC_TEST( RED::ImageTools::Load( envmap, "../resources/envmap.jpg", RED::FMT_RGB, true, true, RED::TGT_TEX_2D, iresmgr->GetState() ) );

RED::IImage2D* ienvmap = envmap->As< RED::IImage2D >();

// Create a cube image from the 2D environmental texture.
RC_TEST( iresmgr->CreateImageCube( g_cubemap, iresmgr->GetState() ) );

RED::IImageCube* icubemap = g_cubemap->As< RED::IImageCube >();
RC_TEST( icubemap->CreateEnvironmentMap( RED::FMT_RGB, RED::ENV_SPHERICAL, 512, 
                                         ienvmap->GetLocalPixels(), ienvmap->GetLocalWidth(), ienvmap->GetLocalHeight(), ienvmap->GetLocalFormat(),
                                         RED::WM_CLAMP_TO_BORDER, RED::WM_CLAMP_TO_BORDER, 
                                         RED::Color::BLACK, 
                                         RED::Matrix::IDENTITY, RED::Matrix::IDENTITY, 
                                         iresmgr->GetState() ) );

// Create a reflective generic material.
RC_TEST( imat->SetupGenericMaterial( false, false,                                           
                                     RED::Color::BLACK, NULL, RED::Matrix::IDENTITY, RED::MCL_TEX0,
                                     RED::Color::BLACK, NULL, RED::Matrix::IDENTITY, RED::MCL_TEX0,
                                     RED::Color::BLACK, NULL, RED::Matrix::IDENTITY, RED::MCL_TEX0,
                                     RED::Color::BLACK, NULL, RED::Matrix::IDENTITY, RED::MCL_TEX0, 0.f,
                                     RED::Color::WHITE, NULL, RED::Matrix::IDENTITY, RED::MCL_TEX0, 0.f,
                                     false, false, g_cubemap, RED::Matrix::IDENTITY,
                                     1.f,
                                     RED::Color::WHITE, NULL, RED::Matrix::IDENTITY, RED::MCL_TEX0, 0.f,
                                     NULL, RED::Matrix::IDENTITY, RED::MCL_TEX0, RED::MCL_USER0,
                                     &g_ls, NULL,
                                     app::GetResourceManager(), iresmgr->GetState() ) );

RC_TEST( sphere->As< RED::IShape >()->SetMaterial( mat_sphere, iresmgr->GetState() ) )

Here is the result of texture-based environmental mapping:

A latitude/longitude texture is used to create a cube map for real-time fake reflections.

What can be very interesting is to have an environmental map which actually shows the real environment of an object and not just a fake texture. REDsdk provides a convenient way to feed a cube image with a on-demand rendering of the scene has seen from a given viewpoint:

// Update the cube image content with a rendering of the scene has seen from the cube centre.
RED::IImageCube* icubemap = g_cubemap->As< RED::IImageCube >();
RC_TEST( icubemap->AutoCubeUpdate( NULL, RED::FMT_RGB, 512, 
                                   app::GetViewpoint(), 0.1f, 10000.f, 
                                   g_ls, true, true, true, true, true, true, iresmgr->GetState() ) );

The cube image has been computed automatically by the engine and displays reflections of scene primitives.

But, as you can see, the reflections, even if they are showing the surrounding primitives, are not coherent. This is because the red, yellow and green primitives are animated while the content of the cube image has been updated only once. To overcome this, you can decide to call the cube image update method once for each frame:

The cube image is updated at each frame by the engine and now displays coherent reflections.