Нервные клетки не восстанавливаются
Не смотря то, что большинство последующей информации будет о том, как сделать ваши объекты наиболее дружелюбно настроенными к вашему движку, я очень прошу вас не забывать, что вся эта информация – это просто взгляд изнутри на то, как работают некоторые вещи, который вы можете использовать в качестве ориентира, чтобы знать с какой стороны лучше подойти к своей работе. Всё должно происходить естественно прямо в процессе работы и не отнимать у вас много времени.
Экономия своего времени или времени своих коллег является намного более важным ориентиром. Я бы сказал, что если ваша оптимизация повлечёт за собой хотя бы час дополнительной работы, неважно для вас или коллег по цеху, то скорее всего она вам не нужна(если конечно вы будете работать учитывая всё нижеизложенное с самого начала). Дополнительные сто треугольников не заставят количество кадров в секунду упасть ниже плинтуса. Если вы не сэкономите лишнюю отрисовку на объекте который будет активно расклонирован или всё время в кадре, то, скорее всего, оно того не стоит. Ощущение того, что работы идёт гладко позволяет формировать счастливые команды, которые успевают делать намного больше за меньшее время. Не превращайте работу в борьбу для кого бы то ни было(включая себя!). Всегда будьте внимательны к нуждам людей, которые будут работать с продуктами вашего труда.
Само-собой количество различных ухищрений, на которые вы можете пойти, чтобы сэкономить своё время и время своих коллег просто бесконечно, поэтому я даже не буду пытаться рассказать о них здесь.
В начале была точка
Давайте на секунду вспомним геометрию. Когда у нас есть точка, ну…у нас есть точка. Точка – это единица, элемент одномерного пространства. Если мы перейдём к двухмерному пространству, то так же сможем оперировать в нём точками. Однако если мы возьмём две точки, то сможем на их основе построить единственную прямую. Линия – это строительный элемент двухмерного пространства. Но, если присмотреться поближе, то линия это всего лишь бесконечное количество точек выстроенных друг рядом с другом согласно линейной функции. А теперь давайте поднимемся ещё уровнем выше. В трёхмерном пространстве вы вполне можете взаимодействовать и точками(вершинами) и линиями. Но если мы добавим ещё одну точку к тем двум, что определяли линию, то сможем построить плоскость. А плоскость это строительный элемент трёхмерного пространства, с помощью которого мы можем формировать объёмы, которыми мы уже можем любоваться со всех сторон.
Я думаю, что все мы привыкли получать количество треугольников, как самую главную директиву для создания объектов или персонажей. И я думаю, тот факт, что, треугольник является строительным элементом трёхмерного пространства, имеет к этому какое-то отношение.)
Но. Это, исходя из человеческой модели мышления. У нас людей и числа от 0 до 9, но у процессоров не так. У них есть только 0 и 1 – бинарная система – самая простая система исчисления. Для выполнения процессором абсолютно любой задачи, она должна быть разбита на самые маленькие и простейшие подзадачи, которые процессор сможет решать последовательно. И мне жаль, что пришлось вас протащить через такую кучу технических и геометрических аспектов, но это было необходимо, чтобы дать вам понять, что процессоры работают так же и в отношении трёхмерной графики – от простого. И даже не смотря на то, что треугольник является строительной единицей трёхмерного пространства, он всё равно состоит из трёх линий, который в свою очередь определяются тремя точками. Отсюда следует, что экономить стоит не треугольники, а точки. Сейчас кто-нибудь должен воскликнуть: “Какая разница? Ведь чем меньше треугольников, тем меньше получается и вершин!”. И он будет абсолютно прав. Но, к сожалению, количество треугольников не единственная вещь, влияющая на количество вершин. Некоторые процессы умудряются проходить абсолютно незаметно для вас.
Мне очень жаль, что опять приходится это делать, но, держитесь – снова программистские штучки)
Трёхмерная модель хранится в памяти компьютера, как набор объектов структур вершины. Структура, выражаясь объектно ориентированным языком программирования(условно), это некоторое количество функций и данных различного типа организованных в одно целое. Таких “целых” может быть огромное количество и все они будут иметь одинаковый набор аргументов и функций, а различаться будут лишь аргументы, хранящиеся в них. Такие “целые” и называются объектами. С точки зрения программирования, у этого типа организации данных огромная глубина. Вот упрощённый пример того, как выглядит структура:
Vertex structure
{
Vertex Coordinates;
Vertex Color;
Vertex Normals;
UV Coordinates;
};
Очень упрощённо.
Если задуматься, то становится очевидным, что структура вершины должна содержать только необходимую информацию. Любая лишняя информация станет огромной тратой памяти, когда ваша сцена упрётся в пару миллионов вершин.
Вершинная структура включает в себя огромное количество атрибутов, но я буду говорить только о тех, которые касаются художников(потому что о других я ничего не знаю)). Насколько мне известно, количество переменных определённых для вершинной структуры соответствует толок одному набору аргументов. Что это значит для нас, художников? Это значит, что у вершины не может быть двух наборов UV координат или двух нормалей или двух различных материалов. Странно как-то получается, ведь все мы с вами назначали различные группы сглаживания объекту или назначали несколько идентификаторов материала на один объект, и все было в порядке. Или, по крайней мере, выглядело в порядке. Как это возможно? Оказывается, что самый доступный способ присвоить дополнительные атрибуты вершине – это создать ещё одну том же самом месте!
Если немного абстрагироваться от технических подробностей, то это означает, что каждый раз, когда вы назначаете ещё одну группу сглаживания группе полигонов или делаете рёбра жёсткими в майе, то незаметно для вас, количество вершин по границе удваивается. То же самое происходит при создании очередного UV шва и для каждого дополнительного материала, который вы назначаете на объект. Если вы хотите создавать эффективные модели, то вы просто обязаны принимать это во внимание. Ребята в больших компаниях об этом уж точно знают. Unreal Development Kit от Epic автоматически сравнивает количество импортированных и сгенерированных вершин во время импорта, и извещает вас, если цифры различаются больше чем на 25 процентов. Это конечно довольно узкие рамки, в которые нужно вписаться, но никто не говорил, что производить эффективный арт – это легко. Если уж программисты из Epic считают это аспектом, достаточно важным, чтобы проверять его при импорте, том вам стоит, как минимум крепко задуматься об этом.
Соединяя точки
Эта маленькая глава посвящена тому, что не даёт вершинам рассыпаться – рёбрам. То, каким образом они формируют треугольники важно для художника, который стремится производить эффективный арт. И не только потому, что они определяют форму, а ещё и потому что они определяют скорость визуализации этих самых треугольников весьма нетривиальными способами.
Как вы думаете, как отрендерить пиксель, который находится прямо посередине ребра, которое делят два треугольника? И опять решение самое простое. Вам придётся рендерить этот пиксель дважды, для каждого треугольника, а потом смешивать результаты. Что приводит нас к довольно интересной концепции – чем выше плотность сетки, тем больше перерендеренных пикселей мы получим, что значит большее время отрисовки. Если предположить что каждый треугольник объекта станет размером с пиксель, то общего количества пикселей затраченных на отрисовку одного этого объекта хватило бы ещё на полтора-два таких. Но для этого у нас к счастью есть LoDы.
В принципе эти знания не должны никак влиять на то, как вы моделите, однако есть специфические ситуации в которых они послужат вам добрую службу.
Триангуляция – как раз один из таких случаев. То, что тонкие треугольники не совсем хороши для рендера факт довольно широко известный. И это вполне обосновано, когда мы говорим о моделинге в общем. Но, если, говоря о триангуляции, мы скажем, что сделали маленький тонкий треугольник, то это же будет означать, что, тем же самым действием, мы сделали другой треугольник больше. Представьте что будет, если мы будем удаляться от равномерно триангулированной модели: чем меньше становится объект, тем больше становится плотность сетки, а как следствие и шансы многократного рендера одних и тех же пикселей.
Однако если мы отбросим равномерную триангуляцию и позаботимся о том, чтобы каждый треугольник имел наибольшую возможную для себя площадь(и как следствие включал в себя как можно больше пикселей), тогда в итоге мы получим треугольники с последовательно уменьшающимися площадями. И теперь, когда вы вновь попробуете отдалиться от объекта, то увидите, что области с наибольшей плотностью ребёр будут ограничены намного меньшим количество экранных пикселей. Так что, чем меньше становится объект, тем меньше пикселей вам придётся перендеривать. Вы так же можете подойти с обратной стороны и пытаться сделать каждое ребро как можно короче. Это поможет сделать ваши объекты более эффективными и спасёт то время, которое могло быть потрачено на отрисовку одних и тех же пикселей.
Если вы столкнётесь с диллемой – добавить аккуртных скосов(chamfer) по краям объекта, сделать его более гладким, но в тоже время наплодить маленьких треугольников, что вроде как плохо, то я советую вам выбрать вариант, от которого ваша работа визуально выиграет. Это всегда самый важный ориентир. А сотпимизировать лишнего в крайнем случае – дело трёх минут.
Воспользуйтесь поиском по сайту: