?

Log in

No account? Create an account
nyaload

Журнал Пушыстого

Журнал Пушыстого

Previous Entry Share Flag Next Entry
Оптимизация размера графики в казуалках
nyaload
_winnie
В казуалках есть одна штука, в которой есть месту техническому теку - это пайплайн, хорошо сжимающий графику. Кто-то считает что необоснованно "пользователю всё равно сколько скачать, 10 мегабайт или 100, он не разбирается", кто-то считает что важно "+10 % к размеру - минус 1% пользователей", ну и видел даму которая не скачивает игры с большим размером "потому что долго ждать".

В mahjongg artifacts встала задача засунуть в небольшой объём много графики - 50 бэков и комиксов 1024x768, плюс всё остальное (музыку, графику, exe).

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

Ну, атласинг - это типично.

Ещё один трюк: rgb-канал - жмется в jpg, а альфа канал - в 64 отенках серого png. Для rgb-канала применяется особый трюк, который продолжает rgb-канал в область прозрачности, таким образом сжатие в jpg не портит резкие границы (границы в rgb размываются, и остаются только в альфа-канале):


И ещё один ультимейт-трюк: в комиксах при выставлении максимального jpeg-сжатия (0% в фотошопе) комикс выглядит в 80% части нормально. Но в некоторых важных местах для человеческого зрения - глаза, губы, пальцы, сюжетные элементы - ужасно. jpeg-изображение состоит из блоков 16x16. Не вопрос, пишем тулзу в которой указываем какие квадратики 16x16 надо сжимать хорошо, и в игровом коде рисуем эти квадратики-заплатки поверх плохого Jpeg:
Как выглядят патчи:






Редактор:




см. так же про то, как удобней сделать интерфейс рисования спрайтов


  • 1
Круто! Очень понравилась идея с выборочным сжатие жпега (кстати, блоки ж 8х8 всегда были?)

В проекте для социалки использую атласинг и png8 с поддержкой альфа-палитры (очень много анимации)

> (кстати, блоки ж 8х8 всегда были?)
jpeg переводит rgb в Y+cr (интенсивность + цвет,цвет), и затем использует 16x16 для цвета и 8х8 для интенсивности (можно настраивать в продвинутых тулзах).

А не удобнее ли не рисовать заплатки поверх, а чуток влезть в упаковщик jpeg и прописать в нём качество не глобально, а по квадратам?

Распаковку при этом можно использовать стандартную, насколько я помню.

Хотя если речь идёт о комиксах - я бы скорее задумался о сжатии по принципу djvu. Отдельно контуры (с высоким разрешением, алгоритм - не на DCT, а PPM-подобный), отдельно заливку (с низким).

В теории блоки можно подменять лишь в случае если quantization table у обоих jpeg'ов совпадают, не знаю возможно ли такое на практике.

Кстати, если квадраты патчей рисуются поверх, то зачем эти самые квадраты оставляются в основной картинке, а не заменяются на «радикальный чёрный цвет»?

А, всё, увидел коммент, что заменяются, просто поздно :)

Да, были времена, прошли, былинные, ни былин, ни эпосов, ни эпопей.
Четыре года назад было очевидно за что биться, сейчас даже и не знаю.

Кстати, рецепты самостоятельно придумывались или наскребались с миру по нитке?

Отличные рецепты! Понравились манипуляции с JPEG.

1. А почему надо именно JPEG, если распаковка все равно кастомная фактически?
в современных видеокодеах стоп-кадры пакуются с адаптивной квантизацией, как раз для этого.
2. Зачем редактор? Почему бы не определять по уровню шума автоматически эти квадратики?


Ну и "размытие" rgb канала это must-have для любых игр с текстурами с альфой, по понятным причинам. Ничего специфически казуального нету.

1) слишком сложной возни с jpeg-декодером не хотелось. Ну вот собственно код который рисует патчики - оно кастомная распаковка, на экране показа комикса нет смысла экономить FPS.
Функция загрузки текстуры есть, функция "нарисовать квадратик там" есть, 10 строчек на загрузку, 5 строчек на отрисовку, зачем вчитыватся в 1000 строчек libjpeg?

2) уровень шума - это не самая лучшая метрика для определения "человеческий глаз видит тут херню". Например, шум на волосах или на облаке может быть очень большой, а шум на глазах или губах меньше.

А почему не взяли JPEG2000, где можно задавать разную степень сжатия для разных областей из коробки?

Я пробовал Jpeg2000, при сильном сжатии артефакты размытия выглядели неприятней, чем шум от обычного JPEG из фотошопа.

У тебя ж вроде раньше были другие однотемные посты (про MA точно писал). Поставил бы на них один тег, толе.

А что за алгоритм использован для запаковки шрифта? Я даже представить себе не могу, как можно спрессовать литеры так плотно.

Алгоритм "тетрис", сортируем по фигурки высоте (пробовались разные эвристики, по ширине, по площади, по диагонали, по сумме).
Затем полный перебор width/height, только оптимизированный, что бы найти прямоугольник наименьшей площади.

Для компьютерных игр - всё в несжатый BMP и в solid 7zip архив - обычно результат замечательный.

Алгоритмы с потерей данных могут дать лучшую степень сжатия, чем алгоритмы без потерь. BMP + 7zip - это хорошо, но если нужно еще выиграть процентов 10-15, то уже начинаешь читить.

Сколько удается таким образом выиграть?
В байтах и в процентах, пожалуйста.

я вообще удивлён, почему формат "JPG+PNGalpha" не стал стандартом. Реализуется легко, в браузерах давно востребован.

Маджонг Артифакт игрушка мне понравилась, когда играл несколько лет назад. Насчет заплаток артифактов мне кажется это извращение, гораздо лучше использовать wavelet-сжатие, например, библиотеку для работы по стандарту JPEG2000. Ведь сейчас даже в видео используется wavelet-сжатие, которое имеет гораздо меньше артифактов.

Пробовал Jpeg2000, не знаю почему но в одинаковых по размеру файлах jpeg смотрелся лучше. В JPEG2000 было сильное размытие, а в JPEG - шум и ореолы, которые приемлемы, в отличие от размытия.

  • 1