This is the documentation for Enlighten.
Per-mesh lightmaps
Introduction and rationale
You can define a lightmap either for an instance of a geometry, or for each mesh within the geometry that defines an instance, depending on your scene authoring needs.
For some, or possibly all, instances of a given geometry, specifying a geometry containing a single mesh with one corresponding lightmap may be sufficient. For some geometries, however, some or all of the instances in the scene may have certain parts that need to be rendered in great detail and other parts that do not. In this case, with only one mesh and lightmap resolution specified per given geometry instance, the whole instance would have to be rendered at the highest resolution required for any part of it, no matter how small. This could reduce performance in relation to overall output quality unacceptably by requiring Enlighten to compute highly detailed lightmaps for relatively large areas unnecessarily. The need to circumvent this problem leads to the concept of per-mesh lightmaps, where lightmaps are appropriated to individual meshes within geometries, and thus to the various parts of their instances, as required.
Per-mesh lightmap baking using the HLBS
To make use of this facility with the HLBS you need to set up an appropriate .scene
file that you can load into GeoRadiosity to precompute, and then bake the result. The minimum prerequisite is therefore that the .scene
file be set up for baking as specified in the section Defining an HLBS Scene File for Baking on the Baking with the High Level Build System page. This then opens up the possibility of specifying different meshes within the same geometry with lightmap resolutions that differ from each other.
Example
An example .scene
file for a simple scene not set up for baking is shown below:
<?xml version="1.0" encoding="utf-8"?> <scene name="ubox" version="1"> <instance name="ubox_left" systemId="2" paramSet="Interior" geometry="ubox_left" type="Radiosity" position="-1000.0 0.0 0.0" rotation="0.0 0.0 0.0 1.0" /> <instance name="ubox_right" systemId="1" paramSet="Interior" geometry="ubox_right" type="Radiosity" position="1000.0 0.0 0.0" rotation="0.0 0.0 0.0 1.0" /> <volume name="Box01" probesParamSet="Cull_L1"> <resolution x="5" y="5" z="5" /> <size x="929.905" y="1713.1" z="932.167" /> <position x="-467.011" y="-956.056" z="36.7885" /> <basis> <U x="1.0" y="0.0" z="0.0" /> <V x="0.0" y="1.0" z="0.0" /> <N x="0.0" y="0.0" z="1.0" /> </basis> </volume> </scene>
This scene contains the standard ubox
asset, which is composed of two halves, left and right, with one geometry instance corresponding to each half, and each instance having its own .geom
file giving the location of the corresponding mesh. The appearance of the scene when loaded into GeoRadiosity, precomputed and exhibiting radiosity is shown below:
To make a scene available for baking, you need to specify lmName
and lmType
in some way to the HLBS. The standard way to do this is to modify the .scene
file by adding in the lmName
and lmType
attributes and values to the declaration of each geometry instance for which lightmap baking is required, as in the example below:
<?xml version="1.0" encoding="utf-8"?> <scene name="ubox" version="1"> <instance name="ubox_left" systemId="2" paramSet="Interior" geometry="ubox_left" type="Radiosity" lmName="B" lmType="512x512" position="-1000.0 0.0 0.0" rotation="0.0 0.0 0.0 1.0" /> <instance name="ubox_right" systemId="1" paramSet="Interior" geometry="ubox_right" type="Radiosity" lmName="A" lmType="512x512" position="1000.0 0.0 0.0" rotation="0.0 0.0 0.0 1.0" /> <volume name="Box01" probesParamSet="Cull_L1"> <resolution x="5" y="5" z="5" /> <size x="929.905" y="1713.1" z="932.167" /> <position x="-467.011" y="-956.056" z="36.7885" /> <basis> <U x="1.0" y="0.0" z="0.0" /> <V x="0.0" y="1.0" z="0.0" /> <N x="0.0" y="0.0" z="1.0" /> </basis> </volume> </scene>
In general you also need to edit the <scene name>_default.bp
file to be consistent with the lmType
value defined in the .scene
file, by replacing the default designations of bakeParams
name
and resolution
with your chosen values. In this case that means replacing <bakeParams name="256x256" resolution="256 256">
with <bakeParams name="512x512" resolution="512 512">
.
If you do not use the default values and do not also edit the baking parameters (.bp
) file correspondingly, the bake will immediately fail.
The appearance of the corresponding scene set up for baking, loaded into GeoRadiosity, precomputed and baked is shown below:
As it stands, the above example is not yet ready to permit per-mesh lightmap baking, since each instance has defined a single, fixed lightmap resolution, which then applies to the whole of the instance. To have different parts of an instance rendered at different resolutions, the geometry of which it is an instance needs to contain separate meshes corresponding to these different parts, each with the appropriate, corresponding resolution. In practice, this means that the geometry (.geom
) file needs to declare two or more meshes, each with its resolution specified. Each mesh corresponds to a different part of the geometry, and each specified resolution corresponds to the lightmap output resolution for that mesh.
A suitable .scene
file to illustrate this is shown below:
<?xml version="1.0" encoding="utf-8"?> <scene name="World" version="1"> <instance name="uboxA" systemId="1" paramSet="Interior" geometry="uboxConstant" type="Radiosity" lmName="A" lmType="64x64" position="0.0 0.0 -1200.0" rotation="0.0 0.0 0.0 1.0" /> <instance name="uboxB" systemId="2" paramSet="Interior" geometry="uboxConstant" type="Radiosity" lmName="B" lmType="512x512" position="0.0 0.0 0.0" rotation="0.0 0.0 0.0 1.0" /> <instance name="uboxC" systemId="3" paramSet="Interior" geometry="uboxVariable" type="Radiosity" lmName="C" position="0.0 0.0 1200.0" rotation="0.0 0.0 0.0 1.0" /> </scene>
This .scene
file shows three examples of ubox
asset instances: two instances of the geometry uboxConstant
and one instance of the geometry uboxVariable
. Each geometry now corresponds to the whole ubox
, rather than two geometries each providing half of the asset, and each geometry has two meshes; that is, there are two meshes (.pim
files) specified in the corresponding .geom
file, one for each half of the ubox
.
The uboxConstant
geometry instances uboxA
and uboxB
each have a constant, fixed resolution specified throughout (64x64 or 512x512) using the attribute lmType
, as before. By contrast the uboxVariable
instance uboxC
does not have a resolution specified in the .scene
file, however, as this would set a fixed resolution for the whole instance and the intention here is to allow the resolution to vary within the instance. Rather, the .geom
file specifies two meshes, one for each half of the geometry uboxVariable
, and it is in the .geom
file that the respective resolutions are defined via lmType
:
<?xml version="1.0" encoding="utf-8"?> <geom id="" name="uboxVariable" version="4"> <mesh name="ubox_left" filename=".\ubox_left.pim" lmName="Left" lmType="64x64" direct="true" indirect="true" target="true" doAtlassing="false" deferProjection="false" uvChannel="0" lodLevel="0" /> <mesh name="ubox_right" filename=".\ubox_right.pim" lmName="Right" lmType="256x256" direct="true" indirect="true" target="true" doAtlassing="false" deferProjection="false" uvChannel="0" lodLevel="0" /> </geom>
Thus the lightmap output resolution of the left half of the ubox
in this case is set to 64x64 and that of the right half to 256x256.
For comparison, the .geom
file for the uboxConstant
instances is given below:
<?xml version="1.0" encoding="utf-8"?> <geom id="" name="uboxConstant" version="4"> <mesh name="ubox_left" filename=".\ubox_left.dae" lmName="Left" direct="true" indirect="true" target="true" doAtlassing="false" deferProjection="false" uvChannel="0" lodLevel="0" /> <mesh name="ubox_right" filename=".\ubox_right.dae" lmName="Right" direct="true" indirect="true" target="true" doAtlassing="false" deferProjection="false" uvChannel="0" lodLevel="0" /> </geom>
You can see that the lmType
attribute is absent from each mesh declaration as it is set for the whole geometry and all instances thereof in the .scene
file.
Clearly the baking parameters (.bp
) file also needs to be constructed to be consistent with these multiple lightmap output resolutions. This is achieved simply by extension of the previous .bp
file modification example, as illustrated below:
<?xml version="1.0" encoding="utf-8"?> <bakeParamsList version="1"> <bakeParams name="64x64" resolution="64 64" packUVs="false"> </bakeParams> <bakeParams name="256x256" resolution="256 256" packUVs="false"> </bakeParams> <bakeParams name="512x512" resolution="512 512" packUVs="false"> </bakeParams> <bakeParams name="512x512_NoEmissive" resolution="512 512" packUVs="false"> <solver disableEmissive="true" /> </bakeParams> </bakeParamsList>
The above setup yields a three-tier scene, one ubox
per tier, as shown below:
One instance of uboxConstant
has a fixed resolution of 64x64, the other has a resolution of 512x512 and the one instance of uboxVariable
has the left half at a resolution of 64x64 and the right half at a resolution of 256x256, the different resolutions corresponding to those of the left and right meshes respectively. You can see this in the screenshot below showing the baking resolution:
You can clearly see that in the lower tier, the resolution is quite low (64x64) but uniform; in the middle tier it is also uniform, but high (512x512); and in the top tier the left side of the ubox
is rendered at a low resolution (64x64) whereas the right side is rendered at a considerably higher resolution (256x256).
Addendum — further considerations
From the foregoing it would appear that there are two possible, seemingly equivalent, ways of rendering parts of an instance at different resolutions:
(a) Divide the geometry down into sub-geometries and redefine the latter as the new geometries, each with its own instance;
(b) Define multiple meshes within the geometry and take whatever instances are required for the scene.
The latter is in general preferred because multiplying the number of geometries incurs significantly greater computational expense than multiplying meshes distributed among the same number of geometries. This is due to the way Enlighten manipulates geometries. Indeed, per-instance lightmapping adds to computational expense unnecessarily since the same number of meshes for the various regions of all the scene elements is still required, so dividing up the geometries to give one mesh per geometry/instance simply adds significant computational burden for no gain.
Per-mesh lightmap baking is clearly on the whole the much better strategy, particularly if the regions that need rendering in detail are the same for all or many occurrences of an element in a scene — all the similar occurrences simply become instances of one particular geometry. This is the most common scenario.
On the other hand, the case arises occasionally where differently-situated, but otherwise identical scene elements require different lightmap resolution distributions — different mesh sets — due to their situations, and so cannot be implemented as instances of a single, unique geometry. In this case, clearly you have to define different geometries for the different cases, each with its own particular set of meshes. This admittedly does increase the number of geometries; however, it is still found to be generally preferable to per-instance lightmapping, since you still have the same number of meshes, but most often have to generate even more geometries. The exception to this would be a case where a significant proportion of the required sub-areas of the scene elements were reusable among the elements, even though not in the same total arrangement, so that these pieces could be defined as geometries and then instantiated multiple times in varying contexts and combinations among many scene elements.