Формат PBR материалов - w23/xash3d-fwgs GitHub Wiki

Репозиторий с материалами https://rtxash.omgwtf.ru/Half-Life-RTX/Half-Life-PBR

Структура

В директорию мода (valve и т.д.) кладётся папка pbr, вот её структура:

  • /pbr/
    • /materials.mat — глобальный файл для базовых материалов.
    • /wadname.wad/wadname.mat — материалы для замены текстур конкретного вад файла (если он задан в карте).
    • /maps/mapname.bsp/mapname.mat — материалы применяемые только на конкретной карте.
    • /models/modelname.mdl/modelname.mat — файл для конкретной модели.
    • /sprites/spritename.spr/spritename.mat — файл для конкретного спрайта.
    • /env/skyboxname.mat — файл для конкретного неба.

Как уже стало понятно, каждый файл .mat может включать в себя другие файлы материалов через директиву:

"include" "путь/названиефайла.mat"

Поддерживается до 4 уровней вложения.

Сам materials.mat состоит из повторяющихся блоков вида:

{
"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"
}

Где {} границы блока, а само содержимое в простом формате "ключ" "значение".

Значение ключа "for" описывает название текстуры которую надо заменить. Чтобы заменить текстуру карты достаточно указать её название из wad файла (или прописанное внутри карты которое можно посмотреть через команду r_infotool 1 либо через программу newbspguy) и всё. Чтобы заменить текстуру модели или спрайта нужно запустить игру с ключами -dev 2 -log и в engine.log найти записи связанные с нужными текстурами, там будет полный путь такого вида:

[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

Вот этот путь "#models/v_357/bluesteelchrome.mdl" и "#sprites/laserdot(frame:00).spr" надо вписывать в значение после "for". Далее можно по аналогии указывать текстуры вручную. Названия текстур моделей можно получить через просмотрщик HLMV, а спрайты лежат в папке /sprites/ (посмотреть можно через SprView). Для спрайтов нужно только помнить что если спрайт без анимации ему всё равно нужно прописать (frame:00) в пути для значения "for".

Далее идут сами карты (текстуры) для замены исходной текстуры. Шаг размера текстуры 16 пикселей. Все текстуры на данный момент должны быть 8бит RGB(A) PNG. 16bits/sample пока не подходят, как и скорее всего grayscale. То есть экспортные текстуры из (например) Substance B2M нужно будет пережимать в 8 бит на канал.

Ключи

"for_rendermode" для какого режима отрисовки применить параметры, по умолчанию "kRenderNormal", доступны "kRenderTransColor", "kRenderTransTexture", "kRenderGlow", "kRenderTransAlpha", "kRenderTransAdd". Обычно полупрозрачные объекты это "kRenderTransTexture".

"basecolor_map" базовый цвет, альбедо, похожа на обычную (diffuse) текстуру только без лишних бликов и теней (они делаются через карту нормали и карту шероховатости), то есть она лишена визуально объёма, будто перед нами совершенно плоская поверхность.

"normal_map" карта нормали, которая как раз описывает световую форму объекта, нормаль имеет формат opengl то есть светлые участки сверху.

"metal_map" карта металлика, ЧБ (она монохромная), описывает в каких местах должен содержаться метал (белый цвет) или диэлектрик (чёрный цвет).

"roughness_map" карта шероховатости, оттенки серого, указывает где в какой части текстуры должны быть отражения, чем темнее тем более глянцевая поверхность будет, чем светлее тем матовая.

Доступны ещё:

"base_color" "R G B A" для задания цвета без текстуры (полезно для отладки/простых металлов/коррекции существующих текстур), где R G B A красный зелёный синий альфаканал, данные в формате плавающей запятой, от 0 до 1.

"metalness" "V" для задания металлическая или диэлектрическая поверхность, где V это значение 1 (металл) или 0 (диэлектрик), кроме этого как интенсивность для "metal_map" (metal_map * V).

"roughness" "V" для задания шероховатости, где V это значение в формате плавающей запятой от 0 (полностью гладкий) до 1 (полностью шероховатый), кроме этого как интенсивность для "roughness_map" (roughness_map * V).

"normal_scale" "V" для задания интенсивности normalmap, где V это значение в формате плавающей запятой от 0 (нет normalmap) до x (normalmap * x).

Для спрайтов доступна только "basecolor_map", остальные текстуры будут проигнорированы.

Подробное описание свойств карт PBR материалов можно прочитать тут.

После ключа той или иной карты указывается в значении путь к ней. Путь начинающийся с / ведёт на корень /pbr/. Путь начинающийся без / ведёт на подкаталог в котором находится задействованный materials.mat. Возможны относительные пути (например можно сослаться на текстуры в подкаталогах).

Другие ключи:

  • "force_reload" "1" который вписывается в блок нужной текстуры (сразу следующей строркой после "for" "текстура" иначе работать не будет) для её быстрой перезагрузки через консольную команду rt_debug_reload_patches (можно забиндить на клавишу, например bind g rt_debug_reload_patches).
  • "new" "texturename" для создания нового материала (можно назначить текстуре через "inherit") или текстуры которой нет на карте. Чтобы запатчить на карте одну текстуру на другую, объявите внутри /maps/mapname.bsp/mapname.mat материал, а потом в /luchiki/maps/mapname.patch задайте _xvk_material с этим именем.
  • "inherit" "materialname" использовать параметры материала для текстуры.

Skyboxes

Для HDR скайбоксов есть одноимённый mat файл

  • "exposure" "V" где V экспозиция
  • "sun_solid_angle" "V" где V угол в стерадианах (регулирует размытость теней от light_environment)

Тестирование без поддержки лучей

Тестирование PBR-материалов без лучей возможно через команду vk_use_material_textures 0|1, но нужен патч на гамму:

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);

При этом показываются только базовые текстуры, без карт нормалей и прочего.