Atlasing Modes & Texture Scaling

< previous page next page >

Table of Contents

In this tutorial we are going to explore the available atlasing modes of RapidCompact. Different atlasing modes allow us to configure how RapidCompact should create new texture images for the optimized model. The atlasing mode can be changed through the setting compact:atlasingMode.

Name Type Default Valid Range Quick Description
compact:atlasingMode String separateAlpha {'single', 'separateAlpha', 'separateNormals', 'separateAlphaNormals', 'separateMaterials'} mode used to assign meshes to atlases

There are five different options:

Making Use of Different Atlasing Modes

 back to top

As an example file we will again use the FlightHelmet asset. You can download the glTF file here.

Let us first have a look at the number of input atlases:

As you can see the file comes with 3 textures (base color, normals, ORM) and one atlas per each of the 5 materials, resulting in 15 texture maps.

Now optimize the asset to 25% of the original faces using just the default settings of RapidCompact:

     rpdx -i FlightHelmet.gltf -c f:25% -e compact/FlightHelmet-compact.gltf

The default configuration results in three textures and one atlas corresponding to the flattening mode auto/byOpacity; In this case resulting in 2 atlases and thus 6 texture maps.

This splitting by opacity is useful because we can store the semi-transparent parts (the glasses) in an RGBA image, using the PNG format, while storing the rest of the texture data more efficiently in an RGB image in JPG format. This simple splitting can enable huge savings in the resulting file size of the overall asset.

Note that the texture resolution for the maps of the glasses are considerably smaller than the opaque texture maps. This is the case because RapidCompact automatically scales the texture resolution adaptively corresponding to the occupied surface area in 3d space. See also the following section to understand how to alter this automatic scaling to your needs.

Atlasing Factor

 back to top

A common limitation with the compact operation is the lack of control over number of UV atlases generated. If the input model is completely flattened and uses atlasing mode single this will usually result in one single UV atlas in the output. In contrast if flattening by material or no flattening is utilized the resulting number of UV atlases might be quite large depending on the number of materials or input model respectively.

In order to get more control over the number of output UV atlases, the atlasingFactor setting can be utilized. It will split each generated output atlas by the factor specified. Note that the value entered is not equal to the number of output UV atlases or textures, as this is a factor for dividing rather than a fixed value.

Name Type Default Valid Range Quick Description
compact:atlasingFactor Int 1 {1 .. 10} divide each created atlas into n new atlases

Add the setting to the commandline as follows:

     rpdx -i FlightHelmet.gltf -s compact:atlasingFactor 2 -c f:25% -e compact-atlasingFactor2/FlightHelmet-compact-atlasingFactor2.gltf
As you can see the Atlasing Factor of 2 doubles each material type's (opaque vs transparent) output atlas, resulting in 12 total output textures rather than 6.
Current Limitations: Atlasing Factor is currently not compatible with any file size limit (mb) or any size on screen and will be ignored if used in conjunction with preserve UVs or preserve Tiled UVs Decimation Constraints.

Texture Scaling

 back to top

To get an overview on how RapidCompact scales down the textures according to the surface area in the 3d space, have a look at the following settings available under compact and baking in the config file:

Automatic Texture Scaling With pixelsPerUnitLength

Name Type Default Valid Range Quick Description
compact:pixelsPerUnitLength Real 0 {0 .. inf} number of pixels per unit length (e.g. per meter)

With compact:pixelsPerUnitLength, you can control the automatic texture scaling algorithm of RapidCompact. To enable it, set the setting to a value greater than zero. Once enabled, RapidCompact will then make sure that the resulting maps produce at least the given amount of pixels per spatial unit, when applied to the 3D surface. Example: If your 3D model is given in meters and you set compact:pixelsPerUnitLength to 1000, this means that one square meter of the model would be textured with 1000 x 1000 pixels of texture. Naturally, this method can produce textures that are not having a power-of-2 size (see respective paragraph below).

Note Once an automatic 3D-aware scaling is specified, using a nonzero value for compact:pixelsPerUnitLength, setting the resolutions of individual texture maps manually via baking:baseColorMapResolution (or similar settings for other map types) has no effect.

Using A Fixed Size or Atlas Budget

Above we have seen how to scale texture maps automatically, following their projected 3D size - using compact:pixelsPerUnitLength. Alternatively, when setting compact:pixelsPerUnitLength to zero, we can simply specify a fixed overall number of texels (texel budget) to use for the texture atlases, or, alternatively, specify a single, fixed resolution for all atlases. Naturally, the latter automatic method can produce textures that are not having a power-of-2 size (see respective paragraph below). The following setting allows us to choose between the latter two modes:

