2015-05-29 2 views
0

У меня есть некоторые проблемы с организацией различных умножений матриц для реализации графика сцены для моей сцены WebGL.Как реализовать граф сцены в WebGL

До сих пор я использовал иметь три матрицы, то projectionMatrix, то viewMatrix и modelMatrix (The normalMatrix в сторону), которые multiplicated в том же порядке. У меня также есть узел -объект, который содержит в основном всю информацию, необходимую для рисования.

В то время как projectionMatrix и viewMatrix обновляются по отдельности с помощью drawScene -функции, то modelMatrix равен каждый узел localMatrix, которые - с каждым рисунком-вызовом - устанавливаются равному идентичности а затем преобразовал то, что я хочу.

Узлы хранятся в массиве (nodeList), и когда вызывается функция drawScene -function, я прохожу через этот список и расскажу каждому узлу о том, как рисовать себя.

Теперь я прочитал учебник для реализации графа сцены в WebGL на www.webglfundamentals.org и попытался добавить эту функцию в моей сцене -функции, но хотя этот учебник очень хорошо написано, я все еще немного запутался из как это сделать.

После этого урока, каждый узел должен иметь не только localMatrix, но и worldMatrix. Затем, если узел является корень элементная (то есть, когда он не имеет родительского-узла), их localMatrix и их worldMatrix идентичны, в противном случае, если является родитель-узел, то worldMatrix ребенка-узла вычисляется путем умножения их localMatrix с worldMatrix их родителя-узла, так что worldMatrix каждого узла является то, что в моем прежнем коде, используемом, чтобы быть modelMatrix/localMatrix.

Может быть, я просто не могу видеть лес за деревьями, но я спрашиваю себя, где и когда для вызова функции для обновления всемирно матрицы узлов и когда установить матрицы обратно идентичности , один раз для всех, только для корневого узла или для каждого узла отдельно?

Я имею в виду, что код, указанный в этом учебнике, делает это путем рекурсивного прохождения через все дочерние узлы узла, но мой nodeList -array не отражает потенциальные иерархические отношения узлов и с каждым вызовом чертежа, локальный -матрицы возвращаются к личность. Таким образом, он не может работать таким образом, не так ли?

ответ

2

EDIT

К сожалению мой предыдущий ответ был о чем-то другом, и это не будет реализован таким образом, в руководстве (к сожалению).

который - с каждым призывом к вызову - устанавливается в идентичность, а затем преобразуется так, как я хочу.

Зачем вы устанавливаете что-либо обратно в личность? Вы не должны этого делать.

но мой nodeList -array не отражает потенциальные иерархические отношения узлов и с каждым проборки вызова, местные-матрицы устанавливаются обратно идентичности. Таким образом, он не может работать таким образом, не так ли?

Цель графика сцены - упростить и избежать дополнительных математических операций. Для этого требуются узлы в иерархии деревьев.

Initialization

Чтобы не иметь узлов из учебника:

var node = { 
    localMatrix: ..., // the "local" matrix for this node 
    worldMatrix: ..., // the "world" matrix for this node 
    children: [],  // array of children 
    thingToDraw: ??, // thing to draw at this node 
}; 

Тогда у вас есть две вещи, корневой узел всей сцены и nodeList где важные узлы (эти, которые могут быть преобразованы в будущем) ,

var rootNode = new Node(); 
var nodeList = []; 

Теперь поместите все вещи в иерархию узлов, все узлы являются частью rootNode. И те, которые могут трансформироваться в будущем, сохраняются в nodeList.

Этапы являются повторением для каждого tick()

Этап 1 - обновление

обновления местоположения всех элементов, которые вы хотите, а это значит забрать вещи из Nodelist и преобразования localMatrix. Вы ничего не делаете с родителями или детьми.

Stage 2 - найти мир позиция

Когда все обновления сделаны, необходимо пересчитать все worldMatrices. Это означает уничтожить старые worldMatrix и создать новый. Вы делаете это с помощью rootNode.updateWorldMatrix(). Это будет идти сверху вниз и вычислять новый worldMatrix для каждого узла в дереве на основе родительской worldMatrix и узла localMatrix. Он не меняет localMatrix.

Этап 3 - drawcall

Теперь мы возвращаемся к старой известной проекции, вид и модель матрицы. Сделайте что-то вроде rootNode.draw(), которое является рекурсивной функцией, которая будет рисовать каждый узел в иерархии. Модельная матрица = worldMatrix.

О

