This is the documentation for Enlighten.

Baking with the low level bake API


Overview

This section describes the low level baking API (the EnlightenBake library).

As an additional resource, the Enlighten SDK includes a sample application called BasicLightmapBaking that implements all these steps on a simple scene. Executing the compiled binary will generate light maps for direct and indirect lighting and ambient occlusion as well as the .scene files that can be viewed in GeoRadiosity. See the source files for more information.

Key

Bake system definition

The initial stage of the baking is:

  1. Decide which Enlighten IPrecompInputGeometry instances you want in each bake system. Each bake system represents one output lightmap.
  2. Create an IBakeInputSystem for each bake system you want. Ensure the name is unique.
  3. Set the resolution of the system in the Enlighten IBakeInputProperties, and if you are not creating your own lightmap UV stream, turn packing on here also. Use IBakeInputSystem::SetBakeProperties to pass the properties to the bake system.
  4. For each instance in that system, create a Enlighten BakeInputMeshInfo object filling out the fields appropriately, and then call IBakeInputSystem::AddMesh().
  5. Call IBakeInputSystem::Finalise(), and extract the new lightmap UV stream if packing was required.

Outputs from a previous stage are never modified by a later one, so you can often run these stages in parallel (for example, through distributed build systems such as IncrediBuild).

The diagram below shows the creation of one IBakeInputSystem. Repeat for each output map required.

Direct light baking

  1. First, all the bake systems have to be combined into a BakeSystemResource object. This object is used to create a KD tree for the other stages to trace against, so requires updating if any geometry changes.
  2. Next, copy lighting information into an IBakeInputLighting object.
  3. Now, for each BakeSystemResource, create an IBakeVisibilityBuffer with the IBake API. This operation is slow; therefore if only the lights have changed (and not the geometry) you can pass in an IBakeVisibilityBuffer from a previous run and it will be updated.
  4. Call IBake::BakeSystemDirect() to create the IBakeOutputSystemDirect. Optionally pass in a BakeSystemResource object to be able to apply a visibility-aware post-processing filter, with its size set as the filter size baking property. The final output texture, in FP16 format, can be pulled from this object.

The diagrams below show a scene with two IBakeInputSystems; there may be more or fewer than this.

Indirect light baking

  1. Create an IBakeInputRuntime and fill it with the RadSystemCore and InputWorkspace of each Enlighten system.
  2. For each Enlighten system, create an IBakeInputSystem using all the Radiosity objects of the Enlighten system. This is required later in the process in order to fit the Enlighten lit instances to the bake system instances. Set the resolution of the IBakeInputSystem to the resolution of the Enlighten lightmap via an IBakeInputProperties object passed to the IBakeInputSystem::SetBakeProperties method.
  3. For each Enlighten system, call IBake::CreateRuntimeLighting to create an IBakeRuntimeLighting from:
    1. the IBakeInputSystem that you just made
    2. the IPrecompSystemDuster
    3. the IPrecompPackedSystem
    4. the global IBakeInputLighting
  4. For each runtime lighting you made:
    1. For each bake system representing the output lightmaps:
      1. Call IBake::UpdateRuntimeLighting to apply the light and albedo information for each bake system to the Enlighten system.
    2. Call IBake::FinaliseRuntimeLighting
  5. Call IBake::RunEnlightenSolver; this takes all the information and spins a small Enlighten Runtime until the lighting values settle. This is run only once as it contains information about every system in the bake.
  6. For each bake system, call IBake::BakeSystemIndirect and extract the indirect lighting from the IBakeOutputSystemIndirect it creates. Optionally pass in a BakeSystemResource object and a IBakeInputRayOriginPositions to be able to enable visibility-aware upsampling with the identically named baking property.


Final Gather light baking

Final Gather creates a refined version of the indirect lightmap through ray tracing, by using previously calculated indirect and direct lightmaps. The final gather baking thus has a dependency on all the IBakeOutputSystemIndirect and all the IBakeOutputSystemDirect objects previously created for the baked scene, as well as their matching IBakeInputSystem objects. It also has a dependency on the IBakeSystemResource object (used for raytracing) and the IBakeSolvedRuntime objects for the baked scene.

  1. For each IBakeInputSystem, call IBake::BakeSystemFinalGather.
  2. Extract the FP16 output textures from the resulting IBakeOutputSystemFinalGather objects.


Ambient occlusion

  1. For each BakeSystemResource, call IBake::BakeSystemAO.
  2. Extract the FP16 output textures from the resulting IBakeOutputSystemAO objects.


Direct light baking for probes

  1. First, copy lighting information into an IBakeInputLighting object.
  2. Now, for each probe set represented by an IPrecompInputProbeSet, create an IBakeVisibilityBuffer with the IBake API. You also need to pass in a BakeSystemResource object, with all the systems that can influence the direct lighting for the probes. This operation is slow; therefore if only the lights have changed (and not the geometry) you can pass in an IBakeVisibilityBuffer from a previous run and it will be updated.
  3. Call IBake::BakeProbeSetDirect() to create the IBakeOutputProbeSet. Use the IBakeOutputProbeSet::GetOutput() method to retrieve the SH coefficients of all probes in the probe set.


Indirect light baking for probes

  1. First follow the steps described in Indirect light baking.
  2. Now, for each probe in a probe set, use the IBakeSolvedRuntime::GetSolvedProbe() method of IBakeSolvedRuntime to retrieve the SH coefficients.


Baked Radiosity Normal Texture

The baked radiosity normal texture is needed when using baked directional irradiance to better bring out features when the fine-grained shading normal used in runtime deviates from the cruder normal used for computing radiosity. (typical example is re-lighting normal maps)

  1. For each BakeInputSystem, call IBake::BakeSystemRadiosityNormal, providing the BakeSolvedRuntime for all Enlighten systems.
  2. Extract the FP16 output textures from the resulting IBakeOutputSystemRadiosityNormal objects.


Message reporting and error handling

If you experience problems when using the Low Level Precompute API, call the GeoAttachSystemLoggers/GeoAttachLogger functions to issue error and warning messages. For more information, see the API documentation at module Message Reporting and Error Handling.

Debugging using GeoRadiosity

To debug scenes with baked light maps using GeoRadiosity, follow the steps required for the low-level precompute API. In addition to the precompute input files, you also need to serialise the IBakeInputSystem and IBakeInputProperties objects. Please note that you should have assigned a GUID to the IBakeInputProperties because this identifier is used to link the properties with the generated light maps.

If you pass in different chart UVs to the low-level baking API than to the low-level precompute API, you must generate an object of the IBakeInputGeometryUvs class for each geometry in your scene. This file must have the same file name as the serialised IPrecompInputGeometry object, but with the extension changed to .buv.

Additionally, to support materials in baking, you must generate XML-based material files as used in the high-level build system. For each IPrecompInputGeometry you have, a material file can be created for each mesh with the index of the mesh appended to the file name and the extension changed to .mats. For example, if your serialized IPrecompInputGeometry is called Geom.ig and contains two meshes, then you should create two materials files called Geom_0.mats and Geom_1.mats. Please note that this is optional and only required if you need to reproduce the materials in the reconstructed scene; for example if it important for your debugging effort.

Any referenced texture in the materials file should have a file path relative to the material file. Use the GeoRGBXTexture class to serialise the texture.

Only scenes which assign instances to light maps can be extracted. Scenes which map individual meshes to light maps are currently not supported.