Closed 0x4E69676874466F78 closed 7 months ago
Для DDS с BC7 нужно просто смержиться со свежим мастером.
Заметки:
FORMAT_BC1_RGB_UNORM_BLOCK
FORMAT_BC1_RGB_SRGB_BLOCK
FORMAT_BC1_RGBA_UNORM_BLOCK
FORMAT_BC1_RGBA_SRGB_BLOCK
FORMAT_BC2_UNORM_BLOCK
FORMAT_BC2_SRGB_BLOCK
FORMAT_BC3_UNORM_BLOCK
FORMAT_BC3_SRGB_BLOCK
FORMAT_BC4_UNORM_BLOCK
FORMAT_BC4_SNORM_BLOCK
FORMAT_BC5_UNORM_BLOCK
FORMAT_BC5_SNORM_BLOCK
FORMAT_BC6H_UFLOAT_BLOCK
FORMAT_BC6H_SFLOAT_BLOCK
FORMAT_BC7_UNORM_BLOCK
FORMAT_BC7_SRGB_BLOCK
Предварительно:
Что касается вариантов UNORM/SNORM, UNORM/SRGB и UFLOAT/SFLOAT я пока не знаю какие лучше. Сompressonator даже не заявляет какой именно у него BC7, для остальных варианты есть.
Чем сжимать: https://github.com/GPUOpen-Tools/compressonator/ https://github.com/GameTechDev/ISPCTextureCompressor/ надо собирать самому
- Для normalmap BC5 два канала сжатые блоками BC4, потребуется восстановить компонент Z в пиксельном шейдере
Почему именно BC5? (интересно)
- Для теста 16бит-нормалей тоже можно попробовать BC6H либо безсжатия ARGB_16F.
Без сжатия жирно (хотя KTX2 умеет тупо в zlib/zstd внутри, но это надо писать)
Что касается вариантов UNORM/SNORM, UNORM/SRGB и UFLOAT/SFLOAT я пока не знаю какие лучше. Сompressonator даже не заявляет какой именно у него BC7, для остальных варианты есть.
Для roughness и metallic UNORM, они в 0..1 диапазоне Для basecolor SRGB может быть нужен только если детали тёмные сохранить, иначе UNORM естественней тупо сразу линейный для освещения. Для нормалей мы сейчас тоже сидим на UNORM, поэтому UFLOAT проще. Надо смотреть, будет ли удобнее/проще математика на SFLOAT/SNORM.
Можно попробовать всякое и сравнить.
Ага, в нормалях мы там фигакс руками из UNORM в SFLOAT (вот эти *2. - 1.
): https://github.com/w23/xash3d-fwgs/blob/6bfa4c90fac80ce8a56b47e491f6cd07530a2804/ref/vk/shaders/ray_primary_hit.glsl#L48
Поэтому можно сразу SNORM/SFLOAT
(там, кстати, normal_shading
отломана для баунсов и для else
)
Почему именно BC5? (интересно)
Ну там два канала хорошего качества. Народ рекомедует. Вот ещё можно почитать: https://www.reedbeta.com/blog/understanding-bcn-texture-compression-formats/
Для basecolor SRGB может быть нужен только если детали тёмные сохранить
У нас текстуры SRGB, тёмные детали хорошо бы сохранить, мы уже наелись с гаммой вдоволь. Но вообще надо глянуть во что там конкретно сохраняют тузлы. Я до практической только-только подступаю.
(там, кстати, normal_shading отломана для баунсов и для else)
Поэтому у нас там артефакты с чернотой?
У нас текстуры SRGB, тёмные детали хорошо бы сохранить, мы уже наелись с гаммой вдоволь.
Кстати, нет. Мы UNORM
: https://github.com/w23/xash3d-fwgs/blob/6bfa4c90fac80ce8a56b47e491f6cd07530a2804/ref/vk/vk_textures.c#L346
Для родных текстур там 1998 год и что попало с гаммой, а вот с пбр пнг текстурами почему оно не шакалит, это сюрприз (или шакалит?)
(там, кстати, normal_shading отломана для баунсов и для else)
Поэтому у нас там артефакты с чернотой?
Не, это другое.
@w23 ты не забывай что мы делаем преобразование в линейное пространство (SRGBtoLINEAR), а потом в конце делаем гамма-коррекцию (LINEARtoSRGB).
А это строго говоря неправильно. Потому что так оно би/трилинейную интерполяцию в текстурном блоке в srgb неуклюже делает
А это строго говоря неправильно. Потому что так оно би/трилинейную интерполяцию в текстурном блоке в srgb неуклюже делает
У нас тогда было всё довольно плохо, сейчас оно хотя бы ожидаемо работает и выглядит хорошо.
Вариант с переделать принимаемый формат на SRGB и убрать SRGBtoLINEAR возможен, но есть нюанс. https://github.com/search?q=repo%3Aw23%2Fxash3d-fwgs%20SRGBtoLINEAR&type=code
Возможно сейчас удастся безболезненно, но не факт. Там потенциальная проблема здесь:
Это точно нельзя делать втупую, нужно тестировать не уедет ли гамма у текстур.
Чтобы примерно понять в чём проблема прочитай комментарии начиная отсюда: https://github.com/w23/xash3d-fwgs/issues/321#issuecomment-1003203617 Не помню пытались ли мы сделать сразу SRGB (вроде да, но тогда не было должного понимания), но можно как-нибудь повторить.
Ну там да, имея "умеренно корректный" вид сейчас, план может быть примерно такой:
_SRGB
, и убрать ручную конверсию._UNORM
(или даже _SNORM
попробовать для нормалей). Это надо будет явно указывать при загрузке текстур для PBR материалов.Кстати говоря, всё вышесказанное является необходимым для корректной загрузки KTX2. Если не сделать, получится несогласованный шлак.
Загрузку из PNG бы при этом ещё не сломать. Если играться с этим предлагаю сначала на PNG убедиться что всё правильно.
Без сжатия жирно (хотя KTX2 умеет тупо в zlib/zstd внутри, но это надо писать)
У compressonator есть кстати такой вариант
BRLG Lossless Compression using Brotli-G
Интересно, но малоприменимо. Brotli-G:
У KTX2 есть расширяемый режим "а запакуй конкретно данные изображений чем-то". Для этого "чем-то" есть в прям стандарте zlib, zstd, суперкомпрессия эта от universal basis, и ещё какая-то проприетарщина "напишите нам".
zlib поддержать должно быть просто -- в ксаше уже, вроде, есть miniz. В крайнем случае libz есть везде. zstd тоже нетрудно. universal basis крестовый, толстый, не всё умеет. В пень.
Мне было бы интересно потом когда-нибудь подрочить своими руками декомпрессию на гпу в стиле http://gamma.cs.unc.edu/GST/gst.pdf, почему-то не нашёл с ходу ничего такого готового опенсорсного. Можно сделать свою либу, лайки гитхабы сабскрайбы цветы поклонницы.
Утверждаем базовую схему:
basecolor(+alpha) BC7 (тот что в compressonator видимо SRGB UNORM, но нам надо SRGB)
normalmap BC5 SNORM
roughness/metalness BC4 UNORM
combined roughness+metalness BC5 UNORM
?
Кстати а как движковые текстуры к нам прилетают? В сыром несжатом виде? По идее их можно было бы BC1 (RGB5:6:5 + 1bit alpha) пожать на лету. Текстуры ещё там прилетают с 4 мипами их тоже можно было бы пожать. Хотя это наверное экономия на спичках?
sRGB linear-vs-gamma situation is a disaster:
Whether to give up and just treat UNORM as SRGB in shaders depends on whether my assumptions about gamma-vs-linear-texture-interpolator are correct. I propose a test: 2x2 black and white texture (checkerboard), scaled to a significant portion of the screen. This means that texture block will do interpolation for us in whatever texture colorspace is specified. Then we upload this same texture twice: in SRGB format and in UNORM/linear format. Then in shader we just read raw values and display them as they are. We can also SRGBtoLINEAR them in the shade too, and compare the results with "hardware" linearization. So, in total, a table 4x4: format srgb-vs-unorm x shader raw-vs-srgb2linear. Results that I expect: only the SRGB format + raw value looks "uniformly" gradient. All other variants are broken.
(We could also play with srgb framebuffer and linear2srgb in the same fashion.)
Утверждаем базовую схему:
- basecolor(+alpha) BC7 (тот что в compressonator видимо ~SRGB~ UNORM, но нам надо SRGB)
Как выяснилось, компрессонатор умеет только в UNORM, в BC7_SRGB
он не умеет, имея только ошмётки дефайнов для этого формата для DX.
Тут вообще встаёт вопрос, как делает индустрия в целом, потому что выглядит слегонца странно.
- normalmap BC5 SNORM
Почти. Надо:
Для BC6H HDR мы уже выяснили, что он в -1..1 даёт только 10-битную точность. Проверить, достаточно ли. Если недостаточно, то надо руками тогда перенормировать.
- roughness/metalness BC4 UNORM
- combined roughness+metalness BC5 UNORM ?
Вроде так.
Вообще, по вышеперечисленному как-то начинает вырисовываться кастомный пайплайн подготовки текстур, что выглядит подозрительно.
Кстати а как движковые текстуры к нам прилетают? В сыром несжатом виде? По идее их можно было бы BC1 (RGB5:6:5 + 1bit alpha) пожать на лету. Текстуры ещё там прилетают с 4 мипами их тоже можно было бы пожать. Хотя это наверное экономия на спичках?
Они прилетают уже разжатые RGBA32 (если не dds). Для оригинальных текстур это спички, да, там кот наплакал пикселей.
Для наших PNG жиробасов всё же уместнее их было бы более качественно паковать в оффлайне.
Как выяснилось, компрессонатор умеет только в UNORM, в BC7_SRGB он не умеет, имея только ошмётки дефайнов для этого формата для DX.
Существует не только он, я уже нашёл другие проги, но ещё не тестировал, поддержка BC7_UNORM_SRGB там есть. Для compressonator уже создал issue: https://github.com/GPUOpen-Tools/compressonator/issues/277
Тут вообще встаёт вопрос, как делает индустрия в целом, потому что выглядит слегонца странно.
Как понимаю:
Однако у первого варианта есть проблемы, он ограниченный, то есть это не работает если у нас есть в игре градиенты. Допустим в игре есть разные баннеры с рекламой, в рекламе есть градиентный переход, он очевидно сломается и будет выглядеть некрасиво.
Убедиться, что нормалмапа правильно предварительно отнормирована. Если почему-то нет, то отнормировать и перепроверить квантизацию.
Ну я думаю просто сделать обязательный проход нормализации. Даже если она уже была отномирована до этого ничего плохого не произойдёт.
Если уже отнормирована, то значит, что 8-битной точности двух каналов недостаточно. Либо как-то уменьшить диапазон -- ограничить, насколько нормалмапа может влиять на нормаль. Либо искать более качественный формат.
Проверю.
Для BC6H HDR мы уже выяснили, что он в -1..1 даёт только 10-битную точность. Проверить, достаточно ли. Если недостаточно, то надо руками тогда перенормировать.
С этим форматом есть проблема, пока нет корректных средств для генерации таких нормалей (те файлы что я кидал они негодные), мне надо доработать materialize для этого. Пока эта задача отлетает на вторичный план, мало когда нужны 10битные нормали, это скорее задел на будущее.
Вообще, по вышеперечисленному как-то начинает вырисовываться кастомный пайплайн подготовки текстур, что выглядит подозрительно.
Ничего подозрительного, это нормально и решаемо. Я думаю многие вещи сделать через паплайн в chainner и materialize.
Проверил быстро через kram (нет под линя, только винда и макось, но для теста сойдёт), kram encode -format bc7 -srgb -srcsrgb -i debug_gradient_color.png -o debug_gradient_color_BC7_SRGB.ktx2
Подгрузил на srgb-gamma бранче и всё ожидаемо нормализовалось:
На всякий случай проверил через серый градиент что формат вообще подгружается (он подгружается).
Текстуры для теста: debug_gradient_BC7_SRGB.zip
kram можно попробовать портировать под линь, исходники есть.
2x2 black and white texture (checkerboard), scaled to a significant portion of the screen. This means that texture block will do interpolation for us in whatever texture colorspace is specified.
https://github.com/w23/xash3d-fwgs/pull/597#issuecomment-1753975750
- нормали я ещё не нормализовал (кроме где есть приписка _normalize)
Не горит. Мы, если что, сможем и свой нормализатор написать.
- вот debug_dds.zip для тестов DDS, эти текстуры почему-то не грузятся
Поддержка DDS у нас сейчас отсутствует напрочь. Поэтому и просил, чтобы научиться и протестить.
Поддержка DDS у нас сейчас отсутствует напрочь. Поэтому и просил, чтобы научиться и протестить.
Ну в движке она есть, я думал там автоматом грузанёт, но нет.
Обновление схемы отсюда https://github.com/w23/xash3d-fwgs/issues/154#issuecomment-1750885440 Пока не утверждаем, а разбираемся:
Ещё информация:
Рано списал со счетов BC5, всё не так однозначно. Можно сказать что на крайних случаях BC5 не справляется, но BC6H имеет тоже свои артефакты/особенности. Нужно делать больше нормалей и ближе к реальности. Сделаю отдельную карту для этого. BC7 плох для нормалей.
Не знаю стоит ли открывать, но с нормалями мы пока не определись. Лучше всего пока себя показывает BC5 UNORM, но есть нюансы.
Не знаю стоит ли открывать, но с нормалями мы пока не определись. Лучше всего пока себя показывает BC5 UNORM, но есть нюансы.
Разборки с нормалями имо не для этой ишьи. Надо бы открыть отдельную, и резвиться там.
Хорошо, создал #608
uploadTexture()
Ещё вариант: https://github.com/BinomialLLC/basis_universal/