Как вы видите, нет setIdentity в весь процесс (worldmatrix может быть установлен в идентичности InstEd быть destoried, но я не вижу никаких преимуществ в этом). Плохая вещь об этом - если у вас есть лес, полный деревьев, а деревья не двигаются, ни земля, ни одно дерево в любом случае не пересчитывает свое мировое положение. Этого можно предотвратить, добавив этап 1 и 2 и расширяющий узел с флагом.

РЕДАКТИРОВАТЬ 2

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

Сценарий делает только одно, он изменяет каждую базовую точку моделей от чего-то статического (= статическое положение, например, 0,0,0), к чему-то относительному (другое положение модели).

Каждая модель все еще имеет свою собственную матрицу модели, которая представляет собой ее преобразование из базовой точки.

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

Это именно то, что вы можете и должны делать! Matrix 4x4 содержит 16 номеров и имеет предопределенные операции. Положение, вращение и масштаб - 3 вектора, каждый из которых имеет 3 числа, что составляет 9 чисел, и они представляют текущее состояние модели (в 3D, в 2D мы имеем разные преобразования). Мы объединили их в один mat4, поэтому mat4 содержит текущее состояние модели, и нам больше не нужно поддерживать 3 вектора, все в матрице.

Matrix used to describe 3D transformation

Когда вы звоните mat4.translate(), mat4.rotate(), mat4.scale() вы transfrom модель. mat4.multiply(mat4) применяется не только к одному, но и к множеству преобразований.

Кроме того, матрица была разработана to not have its operations commutative! matA * matB! = MatB * matA. Это очень полезно, например, если вы сначала повернете камеру и затем переведите ее, она будет двигаться в направлении, которое она ищет. Иногда вы этого не хотите, но большую часть времени вы этого хотите.

В случае, если вы этого не хотите, вы установите матрицу обратно на личность, которая сбрасывает модель по умолчанию и затем выполняет преобразование так, как вы хотите.

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

В графе сцены также есть мировое положение для каждой модели, которая представляет собой сумму всех предыдущих родительских матриц и матриц модели. Он не позволяет делать все умножения для каждой модели отдельно, поэтому очень глубокие модели simbling doenst требуют большого количества умножений. Это важно, представьте, что вам нужно делать все умножения 60 раз в секунду, и все это с процессором.

Это не из моего ума, все, что связано с матрицами, является родным в GLSL.Графические карты готовы работать с матрицами.

Я имею в виду, вы уже признали, что я не так много в матрицу-математических

Вы не должны, вам просто нужно использовать 4 функции: перемещение, вращение, масштаб и и знать, что состояние модели представляет собой одну матрицу, и это все. Все позади - это быть в черном ящике. Вам не нужно знать, как получить расстояние модели от матрицы, вам просто нужно знать: как только вы будете делать modelviewprojectionmatrix * vertex, модель будет отображаться.

+0

Hello Entity Black! Не зная концепцию _abstract-node_, это то, что я делал до сих пор: я не упоминал об этом в вопросе, но в моем _node_-объекте у меня также есть опция для дополнительного _parentNode_, который является только матрицы и не содержит информации о рисовании материала. Но я хочу, чтобы мой код был более переменным, так что можно установить родительские-дочерние отношения произвольной глубины. Решение, представленное на ** www.webglfundamentals.org **, похоже, именно то, что я хочу (я имею в виду, чтобы сказать узел, _not_ рисовать что-то, и только макеты с вычислениями не так велики) ... –

+0

... Я также понимаю концепцию того, как это делается, но я изо всех сил стараюсь сделать последний шаг и отредактировать код из учебника до моих существующих функций: не проблема устанавливать отношения родитель-потомок (это очень похоже на DOM , не так ли), но я прошу себя _when_ и _where_ обновлять матрицы. Я имею в виду, что в моей прежней модели это было легко, потому что узлы matrix-calcs не влияли на другие матрицы узлов (только локальная и _local_-parent-matrix), поэтому во время рисования я мог просто пропустить мою " nodeList' и сообщить каждому узлу, чтобы вычислить их матрицу (или матрицы), а затем нарисовать себя ... –

+0

... но, делая это, при каждом вызове рисования локальная и _local_-родительская матрица возвращаются к _identity_. Итак, когда, с одной стороны, функция обновления _world-matrices_ проходит рекурсивно через всех дочерних узлов узла, а с другой стороны, матрицы узлов возвращаются к _identity_ с каждым вызовом чертежа перед преобразованием, предыдущий расчеты будут недействительными. Поэтому возникает вопрос о том, когда и где следует вызывать функции (update) для «updateWorldMatrix» и когда устанавливать матрицы обратно в _identity_. –

Смежные вопросы