Bake Ambient Occlusion
Ambient occlusion (AO) is a rendering technique increasing realism by simulating real-world shadowing. To limit the computational cost in your real time application, you can precompute the self occlusion of an object, and store these values to a dedicated texture.
Read time 3 minutesLast updated 21 hours ago
API functions:
- algo.beginBakingSession
- algo.endBakingSession
- algo.bakeAOMap
- algo.filterMeshVertexColors
- algo.convertNormalMap
- material.filterAO

Computation
Similarly to any other map baking, ambient occlusion can be baked thanks to the dedicated function algo.bakeAOMap called within a session lifecycle:Occlusions are detected by ray tracing, where the number of rays cast for each texel is given by the parametersessionId = algo.beginBakingSession(destinations, sources, 0, 1024)aoMaps = algo.bakeAOMap(sessionId, samples = 32)algo.endBakingSession(sessionId)
samples
Depending on the required map resolution and number of samples, ambient occlusion computation can be time consuming. It is strongly recommended, if possible, to enable the GPU back-end for this operation.
Note however that samples are generated so as to ensure a blue noise distribution of the error in texture space, which has pretty nice properties:
- Error is scattered in such a way that it is perceptually less significant,
- It shows good behavior with respect to smoothing (see Filtering).
![]() | ![]() | ![]() |
|---|---|---|
| 8 spp | 16 spp | 32 spp |
Bent normals
The bent normal at a given surface point corresponds to the axis of the cone defined by non-occluded directions. It is used by some rendering engines for advanced shadowing techniques.
If the flag is enabled, the returned list contains both AO and bent normal maps, stored in an interleaved manner:aoMaps = algo.bakeAOMap(sessionId, samples = 32, bentNormals = True)
- : first AO map
aoMaps[0] - : first bent normal map
aoMaps[1] - : second AO map
aoMaps[2] - : second bent normal map
aoMaps[3] - ...
Filtering
Filtering AO baked to a texture map
To get a smoother result without requiring to drastically increase the number of samples, the ambient occlusion map can be filtered by using function material.filterAO, which preserves signal discontinuities by combining three Gaussian blurs, respectively depending on:- texel coordinates (controlled by parameter ),
sigmaPos - ambient occlusion or bent normal values (controlled by parameter ),
sigmaValue - normal orientations (controlled by parameter ).
sigmaNormal
The following image illustrates the effect of each component of the filter:sessionId = algo.beginBakingSession(destinations, sources, 0, 1024)# normalMaps = [normalMap[0], ..., normalMap[n-1]]normalMaps = algo.bakeNormalMap(sessionId)# aoMaps = [AOMap[0], bentNormalMap[0], ..., AOMap[n-1], bentNormalMap[n-1]]aoMaps = algo.bakeAOMap(sessionId, samples = 32, bentNormals = True)algo.endBakingSession(sessionId)# filteredAO = filtered copy of both ambient occlusion and bent normal maps.filteredAO = material.filterAO(aoMaps, normalMaps) # apply filter with default values.
![]() | ![]() | ![]() | ![]() |
|---|---|---|---|
| 16 spp No filtering | | | |
Filtering AO baked to vertex colors
When ambient occlusion is baked to mesh vertex colors, the function algo.filterMeshVertexColors can be used to smooth the result similarly to the process described above: it combines different filters in order to reduce noise in the signal while preserving features.sessionId = algo.beginVertexBakingSession([destination], sources)algo.bakeAOMap(sessionId, samples = 128)algo.endBakingSession(sessionId)meshes = scene.getPartOccurrences(destination)algo.filterMeshVertexColors(meshes) # apply filter with default values.aoValues = algo.getMeshVertexColors(meshes)





