In this tutorial, we are going to use RapidCompact CLI to process and optimize materials suited for PBR (Physically Based Rendering) in form of textures of an input mesh. We will also quickly review the PBR workflow in general and apply metallic and roughness values to our output meshes. Physically based rendering is a philosophy in computer graphics that seeks to render graphics in a way that accurately describes light behaviour similar to the real world. Many PBR pipelines have the simulation of photorealism as their goal (although PBR workflows for real-time applications cannot make practical use of all theoretical implementations yet). Even without all the benefits of a completely photo-realistic approach, the PBR concept still delivers more consistent and predictable rendering results than ever before in real-time graphics, and the parameters are pretty intuitive and plausible.
At first we will have a look at the basic principle of the PBR workflow for real-time graphics and how it can add value to 3D visualizations; real-time PBR materials mostly make use of three main areas of research taken from the general approach of physically-based rendering:
In the practical real-time use case, those areas are simplified and described as values from 0 to 1, or as greyscale RGB values from 0 to 255 per pixel, on a texture map.
As a result, we distinguish between Metallic and Roughness maps, describing how metallic a material is (usually 1 or 0) and how light will be diffusively scattered or directly reflected depending on the roughness or smoothness of a surface. In addition, the albedo map describes the color of the diffused light. The following image shows a visual representation of metallic and roughness values:
In this section we will apply basic PBR values to a mesh using the RapidCompact CLI. To get started, just download the sample mesh here. We will create four different material versions for the model.
These materials are just examples which do not necessarily exactly represent the materiality of real objects. However, they illustrate well how the different values interact with each other. Further PBR material parameters for real-world materials such as gold, copper or chrome, can be found here.
For achieving the different materials we have two options:
1.) Writing a config file and entering the different PBR values for each material
2.) Directly adding the values as a part of the CLI command itself
For method 1), just type the following command and write the file into your desired directory:
rpdx --write_config
After that simply open the config in an editor and find the following lines:
"material:defaultBaseColor": "1 1 1",
"material:defaultMetallic": 0.2,
"material:defaultRoughness": 0.4,
Replace these standard values with one out of the following chart corresponding to the four sample materials:
BaseColor | Metallic | Roughness | |
---|---|---|---|
Blue Metal | 0.1 0.1 1.0 | 1.0 | 0.1 |
White Half- Metal | 0.9 0.9 0.9 | 0.5 | 0.25 |
White Porcelain | 0.9 0.9 0.9 | 0.0 | 0.15 |
Blue Rubber | 0.1 0.1 1.0 | 0.0 | 0.7 |
We will now decimate the mesh to a sample count of 5000 faces and output it in the glTF format with the new materiality applied. Run the following command with the config file in place:
rpdx -i dragon.obj -c f:5000 -e dragon.glb
For method 2.), where we directly add the values as part of the command, you can simply ignore the config file creation and insert those commands at the beginning:
-s material:defaultBaseColor "0.1 0.1 1.0" -s material:defaultMetallic 1.0 -s material:defaultRoughness 0.1
The full command then looks like the following:
rpdx -s material:defaultBaseColor "0.1 0.1 1" -s material:defaultMetallic 1 -s material:defaultRoughness 0.1 -i dragon.obj -e dragon.glb
Additionally here is a list of the material settings which you can find in the json config file:
Material Settings
Name | Type | Default | Valid Range | Quick Description |
---|---|---|---|---|
material:defaultMetallic | Real | 0 | {0 .. 1} | default material metallic property |
material:defaultRoughness | Real | 0.5 | {0 .. 1} | default material roughness property |
material:defaultBaseColor | String | 1 1 1 | default material base color |
A more advanced approach to display PBR materials can be achieved by using Texture Maps instead of simple values. The different material properties can be stored in pixels as described in the first section.
The RapidCompact CLI will handle all PBR Texture Map Inputs and is able to convert multiple maps into one UV Atlas. In addition, the glTF formats Roughness/metallic and occlusion Textures will be stored in the respective RGB channels of the Texture file (Red=occlusion; Green=roughness; Blue=metallic)
To illustrate these functions we will go through the whole process of optimizing a mesh with several PBR Texture Maps applied and also cover real time web visualization in a PBR shading environment.
First of all we need the input mesh to start with, it can be downloaded here.
As a next step, we will create a compact glTF 3D Model for Web presentation purposes. In order to achieve that, we simply have to get our config file ready and then execute our optimization as a command in the RapidCompact CLI. At first, we will simply create a config file with the following command:
rpdx --write_config
In order to create the best possible visual outcome while still reducing the file size significantly, some values can be altered. In this case, the most important changes are the file format change for the normal map in addition to the setup of the sample count for the baking process, which enhances the quality of the output normal map quite significantly. To compensate the increase of size due to the chosen png format, we can set the resolution of most maps to 1024, as RapidCompact already uses the available UV atlas space quite efficiently. In the following you can see specific settings of the default config file which we will further optimize for the example model:
Name | Type | Default | Valid Range | Quick Description |
---|---|---|---|---|
baking:normalMapResolution | Int | 2048 | {1 .. 16384} | resolution for baked normal maps |
baking:occlusionMapResolution | Int | 2048 | {1 .. 16384} | resolution for baked AO maps |
baking:roughnessMapResolution | Int | 2048 | {1 .. 16384} | resolution for baked roughness, specular and glossiness maps |
baking:metallicMapResolution | Int | 2048 | {1 .. 16384} | resolution for baked metallic maps |
export:normalMapFormat | String | auto | jpg; png; ktx-basis-etc1s; ktx-basis-uastc | desired output file format for normal maps |
baking:sampleCount | Int | 4 | {1, 4, 8, 16} | number of samples per texel for texture baking |
general:normalsHardAngleDeg | Real | 60 | {0 .. 180} | hard angle (degrees) used for normal generation (0 = everything flat, 180 = everything smooth) |
Now that we identified the most important settings we can start to replace the default values with the custom values from the following table (Alternatively you can find the custom config file within the zip here):
Type | Default | Custom | |
---|---|---|---|
baking:normalMapResolution | Int | 2048 | 1024 |
baking:occlusionMapResolution | Int | 2048 | 1024 |
baking:roughnessMapResolution | Int | 2048 | 1024 |
baking:metallicMapResolution | Int | 2048 | 1024 |
export:normalMapFormat | String | auto | png |
baking:sampleCount | Int | 4 | 8 |
general:normalsHardAngleDeg | Real | 60 | 180 |
After the config file is set up and in place, we can go on by simply typing in the following command in the RapidCompact CLI:
rpdx -i BoomBox.gltf -c f:50% -e Output/BoomBox_compact.gltf
In case you have the already prepared custom config file in place, simply use this command:
rpdx -i BoomBox.gltf --read_config custom_config.json -c f:50% -e Output/BoomBox_compact.gltf
The resulting output files should now look like this:
To further ease the handling of the model, we can simply output a single, self-contained .glb file instead of .gltf. The result will only be about 1MB in size, which is roughly 10x smaller then the input file, and you'll be able to directly view it in Windows 10 (using the mixed reality viewer, or inside applications such as MS Office), for example. If desired, rendered thumbnail images of the new model can be directly created with the RapicCompact CLI. The respective Tutorial can be found here.
In addition, the compact glTF model can be exported as a Web-ready HTML5 viewer, using the following command:
rpdx -i BoomBox.gltf -c f:50% -w web
To have a look at the result in 3D, you can either embed the Web container into your site, for example as an HTML iframe, or zip and upload the web directory to any Web server that will deliver it as static HTML content. The result should look similar to this version:
You will have noticed that the example glTF file comes also with an RMA Texture Map, containing the metallic, roughness and occlusion map in the RGB Color Channels. In real time graphics this is a common approach and the RapidCompact CLI supports working with that kind of Texture Maps. We will now have a very brief look on how to get the individual Texture Maps from an RMA and how RapidCompact uses this approach for example for the gltTF file format.
To unpack the RMA map of the BoomBox.gltf file, simply convert it to the .obj format by using the following command:
rpdx -i .\BoomBox.gltf -e channel_unpacking/BoomBox.obj
The RapidCompact CLI is not only capable of baking Texture Maps it supports internally, it also bakes Generic Textures with arbitrary naming conventions specified by the user. To give an example you can download the Nefertiti Mesh, used in the last Tutorials here.
The difference is that this file comes with a total ammount of 8 Texture Maps containing also 5 generic maps in addition to the base color, normal and occlusion map. After extracting the .zip file you can execute the following command:
rpdx -i nefertiti.obj --read_config baking_config.json -c f:50% -e baked_generic/nefertiti_baked.obj
This should result in an output mesh containing 50% of the input faces and the rebaked 8 input maps:
Note that to make use of baking generic maps with obj files the mtl file has to be altered by adding an arbitrary map category name and after that entering the filepath and name of the generic map. The content of the nefertiti.mtl file can serve as an example in this case:
newmtl generic_maps map_bump normal.jpg norm normal.jpg map_Kd basecolor.jpg map_Ka occlusion.jpg map_height heights.jpg map_thickness thickness.jpg map_translucency translucency.jpg map_cavity cavity.jpg map_curvature curvature.jpg