У меня есть вопрос относительно того, как Unity3D обрабатывает импорт файлов .obj. Я импортирую этот чайник: http://groups.csail.mit.edu/graphics/classes/6.837/F03/models/teapot.obj
Число вершин этого чайника составляет 3644. Я знаю, что класс Mesh в Unity должен реплицировать эти вершины для каждой грани, разделяемой одной и той же вершиной. Я попробовал это с кубом, импортированным из .obj, и с помощью Debug.Log (), чтобы напечатать количество вершин, я обнаружил, что в массиве вершин меша было 24 вершины.
Однако в чайнике исходный файл имел 3644 вершины, поэтому в Unity число вершин должно составлять 18960. Вместо этого, когда я печатаю длину массива вершин меша, он печатает 3260 (даже меньше, чем исходный файл).
Конечная цель этого заключается в том, что я пытаюсь модифицировать скрипт OBJ Importer из вики Unity, чтобы число вершин, полученных из этого скрипта, было таким же, как и у собственного импортера Unity. Ссылка: http://wiki.unity3d.com/index.php?title=ObjImporter Примечание. С помощью этого импортера я распечатал количество вершин, и результат составил 18960.
У кого-нибудь есть представление о том, как можно добиться сокращения вершин?
Ответы:
Есть несколько факторов, которые способствуют тому, как геометрия сохраняется и обрабатывается в различных средах (программы, форматы файлов, API). Я реализовал несколько коммерческих программ анализа геометрии, поэтому у меня есть некоторый опыт в этом.
Во-первых, я уверен, что это не имеет ничего общего с Unity, упрощающим что-либо. Но в случае, если есть, есть несколько алгоритмов прореживания, которые могут быть реализованы, но я уверен, это не так, поскольку игровой движок не должен изменять форму (геометрические свойства меша), но обычно может изменять его связность. чтобы соответствовать его оптимальной структуре.
Вот некоторые из этих факторов:
Что делает вершину уникальной?
Это может сильно различаться в зависимости от того, как программа, API или формат файла работает с вершиной. Вершина может быть уникальной, если она имеет уникальную позицию, но в других случаях она уникальна, если у нее есть какой-либо уникальный атрибут. Например, если две вершины разделяют одну и ту же позицию, но имеют разные нормали, их следует «дублировать» в случае OpenGL, это особенно очевидно в случае упомянутого вами куба.
Хард против гладких краев.
Нормальные значения могут определять, считается ли ребро жестким или гладким, если вершина вносит вклад в резкое ребро, то ее необходимо дублировать, чтобы текущие API-интерфейсы рендеринга могли понять, как правильно визуализировать (заштриховать) эту грань.
индексы
Многие форматы файлов позволяют вершинам грани иметь несколько индексов для позиции вершины / texCoords / normals, это не относится к текущим API рендеринга. Прекрасным примером этого является файл Obj, который заставит Unity перестроить индексы и часто дублировать многие атрибуты, чтобы соответствовать индексам вершин.
связь
Многие вершины, которые на самом деле связаны и являются уникальными, сохраняются многократно, это связано с тем, как оригинальный обработчик файлов обрабатывал и сохранял сетку. Unity уменьшит количество дублирующихся вершин (помните, если у него другой атрибут, тогда он не уникален), чтобы сделать его более эффективным для хранения и обработки без ущерба для качества.
Это также связано с тем, сколько сторон многоугольника разрешает исходный файл, например, Obj разрешает многоугольники N-стороны, чего не хочет ни один здравомыслящий игровой движок, так что в итоге он триангулирует сетку и пересчитывает многие из его атрибутов, которые часто изменить количество вершин.
источник
Форматы Obj особенно странны, потому что позиции, нормали и координаты текстуры разделены, и каждая грань может выбрать любой индекс из каждого потока. Когда вы ссылаетесь на счетчик вершин, вы думаете, что количество вершин и нормалей не совпадают, и вы не можете ссылаться на весь счетчик.
Во время загрузки все эти три атрибута должны быть объединены вместе, чтобы одна позиция вершины могла закончиться дублированно, потому что грань, связанная с этой позицией вершины, связана с двумя нормалями . Это может происходить и в обратном порядке, поэтому у большинства загрузчиков есть шаг для оптимизации объекта, но в случае вашего куба оптимизация не будет работать, так как у куба есть жесткие ребра и каждая вершина имеет свою нормаль (или координату текстуры). Вот почему вы насчитали 6 позиций вершин, но единица дублировала эти позиции, в результате чего получилось 24 вершины.
Чтобы загрузить сетку, вы можете дублировать положения / нормали или координаты текстуры, поэтому оптимизировать это не просто. Это сводится к выбору минимального количества дубликатов из этих трех потоков.
источник