Pull to refresh

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

Reverse engineering
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-шник, где можно заблудиться в дебрях кода, скармливающего всю эту информацию видеоподсистеме.
Tags:3d-модельплоские людиразбор ресурсовформаты данныхмоддинг
Hubs: Reverse engineering
Total votes 27: ↑24 and ↓3+21
Views32K

Popular right now