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:
- Decide which
Enlighten IPrecompInputGeometry
instances you want in each bake system. Each bake system represents one output lightmap. - Create an
IBakeInputSystem
for each bake system you want. Ensure the name is unique. - 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. UseIBakeInputSystem::SetBakeProperties
to pass the properties to the bake system. - For each instance in that system, create a
Enlighten BakeInputMeshInfo
object filling out the fields appropriately, and then callIBakeInputSystem::AddMesh()
. - 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
- 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. - Next, copy lighting information into an
IBakeInputLighting
object. - Now, for each
BakeSystemResource
, create anIBakeVisibilityBuffer
with theIBake
API. This operation is slow; therefore if only the lights have changed (and not the geometry) you can pass in anIBakeVisibilityBuffer
from a previous run and it will be updated. - Call
IBake::BakeSystemDirect()
to create theIBakeOutputSystemDirect
. Optionally pass in aBakeSystemResource
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 IBakeInputSystem
s; there may be more or fewer than this.
Indirect light baking
- Create an
IBakeInputRuntime
and fill it with theRadSystemCore
andInputWorkspace
of each Enlighten system. - 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 theIBakeInputSystem
to the resolution of the Enlighten lightmap via anIBakeInputProperties
object passed to theIBakeInputSystem::SetBakeProperties
method. - For each Enlighten system, call
IBake::CreateRuntimeLighting
to create anIBakeRuntimeLighting
from:- the
IBakeInputSystem
that you just made - the
IPrecompSystemDuster
- the
IPrecompPackedSystem
- the global
IBakeInputLighting
- the
- For each runtime lighting you made:
- For each bake system representing the output lightmaps:
- Call
IBake::UpdateRuntimeLighting
to apply the light and albedo information for each bake system to the Enlighten system.
- Call
- Call
IBake::FinaliseRuntimeLighting
- For each bake system representing the output lightmaps:
- 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. - For each bake system, call
IBake::BakeSystemIndirect
and extract the indirect lighting from theIBakeOutputSystemIndirect
it creates. Optionally pass in aBakeSystemResource
object and aIBakeInputRayOriginPositions
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.
- For each
IBakeInputSystem
, callIBake::BakeSystemFinalGather
. - Extract the FP16 output textures from the resulting
IBakeOutputSystemFinalGather
objects.
Ambient occlusion
- For each
BakeSystemResource
, callIBake::BakeSystemAO
. - Extract the FP16 output textures from the resulting
IBakeOutputSystemAO
objects.
Direct light baking for probes
- First, copy lighting information into an
IBakeInputLighting
object. - Now, for each probe set represented by an
IPrecompInputProbeSet
, create anIBakeVisibilityBuffer
with theIBake
API. You also need to pass in aBakeSystemResource
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 anIBakeVisibilityBuffer
from a previous run and it will be updated. - Call
IBake::BakeProbeSetDirect()
to create theIBakeOutputProbeSet
. Use theIBakeOutputProbeSet::GetOutput()
method to retrieve the SH coefficients of all probes in the probe set.
Indirect light baking for probes
- First follow the steps described in Indirect light baking.
- Now, for each probe in a probe set, use the
IBakeSolvedRuntime::GetSolvedProbe()
method ofIBakeSolvedRuntime
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)
- For each
BakeInputSystem
, callIBake::BakeSystemRadiosityNormal
, providing theBakeSolvedRuntime
for all Enlighten systems. - 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.