Name Type Default Valid Range Quick Description
baking:fixedAtlasResolution Flag false {true, false} if false, each texture's pixel budget is divided by all atlases

This setting will work together with other settings like baking:baseColorMapResolution. When set to false, instead of blindly using the same, specified size for all textures (e.g., for all base color maps), it allows us to still introduce some adaptivity, as in the flight helmet example above, by creating maps of different sizes following their scale on the 3D surface. Example: Let's take the flight helmet asset again, and let's say baking:baseColorMapResolution is set to 2048. When setting baking:fixedAtlasResolution to true, each and every resulting base color texture will then have a size of 204x2048 pixels. However, when setting it to false, the overall budget of 2048x2048 pixels will be spread out amongst the resulting maps, proportional to the space they cover in 3D. A map for the wood and leather parts, for example, will get way over 1000x1000 pixels assigned, while a map for the glasses will have a substantially size, and their areas, when summed up, will in the end all add up to around 2048x2048 pixels.

Power-of-2 Strategies

Name Type Default Valid Range Quick Description
compact:powerOfTwoTextures String ceil {'none', 'ceil', 'floor', 'round'} compact ensures that textures have power of two dimensions

Once texture sizes have been computed automatically, according to the value given via compact:pixelsPerUnitLength or by disabling baking:fixedAtlasResolution, the setting compact:powerOfTwoTextures controls the way RapidCompact chooses the final resolutions for the baked and exported textures. As a default value, there is ceil, which makes sure the resolutions are snapped to the next higher power-of-2 size (eg. from 1023x1023 to 1024x1024, instead of 512x512). The opposite setting would be floor (snapping to the next lower power-of-2 size), and the more adaptive setting is round (snapping to the closest power-of-2 size, can be lower or higher). RapidCompact is also able write out textures with non-power-of-2 resolutions, which is usually more precise with respect to the desired resolution in 3D, but not supported on all rendering platforms. You can choose to disable power-of-2 scaling completely with the setting none, which will produce textures that have the exact optimal resolution that was automatically computed by RapidCompact.

Continuing with the Different Atlasing Modes

back to top

If it is desired to only bake one single atlas in total, but still differenciate between opaque and transparent materials (important for the correct render queue, etc.), we can simply use the atlasing mode single :

     rpdx -i .\FlightHelmet.gltf -s compact:atlasingMode single -c f:25% -e compact-single/FlightHelmet-compact.gltf

The result is now a single atlas, while still preserving transparency in the texture's alpha channel. The corresponding scene elements still stay separate meshes for rendering, due to the flattening mode auto/byOpacity.

In some cases we may want the number of resulting atlases to correspond 1:1 to the number of input materials (one atlas per material). To achieve this, we use the atlasing mode separateMaterials, in combination with the scene flattening mode byMaterial, to make sure all materials stay separate throughout the optimization process:

     rpdx -i .\FlightHelmet.gltf -s flattening:mode byMaterial -s compact:atlasingMode separateMaterials -c f:25% ...

The result now has the same number of materials (and also the same amount of textures) as the input.

Note In order to generate the result above, we had to change the flattening mode. The reason is that the asset gets flattened first before the atlasing modes come into play. To give a better overview on how the modes work internally have a look at the following section.

Atlasing Modes & Flattening

 back to top
Flattening and atlasing modes work on different levels of the asset optimization. However, the outcome of the atlasing process is influenced by the flattening stage. Therefore, depending on the desired output (for example, one texture atlas for each original material), we may have to adapt not only the atlasing mode, but also the flattening mode.

Pixels per Unit Length

 back to top

To put it all together, we can have a look at the flight helmet example and optimize it with the following four settings:

With those settings, we have decided to keep all input meshes separate (flattening:mode none), and also to create a separate atlas for each of their materials (compact:atlasingMode separateMaterials). We have also disabled power-of-2 textures (compact:powerOfTwoTextures none), so that resulting textures will be scaled exactly to match the desired resolution of 1024 pixels per unit on the 3D surface (compact:pixelsPerUnitLength 1024). The result looks like the following:

Results of optimization, keeping input meshes and materials all separate and scaling the resulting texture atlases according to their respective occupied surface area in 3D.

< previous page next page >