Skip to content

Format of PBR materials

NightFox edited this page Apr 11, 2024 · 10 revisions

Materials repository https://rtxash.omgwtf.ru/Half-Life-RTX/Half-Life-PBR

Structure

In the directory of the mod (valve etc.) put the folder pbr, here is its structure:

  • /pbr/
    • /materials.mat — global file for base materials.
    • /wadname.wad/wadname.mat — materials to replace the textures of a specific wad file (if it is specified in the map).
    • /maps/mapname.bsp/mapname.mat — materials used only on the specific map.
    • /models/modelname.mdl/modelname.mat — file for a specific model.
    • /sprites/spritename.spr/spritename.mat — file for a specific sprite.
    • /env/skyboxname.mat — file for a specific skybox.

As already understood, each .mat file can include other material files through a directive:

"include" "path/filename.mat"

Up to 4 levels of nesting are supported.

The materials.mat itself consists of repeating blocks of the form:

{
"for" "c2a3_gar3"
"basecolor_map" "c2a3_gar3.png"
"normal_map" "c2a3_gar3_normal.png"
"metal_map" "/colors/black.png"
"roughness_map" "c2a3_gar3_roughness.png"
}

Where {} is the block boundary and the content itself is in the simple format "key" "value".

The value of the key "for" describes the name of the texture to be replaced. To replace the texture of the map just specify its name from the wad file (or prescribed inside the map, which can be viewed through the command r_infotool 1 or through the program newbspguy) and that's all. To replace the texture model or sprite need to run the game with the keys -dev 2 -log and in engine.log find records related to the desired textures, there will be a full path of this type:

[2021:11:25|23:25:01] Uploading texture #models/v_357/bluesteelchrome.mdl, mips=7
[2021:11:25|23:25:01] Uploading texture #sprites/laserdot(frame:00).spr, mips=5

This is the path "#models/v_357/bluesteelchrome.mdl" and "#sprites/laserdot(frame:00).spr" must be entered after "for". Then you can specify the textures manually by analogy. The names of the textures of the models can be obtained through the viewer HLMV/HLAM, and sprites are in the folder /sprites/ (you can look through SprView). For sprites you just need to remember that if the sprite without animation he still need to prescribe (frame:00) in the path for the value "for".

Next come the maps (textures) themselves to replace the original texture. The texture size step is 16 pixels. All textures at this point must be 8bit RGB(A) PNG. 16bits/sample are not suitable yet, nor is grayscale likely. That is, export textures from (for example) Substance B2M will need to be squeezed to 8 bits per channel.

Keys

"for_rendermode" for which rendering mode to apply the parameters, the default is "kRenderNormal". "kRenderTransColor", "kRenderTransTexture", "kRenderGlow", "kRenderTransAlpha", "kRenderTransAdd" are available. Usually translucent objects are "kRenderTransTexture".

"basecolor_map" base color, albedo, similar to a diffuse texture only without extra highlights and shadows (they are done through the normal map), that is, it is devoid of visual volume, as if we have a completely flat surface in front of us.

"normal_map" a normal map, which is just describing the light shape of the object, the normal has an opengl format, that is, the light areas on top.

"metal_map" a metallic map, grayscale, describes where the metal (white) or dielectric (black) should be contained.

"roughness_map" roughness map, grayscale, indicates where in which part of the texture there should be reflections, the darker the more glossy the surface will be, the lighter the matte.

Also available:

"base_color" "R G B A" to set the color without texture (useful for debugging/simple metals/correcting an existing texture), where R G B A is red green blue alpha, the data is in floating point format, 0 to 1.

"metalness" "V" to specify metal or dielectric surface, where V is a value of 1 (metal) or 0 (dielectric), also for intensity (metal_map * V).

"roughness" "V" to specify roughness, where V is a floating point value from 0 (completely smooth) to 1 (completely rough), also for intensity (roughness_map * V).

"normal_scale" "V" to specify normalmap intensity, where V is a floating point value from 0 (no normalmap) to x (normalmap * x).

Only the "basecolor_map" is available for sprites, the other textures will be ignored.

A detailed description of the properties of PBR material maps can be read here.

After the key any map the path to it is specified in the value. A path starting with / leads to the root /pbr/. A path starting without / leads to the subdirectory in which the involved materials.mat is located. Relative paths are possible (e.g. you can refer to textures in subdirectories).

Other keys:

  • "force_reload" "1" which is written in a block of desired texture (immediately the next line after the "for" "texture" otherwise it will not work) for her quick reload via the console command rt_debug_reload_patches (you can key in, for example bind g rt_debug_reload_patches).
  • "new" "materialname" to create a new material that can be reused (by "inherit") or if the texture does not exist on the map. To patch textures, declare inside /maps/mapname.bsp/mapname.mat and then in /luchiki/maps/mapname.patch set _xvk_material with this name.
  • "inherit" "materialname" using material parameters for some texture.

Skyboxes

For HDR skyboxes there is a mat file of the same skyname

  • "exposure" "V" where V is exposure
  • "sun_solid_angle" "V" where V is angle in steradians (adjusts the blurring of shadows from light_environment)

Testing without ray tracing support

Testing PBR materials without rays is possible via the vk_use_material_textures 0|1 command, but needs a gamma patch:

diff --git a/ref/vk/vk_materials.c b/ref/vk/vk_materials.c
index 2f68e0f8..08ea71ed 100644
--- a/ref/vk/vk_materials.c
+++ b/ref/vk/vk_materials.c
@@ -277,7 +277,8 @@ static void loadMaterialsFromFile( const char *filename, int depth ) {
                                } \
                        } while(0)

-                       LOAD_TEXTURE_FOR(basecolor_map, tex_base_color, kColorspaceNative);
+                       //LOAD_TEXTURE_FOR(basecolor_map, tex_base_color, kColorspaceNative);
+                       LOAD_TEXTURE_FOR(basecolor_map, tex_base_color, kColorspaceGamma);
                        LOAD_TEXTURE_FOR(normal_map, tex_normalmap, kColorspaceLinear);
                        LOAD_TEXTURE_FOR(metal_map, tex_metalness, kColorspaceLinear);
                        LOAD_TEXTURE_FOR(roughness_map, tex_roughness, kColorspaceLinear);

This only shows the base textures, no normal maps or anything else.