Разбор форматов: 3d-модели изнутри

    image

    Еще одна статья о разборе форматов, для летнего воскресного вечера, небольшая и развлекательная. На этот раз речь пойдёт о 3d-моделях. Принципы хранения данных для любых моделей одинаковы, но форматы файлов весьма разнообразны. Даже в условиях одного и того же движка разработчики норовят всё модифицировать и впихнуть что-нибудь своё, ведь в коммерческих версиях у них есть возможность менять код движка, и они ей обычно пользуются.

    Основной объём любого файла с моделью составляют несколько больших таблиц с данными о вершинах, о том, как они соединяются и как на них натягиваются текстуры. Начнём с вершин. Простой список с координатами x,y,z может выглядеть например так:



    Так как чаще всего координаты лежат в виде 32-битных плавающих чисел, их легко распознать внутри файла по повторяющимся через 4 байта цифрам в диапазоне 40-45, или для отрицательных чисел C0-C5. Конечно встречаются и другие байты, но эти чаще всего. Так происходит потому, что диапазон координат 3d-модели небольшой с точки зрения порядка, а порядок как раз хранится в старшем байте.

    Далее, нужна таблица, где указано, в каком порядке вершины соединяются в треугольники. Чаще всего она выглядит так:



    Это 16-битные номера вершин, группами по три. Так как в моделях обычно не более нескольких сотен вершин, числа эти маленькие, и такую таблицу тоже легко видно визуально. В данном примере выделен один из треугольников, состоящий из вершин с номерами 50,51 и 52.

    И третья — таблица текстурных координат, чтобы привязать вершины к плоской текстуре, которую нужно на них натянуть.



    Координаты x и y в пределах текстуры приводятся к диапазону от 0 до 1, и если текстура имеет размер 2048x2048 или 4096x4096, нет смысла в высокой точности. Поэтому они чаще всего хранятся как плавающие числа с половинной точностью, 16 битные. Старший байт у них получается чуть больше 0x30, изредка доходя до 0x40 или чуть больше. Здесь красным и оранжевым выделены текстурные координаты, зеленым и светло-зеленым — координаты на карте освещения.

    После того, как найдены эти таблицы, можно посчитать количество элементов, найти, где это количество хранится и как описывается вся структура. Но кроме этих таблиц в файле обязательно найдутся много мелких непонятных чисел, которые неизвестно к чему относятся и что означают. Вот например, в середине файла с моделью человека имеются три плавающих единицы (выделены зеленым):



    Как узнать, что они обозначают? Да просто поменять их и посмотреть, что получится. Запишем вместо них 1,5 и запустим игру



    Ну конечно, это масштаб. Интересный эффект получается от того, что анимация записана в других файлах отдельно, и она завязана на координаты в моделях, поэтому возникают такие причудливые уродцы. У мужчины на площади на плечах сидит ребенок. Теперь он оказался у него внутри грудной клетки. Человек перед шлагбаумом, совершающий непонятные движения, на самом деле аплодирует.

    Теперь попробуем определить, где здесь ширина, а где высота. Изменим только одно число, первое: уменьшим его в 10 раз.



    Таким образом, экспериментируя, можно определить значение оставшихся чисел. Если же при изменении каких-то из них ничего не происходит, просто оставим их в покое. Может быть мы никогда не узнаем, зачем они нужны. А если вдруг однажды они дадут о себе знать — тогда и будем разбираться.

    Вот один из примеров, когда разобрать формат файла аналитически бывает легче и быстрее, чем изучать exe-шник, где можно заблудиться в дебрях кода, скармливающего всю эту информацию видеоподсистеме.
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 12

      0
      Аналогичным образом в свое время разобрал формат карт для Периметра.
      Но все гораздо хуже в проектах, которые следят за целостностью файлов или как-то пакуют данные.
      Правда последнее время большинство разработчиков этого не делают, потому что аппаратные ресурсы практически безграничные, а шифроваться нет смысла, т.к. модо-творчество — путь к второй жизни игры.
        +2
        Упаковка сейчас очень широко используется. Пример был в прошлой статье: habrahabr.ru/post/261561
          0
          Мне кажется это скорее исключение.
          Я на своей практике встречал игру в которой данные не просто паковались, а еще и шифровались… Но это тоже скорее исключение. :)
          Как правило данные лежат в виде максимально комфортном для быстрой загрузки, что существенно упрощает их обработку.
            +1
            По моему опыту, наоборот. Большинство «больших» игр пакует либо все ресурсы, либо за исключением видео и звука, которые всё равно сильно не сжимаются.
              +1
              >> либо за исключением видео и звука, которые всё равно сильно не сжимаются
              Они _уже_ пожаты. Кто-то хранит голый wave, или видео в виде последовательности .tga? =)
                0
                Речь не о том, «пожаты» они сами по себе или нет. Я просто сказал, что есть игры, которые пакуют всё. Для примера возьмем такую известную серию как Doom/Quake. Все ресурсы, включая звук, одной кучей упакованы в zip-архив.
              0
              Внешняя память всегда самая медленная — практически всегда быстрее прочитать небольшой блок упакованных данных одним куском и потом распаковать его в значительно больший объем данных для использования в оперативной памяти.
          0
          Реверс-инженеринг 3д форматов впервые делал в Elite для ZX-Spectrum. Там 3д модели кораблей были простые, разобраться было несложно. Наделал кучку совершенно других моделей, было весело.
          Сейчас реверс-инженеринг с последующим ковырянием модели в hex-едиторе выглядит как-то по-детски. Гораздо проще выдрать модель целиком и отредактировать ее в соответствующем редакторе.
          Тем более, что на самом деле гораздо удобнее взять редактор моделей, который подходит для определенного движка, и модели поправить в нем.
          Также можно создать в нем простейшие модели каких-либо фигур, и реверсить на них, а не на таких сложных моделях как фигура человека со всеми его формами.
            +1
            Никто не говорит о редактировании модели в HEX редакторе.
            Речь о том, чтобы разобрать формат и потом сделать импортер/экспортер, например.
              0
              Импортёр — ладно. Но для экспортёра понадобится знать, что прописывать в те самые магические числа, смысла которых понять не удалось. Если новая модель будет хотя бы иногда показывать что-то правдоподобное — то уже повезло. Но скорее всего, при небольшом изменении топологии или числа вершин/треугольников всё сломается так, что не разберёшь.
              +3
              Я потому и написал в самом начале, что разработчики модифицируют движки. Ни один редактор обычно не подходит.
              +1
              Что-то маловато написали.
              Думаю, стоит упомянуть ещё несколько таблиц, которые тоже бывают: нормали (возможно со знаком бинормали в третьем компоненте), веса костей для скелетной анимации. Ещё текстурных координат может быть два набора (для стационарной геометрии).

              Таблицы могут записываться как отдельно, так и вперемешку (то есть все компоненты вершины описывается одной записью), так как во втором случае производительность несколько выше.

              Ещё могут быть лоды, описания габартных контейнеров, сам скелет с иерархией костей и т.д.

              Only users with full accounts can post comments. Log in, please.