Building a Geometry - Part 2 - Setting Up a GI Cache

Previous tutorial (Building a Geometry - Part 1 - Loading a Source Scene) showed how to load a geometry from an external RED scene graph. In this sample, we will add global illumination (GI) and ambient occlusion (AO) data.

First we will see how to generate and save GI and AO data, then we will use a method to load back these data and set them to the geometry.

Generating the GI and AO Data:

To generate the GI and AO data for a geometry, there is a single method to call:

// Building the GI caches: A set of GI caches for the sun, a set of GI caches for baked lights and AO caches.
// The method also builds the ground ambient occlusion for the integration of the geometry in a surrounding scene.
RED::Vector< RED::Vector< RED::Object* > > giCaches;
RED::Vector< RED::Vector< RED::Object* > > bakedLights;
RED::Vector< RED::Object* > aoCache;
RED::Vector< unsigned char > groundAO;
double groundBC[3];

// Setup the baked light names:
RED::Vector< unsigned int > bakedLightsFull, bakedLightsIndirect, bakedLightsShared;
RC_TEST( bakedLightsFull.push_back( RED::Object::GetIDFromString( "VRayLight001" ) ) );
RC_TEST( bakedLightsIndirect.push_back( RED::Object::GetIDFromString( "portal_0" ) ) );

RC_TEST( iassetmgr->GenerateGeometryGICache( giCaches, bakedLights, aoCache, groundAO, groundBC,
                                            g_geometry_root, RED::LayerSet::ALL_LAYERS,
                                            filterpos_indoor, filterpos_outdoor, portals, splitters,
                                            bakedLightsFull, bakedLightsIndirect, bakedLightsShared,
                                            true, RED::Color::FromCharRGBA( 126, 96, 45 ), 0.0, 500000, 30, 30, 30, 2000, 10, 0.4, false, g_sundir, REDartProgressCB, NULL ) );

This method does four things:

  1. Generating multiple GI caches allowing to have a dynamic illumination for any sun position

  2. Generating a GI cache for each light that is baked

  3. Generating an AO cache for the whole geometry

  4. Generating the ground AO applied on the landscape for the house to be well integrated

Note

Generating a dynamic GI cache in high definition can take several minutes up to several hours.

The method works on the RED source scene graph loaded using ART::IAssetManager::LoadGeometrySourceFile, or directly supplied by the calling application.

To compute a GI cache in HOOPS Luminate, filtering positions must be supplied. These filtering positions are 3d positions in the scene that are used to define from where the scene is visible. These filtering positions are those defined in HOOPS Luminate by RED::IWindow::FrameTracingGICache. The ART::IAssetManager offers a service to automate the generation of filtering positions. See ART::IAssetManager::GenerateGIFilteringPositions.

There are two lists of filtering positions: one for indoor rendering and the other one for outdoor rendering. It’s possible to calculate a GI cache with only one list of filtering positions. However there are differences between the two lists:

  • The indoor list of filtering positions will render a GI cache based on the specified portals. So the sky lighting will only get in through portals defined in the scene. The coverage of the GI samples will be limited by what the indoor filtering positions can see of the scene, given the fact that portals will block the visibility (e.g. it’s not possible to generate GI cache samples on the other side of a window if a portal blocks it).

  • The outdoor list of filtering positions will render a GI cache with no portals. However, portals of the scene will still block visibility and avoid outdoor GI caches to be spread indoor.

Generally speaking, for a clean GI cache generation, there must be a space partitioning between the indoor and the outdoor. Portals are used to define the limit of each area. They’re used to close the indoor area and make it disconnected from the outdoor area. If the closure is not correct, indoor samples will leak outdoor and vice-versa, resulting in unpleasant GI caches at the crossing of the two areas.

As we mentioned it, a GI cache can be calculated based on only one list of filtering positions. In this case, if there are portals, the indoor list should be selected while if there are no portals, the outdoor list should be selected.

Portals are currently identified by their names in the scene graph.

Note

This is the job of the user to correctly place the indoor and outdoor samples in his original scene as well as the portals. Filtering positions can be generated almost automatically by the ART::IAssetManager, using ART::IAssetManager::GenerateGIFilteringPositions. Portals must be defined as skylight portals as this is usually done in HOOPS Luminate.

The method builds an illumination cache for the baked lights of the scene. A light can be

  • fully baked (ART::LB_FULL): direct and indirect lighting is baked, no possibility of dynamic lighting

  • baked only on indirect lighting (ART::LB_INDIRECT): the direct lighting is dynamic

  • not baked (ART::LB_NONE): the light is dynamic, no indirect lighting

The lists of fully baked and indirect baked light names must be provided to the method. The light baking mode must also be set in the geometry lights (see Building a Geometry - Part 3 - Adding Lights).

Saving and Loading the GI and AO Data

To save the data on disk, a convenient method can be used:

// Saving the GI caches:
RC_TEST( iassetmgr->SaveGeometryGICache( giCaches, bakedLights, aoCache, groundAO, groundBC, g_sundir, "../Resources/House_GICache.red" ) );

// Setup the geometry GI caches:
ART::IGeometry* igeometry = g_geometry->As< ART::IGeometry >();
RC_TEST( igeometry->SetGICaches( giCaches, bakedLights, aoCache, 0.5f ) );
RC_TEST( igeometry->SetGroundAOCache( groundAO, ART_GEOMETRY_AO_GROUND_FIELD_RESOLUTION, groundBC ) );

// Refresh the geometry:
RC_TEST( iearth->RefreshGeometry( g_geometry ) );

It simply takes all the previously generated data and save them as a single file.

Reloading the file is as simple as saving it:

// Loading GI caches:
RED::Vector< RED::Vector< RED::Object* > > giCaches;
RED::Vector< RED::Vector< RED::Object* > > bakedLights;
RED::Vector< RED::Object* > aoCache;
RED::Vector< unsigned char > groundAO;
double groundBC[3];
RED::Vector3 sunDirection;
RC_TEST( iassetmgr->LoadGeometryGICache( giCaches, bakedLights, aoCache, groundAO, groundBC, sunDirection, "../Resources/House_GICache.red", REDartProgressCB, NULL ) );

// Setting the GI and AO data:
ART::IGeometry* igeometry = g_geometry->As< ART::IGeometry >();
RC_TEST( igeometry->SetGICaches( giCaches, bakedLights, aoCache, 0.5f ) );
RC_TEST( igeometry->SetGroundAOCache( groundAO, ART_GEOMETRY_AO_GROUND_FIELD_RESOLUTION, groundBC ) );

// Refresh the geometry:
RC_TEST( iearth->RefreshGeometry( g_geometry ) );

Global illumination and ambient occlusion data are set to the geometry thanks to two methods:

  • ART::IGeometry::SetGICache - to transmit the GI and AO data applied to the geometry directly

  • ART::IGeometry::SetGroundAOCache - to transmit the AO data of the house applied to the landscape

Please note that the geometry must be refreshed whenever its GI cache changes.

../../../../_images/wf_building_a_geometry_2_01.jpg

The house without global illumination and ambient occlusion

../../../../_images/wf_building_a_geometry_2_02.jpg

The house without and with global illumination and ambient occlusion