Open 0x4E69676874466F78 opened 1 year ago
@SNMetamorph
@SNMetamorph
Да, определённо нам надо как-то в этом плане совместимость обеспечить
Начал я думать про то, как нам причесать и лучше организовать материалы. Свалю текущее понимание сюда.
Набор параметров для отрисовки, из которых нужно сварганить материал, выглядит примерно так:
int index
в таблицу текстур, прилетающих из движка. Per-geometry.
Одна и та же текстура может быть использована по-разному в разных контекстах далее. Этот параметр статичный за исключением анимированных текстур у брашей.entity_t
(TBD: откуда? может анимироваться? на что конкретно влияет и не влияет?)С другой стороны, в лучах было бы удобно потреблять описание материала, состоящее из:
base_color_map
(albedo_map
). Текстура, RGBA, [0-1]
.base_color
(albedo
). Цвет, RGBA, [0-1]
. Умножается с цветом текстуры.normal_map
. Текстура, RGB, [0-1]
, нормализованная.normal_scale
. Скаляр, [0-1]
. "Приглушает" нормаль из текстуры.roughness_map
. Текстура, один компонент, [0-1]
.roughness
. Скаляр, [0-1]
, умножается с текстурой.metalness_map
. Текстура, один компонент, [0-1]
(в реальности [0, 1]
без градации?).metalness
. Скаляр, [0-1]
([0,1]
?), умножается с текстурой.transmittance
. Скаляр [0-1]
.refractive_index
. Скаляр [0-1]
.model_color
, RGB, [0-1]
.emissive
. RGB, [0-~1e6]
.emissive_map
в будущем?mode
. Вариант из: Regular
, AlphaTest
, BlendAdd
, BlendMix
. Преломляквы детектятся по transmittance > 0
.Наблюдения:
base_color{,_map}
нужен для всех вариантов вообще.BlendMix
нужны только: base_color{,_map}
и model_color
с альфой. BlendAdd
как BlendMix
но ещё жуёт emissive
.model_color
, emissive
, mode
динамические.model_color
, mode
зависят от энтити и render_mode.emissive
может зависеть от per-surface патчей.Ща покормлю детей и закину сюда про то, как я предлагаю реализовать эту трансформацию, сек.
Поправка: kRenderTransColor
для брашей полностью выключает текстуры, заменяя их на константный цвет. То есть текстуры/материалы могут быть динамические и по этому критерию тоже.
Пока неясно, для чего именно это используется, для какого эффекта, и что нам нужно делать.
Model color. Per-model. Прилетает вместе с entity_t (TBD: откуда? может анимироваться? на что конкретно влияет и не влияет?)
Раньше в ксаше был баг и текстура модели могла быть окрашена (но не заменена сплошным цветом) через ключ rendercolor с соответствующим rendermode, но сейчас этого бага больше нет и модель не может принять цвет теперь в этом плане поведение как и в goldsrc. Анимироваться цвет и раньше насколько я знаю не мог.
metalness_map. Текстура, один компонент, [0-1] (в реальности [0, 1] без градации?).
В реальности градации есть и хардкодить бинарное 0/1 не надо, пусть будет плавающим как сейчас. Иногда это очень полезно в сложных ситуациях.
model_color, RGB, [0-1].
Насколько я понимаю умножение цветом через base_color полностью повторяет это, то есть параметр избыточный по крайней мере в формате материалов.
emissive_map в будущем?
По скорее бы! Хочется моделям добавить эмиссив текстуры, тем же блокам с аккумуляторами для костюма и для "реактора" гауспушки.
Для выбора конечного материала для употребления лучеризатором должен использоваться следующий набор критериев:
"for"
в текущей системе материалов. Статичное.chrome
для студийных моделей. Сейчас там подменяется roughness_map
на серую текстуру. Статичный.render_type
. Нужен для определения режимов полупрозрачности. Динамический.render_mode
. Дело в том, что для разных типов объектов (браши-модели-спрайты-...) mode резолвится в type по-разному, теряя информацию. Это может быть важно (а может и не быть). Динамический.Также не исключено, что нужен будет нелинейный маппинг из blend в transmittance. Но в простом варианте их достаточно перемножить.
В простом варианте можно добавить к материалу параметр "for_type"
, который помимо фильтрации по имени текстуры будет ещё и рендер типу фильтровать. Возможные значения, например: "BlendMixDepth"
, "BlendMix"
, "BlendAdd"
, "BlendAddDepth"
.
metalness_map. Текстура, один компонент, [0-1] (в реальности [0, 1] без градации?).
В реальности градации есть и хардкодить бинарное 0/1 не надо, пусть будет плавающим как сейчас. Иногда это очень полезно в сложных ситуациях.
Ок, оставляем.
model_color, RGB, [0-1].
Насколько я понимаю умножение цветом через base_color полностью повторяет это, то есть параметр избыточный по крайней мере в формате материалов.
Сейчас у нас он есть отдельным параметром в формате материалов. Не знаю, насколько он используется. Выглядит так, что это разные вещи -- один цвет статичный, приглушает базовую текстуру. А другой -- динамический, прилетает из движка.
emissive_map в будущем?
По скорее бы! Хочется моделям добавить эмиссив текстуры, тем же блокам с аккумуляторами для костюма и для "реактора" гауспушки.
Для красоты это добавить просто. Сложно сделать, чтобы оно влияло на освещение нормально, т.к. оно будет ломать семплирование.
Сейчас у нас он есть отдельным параметром в формате материалов. Не знаю, насколько он используется.
model_color? это когда он был добавлен? я не в курсе и он никак там не используется.
А другой -- динамический, прилетает из движка.
Ну как уже выяснили баги больше нет и красить модель не надо для соответствия ксашевому гл даже если там прилетает цвет через ключ энтити.
Для красоты это добавить просто. Сложно сделать, чтобы оно влияло на освещение нормально, т.к. оно будет ломать семплирование.
Ты про то что сложно потекстельно сделать маску для сэмплирования? Ну для начала можно сделать проще, пусть свет считается как из цельного полигона, но визуально освещение ограничено текстелями текстуры. Примерно что я предлагал для обычных светящихся текстур ограничением через эмиссив маски.
Сейчас у нас он есть отдельным параметром в формате материалов. Не знаю, насколько он используется.
model_color? это когда он был добавлен? я не в курсе и он никак там не используется.
Не, model_color
берётся из энтити. base_color
берётся из .mat файла: https://github.com/w23/xash3d-fwgs/blob/aab689a37b95d47632b3526d2018c157aaff34f8/ref/vk/vk_materials.h#L11
А другой -- динамический, прилетает из движка.
Ну как уже выяснили баги больше нет и красить модель не надо для соответствия ксашевому гл даже если там прилетает цвет через ключ энтити.
То есть там цвет вообще не учитывается никак?
Для красоты это добавить просто. Сложно сделать, чтобы оно влияло на освещение нормально, т.к. оно будет ломать семплирование.
Ты про то что сложно потекстельно сделать маску для сэмплирования? Ну для начала можно сделать проще, пусть свет считается как из цельного полигона, но визуально освещение ограничено текстелями текстуры. Примерно что я предлагал для обычных светящихся текстур ограничением через эмиссив маски.
Ага. Это сделать условно быстро.
Всякие другие ишьи, релевантные вот этому всему:
Блин, я балбес, хайджекнул эту issue, которая была про совершенно другое :smiling_face_with_tear:.
Начал пробовать начерновить всякую сыроту, как можно было бы сделать:
# Creates a new material 'mat1' with the same values as 'mat0', but with transmittance set to 0.7
# This material does not patch any existing tex_ids directly, only used if referenced by surface patches, or inherited by other material.
{
"new" "mat1"
"inherit" "mat0"
"transmittance" "0.7"
}
{
"for" "mat2"
"for_rendermode" "TransColor TransTexture"
"for_model" "brush studio" # also possible: beam sprite tri
"mode" "mix"
}
# Any Chrome material will get roughness rewritten to 0.5
{
"for_chrome" "1"
"roughness" "0.5"
}
# Glow
{
"for_rendermode" "Glow"
"for_model" "sprite"
"mode" "glow"
}
Но тут много непонятного:
То есть там цвет вообще не учитывается никак?
Да модель нельзя никак покрасить, рендер-моды можно ставить (но не все работают), рабочие можешь посмотреть через карту test_bug_model_renderassassin, заморозь физику там (playersonly) иначе часть нападут, потому что я заметил была разная работа режимов на cycler энити и monster* энтити. Порядок там такой: 1 стобец 1 ячейка cycler 1 стобец 2 ячейка monster_zombie 2 стобец 1 ячейка cycler 2 стобец 2 ячейка monster_zombie и так далее они чередуются по столбцам. 1 столбец renderamt 0, 2 столбец renderamt 128, 3 столбец renderamt 255 у всех прописан rendercolor 255 0 0 и дальше каждый горизонтальный ряд это rendermode, если идти от игрока то от 0 до 5 (normal, color, texture, glow, solid, additive). У ассасинок порядок повторяется. Как видно по карте сейчас в GL никто не окрашивается как и в goldsrc.
К #211 (и вообще) может быть релевантно https://github.com/FWGS/xash3d-fwgs/pull/729 как я понимаю zgdump не в состоянии закончить, хотя осталось там не много:
1. Вернуть R_ShowTextures в ref api
2. Поправить оформление в texturelib
3. Прикрутить текстуры неба
4. Протестировать текстуры-заглушки
5. Решить, стоит ли оставлять оригинал текстуры в ref_ и вообще для чего оно использовалось раньше
"for_model" "brush studio" # also possible: beam sprite tri
Если такое делать то надо поменять формат у моделей и спрайтов, а то сейчас там:
"for" "#models/v_crowbar/chrome.mdl"
"for" "#sprites/muzzleflash(frame:00).spr"
Возможно можно при
"for_model" "studio"
автоматически подставлять #models в начале и .mdl в конец, получается в материалах достаточно будет написать
"for" "v_crowbar/chrome"
или вовсе
"for" "chrome"
если подумать о автоматической структуре относительно путей (тогда в таком случае и не нужен "for_model" "studio"
в 99,9% случаев), чтобы внутри папки models были уже подпапки типа v_crowbar и т.д. подставлялось оно автоматически внутри v_crowbar.mat, что я хотел изначально, но тогда видимо ты был уставшим/ленивым. Тогда не понадобятся ещё мусорные импорты что мне пришлось наплодить.
Со спрайтами сложнее, так как есть кадры, но можно сделать примерно так же как с моделями только вместо имени текстуры там будут номера кадров, типа:
"for" "00"
То есть внутри папки sprites найти подпапку muzzleflash, внутри там будет muzzleflash.mat где будет этот for с номером кадра.
"mode" "mix"
Что это такое?
"for_model"
Предлагаю переименовать в "for_geom" чтобы не было коллизий смысла, т.к. о моделях обычно думают о студиомоделях, а формат у нас для конечного пользователя.
На тему Glow была идея там не режим подставлять, а кастомный шейдер (пусть и который мы заранее объявили и интегрировали).
В остальном надо смотреть по ходу дела.
Возможно можно при
"for_model" "studio"
автоматически подставлять #models в начале и .mdl в конец, получается в материалах достаточно будет написать"for" "v_crowbar/chrome"
или вовсе"for" "chrome"
если подумать о автоматической структуре относительно путей (тогда в таком случае и не нужен"for_model" "studio"
в 99,9% случаев), чтобы внутри папки models были уже подпапки типа v_crowbar и т.д. подставлялось оно автоматически внутри v_crowbar.mat, что я хотел изначально, но тогда видимо ты был уставшим/ленивым. Тогда не понадобятся ещё мусорные импорты что мне пришлось наплодить.
Пока не очень понимаю, о чём именно идёт речь. Похоже, что это про несколько другую проблему? Покажи мусорные импорты, я попробую разобраться.
Со спрайтами сложнее, так как есть кадры, но можно сделать примерно так же как с моделями только вместо имени текстуры там будут номера кадров, типа:
"for" "00"
То есть внутри папки sprites найти подпапку muzzleflash, внутри там будет muzzleflash.mat где будет этот for с номером кадра.
Про кадры интересная проблема. Это уже какой-то недо-макро-язык нужно тащить. Боюсь, что руками по всем анимациям и кадрам пройтись будет тупо быстрее.
"mode" "mix"
Что это такое?
Это значит, что в лучах цвет этой геометрии должен смешиваться с тем, что за ней: $src \alpha + dst (1-\alpha)$
mode
влияет на то, как данная модель/набор геометрий участвует в отрисовке кадра:
opaque
-- обычный непрозрачный материал со всем набором PBR текстур и параметров. Принимает освещение.alphatest
-- как opaque
, но с alpha test дырками.add
-- аддитив, добавляется к тому, что за ним: $dst + base\_color model\_color \alpha$. Использует только base_color
и model_color
. Не принимает освещение, светится сам безотносительно.mix
-- смешивается с тем, что за ним: $dst (1-\alpha) + base\_color model\_color * \alpha$. Остальное так же, как у add
.translucent
(или какой там корректный термин). Полупрозрачный PBR материал, который может пропускать лучи в себя (стекло, вода, ...).
"for_model"
Предлагаю переименовать в "for_geom" чтобы не было коллизий смысла, т.к. о моделях обычно думают о студиомоделях, а формат у нас для конечного пользователя.
А "for_source" "sprite"
, например?
На тему Glow была идея там не режим подставлять, а кастомный шейдер (пусть и который мы заранее объявили и интегрировали).
Оно там немного распределённое, нет одного простого места, куда воткнуть. Это один ровно случай, впрочем, можно не пытаться обобщать.
В остальном надо смотреть по ходу дела.
Ага, я пока склоняюсь к забить и захардкодить выставление mode
по признакам из rendermode и пр. Потом по мере патчинга выявлять законы и исключения -- будет понятнее, как делать.
Пока не очень понимаю, о чём именно идёт речь. Похоже, что это про несколько другую проблему? Покажи мусорные импорты, я попробую разобраться.
Сейчас у нас для wad файлов не требуется писать импорт, достаточно создать папку с wadname.wad с файлом wadname.wad.mat внутри где уже определять что надо.
В случае же с моделями и спрайтами у нас только по 1 точке входа, models/models.mat и sprites/sprites.mat и внутри этих файлов приходится городить на каждую модель и спрайт по своему импорту, чего в случае с вад файлами делать не нужно. Открой эти файлы поймёшь.
Более того в случае с вад файлами нам надостаточно писать просто имя текстуры, без всяких этих
"#models/v_crowbar/chrome.mdl
и "#sprites/muzzleflash(frame:00).spr"
.
Про кадры интересная проблема. Это уже какой-то недо-макро-язык нужно тащить. Боюсь, что руками по всем анимациям и кадрам пройтись будет тупо быстрее.
Не понимаю тебя какой макро-язык, сейчас мне приходится писать:
// sprites/bexplo.spr/bexplo.spr.mat
{
"for" "#sprites/bexplo(frame:00).spr"
//"basecolor_map" "Frame 0.png"
}
{
"for" "#sprites/bexplo(frame:01).spr"
//"basecolor_map" "Frame 1.png"
}
логичнее писать (когда у нас автоматические импорты как в случае с wad'ами)
// sprites/bexplo.spr/bexplo.spr.mat
{
"for" "00"
//"basecolor_map" "Frame 0.png"
}
{
"for" "01"
//"basecolor_map" "Frame 1.png"
}
На лету сгенерировать из файлового пути и значения for не должно требовать какого-то там макро-языка. то есть из данных
sprites/bexplo.spr/bexplo.spr.mat
"for" "00"
получить
#sprites/bexplo(frame:00).spr
не должно быть сложным. Тем более если делать по схеме wad то у тебя не просто путь у тебя понимание что там произошло определение модели/спрайта поэтому не должно быть нужным писать имя модели/спрайта для for.
А "for_source" "sprite", например?
А чем тебе geom не нравится? geom от geometry (такое сокращение есть в словарях с ожидаемым значением формы и т.п.), всё что ты описал геометрия, но source можно конечно тоже.
Предварительные подробности относительно PrimeXT:
@SNMetamorph хочет расширение vmat, я думаю это не принципиально. https://github.com/SNMetamorph/PrimeXT/issues/160#issuecomment-1457200022 Мы можем поддержать и mat и vmat в принципе.
Поправка: kRenderTransColor для брашей полностью выключает текстуры, заменяя их на константный цвет. То есть текстуры/материалы могут быть динамические и по этому критерию тоже. Пока неясно, для чего именно это используется, для какого эффекта, и что нам нужно делать.
Просто геометрия без текстуры, подозреваю что использовалось исходно как оптимизация, т.к. полупрозрачная текстура дороже. Например встречается в стёклах для труб на одном из уровней.
Подытожим (пишу с точки зрения пользователя). Возможно это лучше перенести в новую issue, а эту закрыть.
Новый формат будет JSON-совместим, это значит что его можно будет распарсить JSON-парсером.
Нужно по аналогии с wad подгружать только необходимые материалы для моделей и спрайтов. Сейчас всегда инклудится всё через
pbr/models/models.mat
и pbr/sprites/sprites.mat
где просто тонны инклудов, от этого нужно уйти.
Движок отдаёт строки в виде:
#models/zombiegibs1/Sci3(Shoe).mdl
#models/zombiegibs1/SCIZOM3_LegBack1.mdl
#sprites/zerogxplode(frame:00).spr
#sprites/zerogxplode(frame:01).spr
У нас ожидаются пути
pbr/models/modelname.mdl/modelname.mat
pbr/sprites/spritename.spr/spritename.mat
В данном случае zombiegibs1
это modelname
, а Sci3(Shoe)
это текстура в zombiegibs1.mdl
, немного неинтутивно.
Со спрайтами проще, zerogxplode
это spritename
.
То есть нужно вычленить из строк имя спрайта и модели после чего подключить соответствующий файл материала.
Ещё для чистоты и удобства поменять бы внутренний формат имени у этих материалов.
Сейчас они указываются ровно так же строкой:
{
"for" "#models/zombiegibs1/Sci3(Shoe).mdl"
//"basecolor_map" "Sci3(Shoe).png"
//"normal_map" "Sci3(Shoe)_normal.png"
//"metal_map" "Sci3(Shoe)_metal.png"
//"roughness_map" "Sci3(Shoe)_roughness.png"
}
{
"for" "#models/zombiegibs1/SCIZOM3_LegBack1.mdl"
//"basecolor_map" "SCIZOM3_LegBack1.png"
//"normal_map" "SCIZOM3_LegBack1_normal.png"
//"metal_map" "SCIZOM3_LegBack1_metal.png"
//"roughness_map" "SCIZOM3_LegBack1_roughness.png"
}
{
"for" "#sprites/zerogxplode(frame:00).spr"
//"basecolor_map" "Frame 0.png"
}
{
"for" "#sprites/zerogxplode(frame:01).spr"
//"basecolor_map" "Frame 1.png"
}
Я предлагаю избавиться от мусора в "for", то есть в случае модели писать:
"for" "Sci3(Shoe)"
то есть сразу имя текстуры модели, т.к. мы уже знаем материал какой модели заинклудили, тем более он содержится даже в имени файла материала.
А в случае спрайта просто писать номер кадра:
"for" "00"
Ситуация ровно та же как с моделью.
Всё по аналогии с wad файлами там мы тоже не указываем путь к wad файлу, а сразу пишем имя текстуры.
Текстуры могут быть подгружены без всяких файлов материалов, для этого достаточно не описывать "for"
для текстуры и создать файлы ИМЯТЕКСТУРЫ_тип.{png,ktx,dds}
, где тип
всевозможные алиасы:
basecolor, albedo, (без _типа считается basecolor, то есть ИМЯТЕКСТУРЫ.dds это basecolor), diffuse
normal, normalmap, norm
roughness, rough
metalness, metallic, metal
height, displacement, hmap
metalroughness, combined, pbr, gloss
emissive, luma
Совершенно отдельный режим работы для совместимости с PrimeXT. Это всё не обязательно делать прямо сейчас, но нужно иметь ввиду.
Теперь непосредственно сам формат материалов.
Допустимые поля:
for
// целевая текстура
for_model_type
// тип целевой геометрии: brush, studio, sprite, triapi
for_rendermode
// режим рендера у геометрии: "kRenderNormal", "kRenderTransColor", "kRenderTransTexture", "kRenderGlow", "kRenderTransAlpha", "kRenderTransAdd"
mode
// вариант из: opaque, alphatest, add, mix, translucent; либо Regular, AlphaTest, BlendAdd, BlendMix: проломления определяются по transmittance > 0 // я не понял что в итоге
material
// имя нового материала
use
// назначение материала текстуре
base_color_map
(albedo_map
) // текстура, RGBA, [0-1]
base_color
(albedo
) // цвет, RGBA, [0-1], умножается с цветом текстуры
normal_map
// текстура, RGB, [0-1], нормализованная
normal_scale
// скаляр, [0-1], "приглушает" нормаль из текстуры
roughness_map
// текстура, один компонент, [0-1]
roughness
// скаляр, [0-1], умножается с текстурой
metalness_map
// текстура, один компонент, [0-1]
metalness
// скаляр, [0-1], умножается с текстурой
transmittance
// скаляр [0-1]
refractive_index
// скаляр [0-1]
emissive
// цвет, RGB, [0-~1e6]
emissive_map
// текстура, RGBA, [0-1]
Создание материала
{
"material": "MAT_NAME",
"base_color_map": "base.png",
"normal_map": "irregular.ktx2",
"base_color": "1 .5 0",
// ...
},
{
"material": "mirror",
"base_color_map": "white",
"base_color": "1 1 1",
"roughness": "0",
"metalness": "1",
// ...
}
Назначение материала на текстуру
{
"for": "+EXIT",
"use": "MAT_NAME"
}
Возможно переопределение:
{
"for": "+EXIT",
"use": "MAT_NAME",
"base_color": "1 0 0"
}
Текстура по прежнему может быть описана без материала. Сложные примеры:
{
"for": "wood",
"for_model_type": "brush",
"for_rendermode": "kRenderTransAlpha",
"use": "mat_glass",
"mode": "translucent",
"base_color_map": "glass2.ktx"
}
{
"for_model_type": "brush",
"for_rendermode": "kRenderTransAlpha",
"mode": "translucent",
"map_normal": "glass1.ktx"
}
Приоритет материалов решается просто, наибольшой полнотой, чем больше критериев тем приоритетнее блок над остальными. Такой подход позволит ещё на одну и ту же текстуру задать разные материалы под каждый режим рендера. Конфликт (более одного варианта на те же самые фильтры) решается правом первого, с предупреждением в консоль/лог о дубликате.
Отдельно про патчи:
Внутри патчей мы меняем текстуру через "_xvk_material" "materialname"
, а "_xvk_texture"
остаётся как вспомогательное для #526 чтобы заменить нужную текстуру на гранях браш-модели на целевой материал.
Подытожим (пишу с точки зрения пользователя). Возможно это лучше перенести в новую issue, а эту закрыть.
Ща погоди я сюда подытожу подытоживание, как я всё понял это, и прокомментирую.
Новый формат будет JSON-совместим, это значит что его можно будет распарсить JSON-парсером.
Это "задача 1" (не в смысле приоритета, а просто номер). Мой комментарий: я бы не хотел делать/тащить сюда json парсер без необходимости. Только если нам кровь из носу надо быть совместимыми с кем-то.
Нужно по аналогии с wad подгружать только необходимые материалы для моделей и спрайтов. Сейчас всегда инклудится всё через
pbr/models/models.mat
иpbr/sprites/sprites.mat
где просто тонны инклудов, от этого нужно уйти. Движок отдаёт строки в виде:#models/zombiegibs1/Sci3(Shoe).mdl
#models/zombiegibs1/SCIZOM3_LegBack1.mdl
#sprites/zerogxplode(frame:00).spr
#sprites/zerogxplode(frame:01).spr
У нас ожидаются путиpbr/models/modelname.mdl/modelname.mat
pbr/sprites/spritename.spr/spritename.mat
В данном случаеzombiegibs1
этоmodelname
, аSci3(Shoe)
это текстура вzombiegibs1.mdl
, немного неинтутивно. Со спрайтами проще,zerogxplode
этоspritename
. То есть нужно вычленить из строк имя спрайта и модели после чего подключить соответствующий файл материала.
Разумно и понятно зачем. Это "задача 2а".
Ещё для чистоты и удобства поменять бы внутренний формат имени у этих материалов. Сейчас они указываются ровно так же строкой:
{ "for" "#models/zombiegibs1/Sci3(Shoe).mdl" //"basecolor_map" "Sci3(Shoe).png" //"normal_map" "Sci3(Shoe)_normal.png" //"metal_map" "Sci3(Shoe)_metal.png" //"roughness_map" "Sci3(Shoe)_roughness.png" } { "for" "#models/zombiegibs1/SCIZOM3_LegBack1.mdl" //"basecolor_map" "SCIZOM3_LegBack1.png" //"normal_map" "SCIZOM3_LegBack1_normal.png" //"metal_map" "SCIZOM3_LegBack1_metal.png" //"roughness_map" "SCIZOM3_LegBack1_roughness.png" }
{ "for" "#sprites/zerogxplode(frame:00).spr" //"basecolor_map" "Frame 0.png" } { "for" "#sprites/zerogxplode(frame:01).spr" //"basecolor_map" "Frame 1.png" }
Я предлагаю избавиться от мусора в "for", то есть в случае модели писать:
"for" "Sci3(Shoe)"
то есть сразу имя текстуры модели, т.к. мы уже знаем материал какой модели заинклудили, тем более он содержится даже в имени файла материала. А в случае спрайта просто писать номер кадра:"for" "00"
Ситуация ровно та же как с моделью. Всё по аналогии с wad файлами там мы тоже не указываем путь к wad файлу, а сразу пишем имя текстуры.
Это "задача 2б". Её чуть сложнее сделать -- загрузка материалов становится контекстно-зависимой. Подозреваю, что её в общем виде сделать будет нетривиально, и по ходу реализации наломаем всякого. Пока предлагаю оставить как есть.
Текстуры могут быть подгружены без всяких файлов материалов, для этого достаточно не описывать
"for"
для текстуры и создать файлыИМЯТЕКСТУРЫ_тип.{png,ktx,dds}
, гдетип
всевозможные алиасы: basecolor, albedo, (без _типа считается basecolor, то есть ИМЯТЕКСТУРЫ.dds это basecolor), diffuse normal, normalmap, norm roughness, rough metalness, metallic, metal height, displacement, hmap metalroughness, combined, pbr, gloss emissive, luma
Это "задача 3".
Совершенно отдельный режим работы для совместимости с PrimeXT. Это всё не обязательно делать прямо сейчас, но нужно иметь ввиду.
1. Требуется поддержать расширение vmat 2. В primext две директории materials с материалами и textures с текстурами. По наличию этих папок и можно будет определить что перед нами PrimeXT и нужно включить другую логику обнаружения материалов и текстур. 3. Внутри папки с материалами есть папки с именами wad файлов, все файлы материалов внутри называются как имена wad-текстур; следовательно нужно будет проверять наличие файлов материалов относительно wad файла; внутри директорий wad нет подпапок; найдя файл материала уже можно получить пути/имена pbr текстур. 4. в моделях могут быть подпапки т.к. в самих моделях допустимы и используются в имени подпапки (в wad так нельзя). 5. fallback если не существует файла с материалом, либо в нём не указан путь до нужных текстур, тогда нужно пытаться их загрузить из пути textures/имятекстуры.dds где у имятекстуры помимо обычного случая есть ещё варианты с суффиксами _norm/_hmap/_luma/_gloss/_pbr, где _norm карта нормали, _hmap высот, _luma свечения, далее _gloss или _pbr упакованная текстура с roughness/metalness.
Это "задача 1" выше -- поддержка совместимых с чем-то внешним форматов.
Теперь непосредственно сам формат материалов. Допустимые поля:
for
// целевая текстураfor_model_type
// тип целевой геометрии: brush, studio, sprite, triapifor_rendermode
// режим рендера у модели: kRenderTransColor, kRenderTransTexture, kRenderTransAlpha, kRenderGlowmode
// вариант из: opaque, alphatest, add, mix, translucent; либо Regular, AlphaTest, BlendAdd, BlendMix: проломления определяются по transmittance > 0 // я не понял что в итогеmaterial
// имя нового материалаuse
// назначение материала текстуреbase_color_map
(albedo_map
) // текстура, RGBA, [0-1]base_color
(albedo
) // цвет, RGBA, [0-1], умножается с цветом текстурыnormal_map
// текстура, RGB, [0-1], нормализованнаяnormal_scale
// скаляр, [0-1], "приглушает" нормаль из текстурыroughness_map
// текстура, один компонент, [0-1]roughness
// скаляр, [0-1], умножается с текстуройmetalness_map
// текстура, один компонент, [0-1]metalness
// скаляр, [0-1], умножается с текстуройtransmittance
// скаляр [0-1]refractive_index
// скаляр [0-1]emissive
// цвет, RGB, [0-~1e6]emissive_map
// текстура, RGBA, [0-1]Создание материала
{ "material": "MAT_NAME", "base_color_map": "base.png", "normal_map": "irregular.ktx2", "base_color": "1 .5 0", // ... }, { "material": "mirror", "base_color_map": "white", "base_color": "1 1 1", "roughness": "0", "metalness": "1", // ... }
Лёгкое причёсывание формата, "задача 4". Тут почти ничего не надо делать, кроме добавления новых полей?
Назначение материала на текстуру
{ "for": "+EXIT", "use": "MAT_NAME" }
Возможно переопределение:
{ "for": "+EXIT", "use": "MAT_NAME", "base_color": "1 0 0" }
Текстура по прежнему может быть описана без материала. Сложные примеры:
{ "for": "wood", "for_model_type": "brush", "for_rendermode": "kRenderTransAlpha", "use": "mat_glass", "mode": "translucent", "base_color_map": "glass2.ktx" }
{ "for_model_type": "brush", "for_rendermode": "kRenderTransAlpha", "mode": "translucent", "map_normal": "glass1.ktx" }
Селектор материалов, "задача 5а"
Приоритет материалов решается просто, наибольшой полнотой, чем больше критериев тем приоритетнее блок над остальными. Такой подход позволит ещё на одну и ту же текстуру задать разные материалы под каждый режим рендера. Конфликт (более одного варианта на те же самые фильтры) решается правом первого, с предупреждением в консоль/лог о дубликате.
Алгоритм селекции материалов, "задача 5б". Это, кстати, нифига не просто. По мере возрастания сложности, варианты:
Отдельно про патчи: Внутри патчей мы меняем текстуру через
"_xvk_material" "materialname"
, а"_xvk_texture"
остаётся как вспомогательное для #526 чтобы заменить нужную текстуру на гранях браш-модели на целевой материал.
Индивидуальные патчи, "задача 6".
Это "задача 1" (не в смысле приоритета, а просто номер). Мой комментарий: я бы не хотел делать/тащить сюда json парсер без необходимости. Только если нам кровь из носу надо быть совместимыми с кем-то.
Нам не нужно тащить JSON-парсер, нам нужно просто соответствовать JSON-формату формально, перечитай выше тред, там про это было исходно. Обработать лишние :
и ,
не должно быть проблемой. В PrimeXT подразумевается JSON.
Вложённость там не подразумевается. Игнорировать [
в начале и ]
в конце не должно быть проблемой.
Это "задача 2б". Её чуть сложнее сделать -- загрузка материалов становится контекстно-зависимой. Подозреваю, что её в общем виде сделать будет нетривиально, и по ходу реализации наломаем всякого. Пока предлагаю оставить как есть.
Нужно больше подробностей. Задачу "задача 2б" можно же решить просто по самим путям разбирая их в процессе. То есть уже есть имя файла и этого достаточно чтобы сформировать строки уровня:
#models/zombiegibs1/Sci3(Shoe).mdl
#sprites/zerogxplode(frame:00).spr
для совпадения в "for".
Или как там работает сравнение у загруженных материалов? Мы могли бы формировать эти строки внутри памяти, типа читаешь из файла одно а в памяти уже сформированная строка как выше.
Лёгкое причёсывание формата, "задача 4". Тут почти ничего не надо делать, кроме добавления новых полей?
Соответствие JSON, переименовка полей, новые поля, всё да.
Алгоритм селекции материалов, "задача 5б". Это, кстати, нифига не просто. По мере возрастания сложности, варианты:
Ну наибольшая полнота это упорядочить правила по полноте и стопать по первому полному совпадению. Мы можем руками упорядочить, но разве сложно отсортировать материалы по правилам? Если реально сложно то забей, я просто буду руками вверху определять нужные материалы по полноте.
@w23 там @lifekilled предлагает добавить ещё параметры френеля и преломления, можно это ещё пробросить до кучи? Нужно только пробросить реализует в шейдере он сам.
@w23 там @lifekilled предлагает добавить ещё параметры френеля и преломления, можно это ещё пробросить до кучи?
А что за параметры френеля?
@SNMetamorph
А что за параметры френеля?
Ну Fresnel. https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-shading/reflection-refraction-fresnel.html https://web.archive.org/web/20230307041737/https://www.dorian-iten.com/fresnel/
Если речь за конкретно параметры то наверное его сила?
Эта картинка на отражении - это Френель. Сонаправленность проскости и взгляда усиливает отражение. Для каждого материала он свой. Можно сделать поле в материале, чтобы просто привязывать к каким-то текстурам и потом уже в шейдере разбираться, как его использовать
Преломление тоже у разных материалов разное. По сути нужны просто поля в материалах, которые будут настраивать дизайнеры. Если будет и то, и то, можно будет делать всё от стекла и до воды.
Но также можно еще и добавить какие-то параметры специально для воды, например, масштаб и высоту волн, чтобы она процедурно анимировалась
Либо действительно прокинуть func_water для drag'n'drop совместимости с модами, а стекло при этом просто захачить
А еще помимо френеля (усиление доли отражений) есть еще и аналогичный эффект у прозрачки, это угол полного отражения. Если смотришь на стекло по касательной с определенным углом, оно полностью перестает пропускать через себя свет и превращается в зеркало. Получается 3 переменных у материала.
Что-то такое. По сути просто дополнительные цифры в материале, которые будут использоваться либо в лучах, либо в PBR рендере без лучей, если сделаем и такое
Я в курсе, что эффект Френеля из себя представляет. Меня волнует, что конкретно там нужно вынести наружу? Ведь я насколько помню в аппроксимации Шлика доступна для модификации только переменная F0 - она обозначает множитель отраженной доли света при нулевом угле между нормалью и вектором направления взгляда. Для воды он равен около 0.1, для других поверхностей типично хардкодят 0.04. Вот про эту штуку речь?
Да, достаточно F0
Полное отражение
Параметры "for_model_type" и "mode" в материалах не будут использоваться. Нам и так понятно какой тип модели перед нами относительно системы материалов (разные директории), они не пересекаются. Если надо патчить triapi-текстуры то опять же отдельная директория. Режим рендера патчиться будет через патчи, то есть выбирается энтити и меняется ей рендермод, т.к. рендермод применяется ко всей энтити целиком.
Недостатки текущего формата материалов:
Нам нужен более удобный формат для унификации с PrimeXT, чтобы не мешать им своими заморочками. Предлагаю немного изменить текущий формат и сделать его JSON-совместимым, по сути всё отличие заключается в наличие двоеточия и запятых в конце. Вложенных структур не планируется, то есть существующий парсер не придётся как-либо ощутимо менять в этом плане. Но помимо этого вводится ещё понятие самих материалов, которые можно указать внутри блока замены текстуры, с этим сложнее.
Суть сводится к объявлению материалов отдельным блоком:
дальше мы внутри блока замены текстуры указываем этот материал:
Внутри блока с "for" по прежнему будут работать строки с параметрами материалов. Это по сути просто взятие параметров из блока материалов и вставка их в блок замены текстуры. Таким образом можно будет переиспользовать одни и те же параметры для разных текстур и где-то переопределить внутри блока "for" параметры из "material", это и так сейчас работает если указывать одинаковые ключи, то возьмётся последний.
Внутри патчей мы можем заменить
"_xvk_texture" "texturename"
на"_xvk_material" "materialname"
.Возможно тут будет проблема у парсера из-за одинакового наименования (я не помню как парсер устроен), если так, то можно внутри блок с "for" использовать
"set_material" "blabla blabla2"
.Минус подхода что придётся держать временную хэшмапу с материалами.