Pull to refresh

Comments 9

Меньше кода — больше слов. Простыня кода не понятна и не интересна. Хотелось бы лучше пошагового пояснения алгоритма работы.
Хотя бы простыни кода под спойлеры засунуть, уже будет лучше.
Эм. Какая-то у вас не каноническая реализация матрицы.
Во-первых, насколько я понял, матрица в вашем понятии — это «геометрия» в понятиях большинства движков. Т.е. описание объекта. Однако у вас он описывается в виде несвязных точек, и алгоритм, по которому рисовать грани и повехрности, не понятен.
Во-вторых. WebGL из коробки содержит в себе матрицы поворота и перехода, объединяя это все в матрицу проекции. Гораздо грамотнее было бы хранить у вашего объекта параметры этих матриц и перекидывать в встроенные, а не поворачивать объект ручками.
switch(xyzType){ case "byX":
Ужас. Лучше было бы разнести на три функции, rotateByX, rotateByY и rotateByZ, поскольку передавать этот параметр как строку — плохой тон. Если в плюсах можно задефайнить эти переменные, то тут же этот код сложно рефакторить, и когда-то можно банально забыть написание, потом вспоминать, в общем, не лучший подход.

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

В идеале, если включать сюда матрицы поворота и перехода, то это должно выглядеть так:
У вас хранится исходная геометрия. Когда вы вызываете повороты и прочее — у вас собирается матрица проекции, которая является результатом последовательного умножения матриц, соответствующих вызываемым операция (например, rotateByX, move, scale (к слову, о scale забыли), rotateByZ и так далее). И в функции update вы формируете новый массив точек, перемножая исходный (а не предыдущий!) на эту матрицу перехода.
Почему в иделале?
Во-первых, просто расширять функционал. Проще комбинировать операции.
Во-вторых, операция умножения каждой точки на матрицу будет вызываться только один раз на все операции.
В-третьих, можно будет достаточно просто переделать этот функционал на встроенный, который работает на порядок быстрее, чем js.
При работе над ошибками
rotateByX, rotateByY и rotateByZ — Я эти методы добавлю в примитивы.
Пока у меня у примитива
есть методы
rotateAroundCenter, rotateAroundPoint, rotateAroundMaxPoint, rotateAroundMinPoint, мне просто пока как то так легче, чем если сделать
rotateAroundCenterByX, rotateAroundCenterByY, rotateAroundCenterByZ, rotateAroundPointByX, rotateAroundPointByY, rotateAroundPointByZ,…

Можно, конечно оставить просто rotateAroundPoint и для него сделать эти приставки, но я старался вводить минимум координат. Как мне кажется, система вообще не должна от них зависеть.

По поводу идеальной матрицы…
Я пока до конца не понял.
Подумаю. Мне пока, пока я не дошел до «карты» и «общего мира» не требовалась матрица проекции. Скорее всего при дальнейшей работе столкнусь с данной проблемой, буду иметь виду это замечание.

Спасибо.
www.opengl.org.ru/books/open_gl/chapter2.6.html
Долго не искал, но тут, например, суть ясна.

Смысл в том, что для высокой производительности, все вычислительные операции, связанные с отображениями, переносятся на видеокарту.
Для этого вы отправляете командой PushMatrix последовательность модификаций (повороты, переносы, масштабирование), затем отправляете последовательность точек, приметивов и прочей геометрии. Видеодрайвер (пока не столь важно, каким конкретно образом) самостоятельно применит эти преобразования к каждой вершине. За счет большого количества одновременных потоков производительность повышается до предела. В js же делать афинные преобразования для сложной сцены — глупо, как минимум.

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

Простите, но писать статью о компьютерной графике, не разбираясь в этом самому… ну не хорошо.
Ну извините…

«последовательность точек, примитивов и прочей геометрии» у меня тоже рассчитывается через матрицу, а не вбивается вручную ))). Загвоздка как раз была в этом.
Как идея, чтобы учесть общие замечания. по сколько они сводятся к одному… Это найти способ описать инструкцию формирования примитивов по минимальному кол-ву параметров через данные которые можно передать в шейдеры.

Как самый «топорный» вариант я могу пользоваться своим алгоритмом, чтобы сохранить «последовательность точек, приметивов и прочей геометрии» где-нибудь а потом от кудо-нибудь это всё использовать.

При обрисовки сферы, правда с очень хорошей детализацией (то есть её можно без сильной потери уменьшить в полтора раза) у меня в массив индексов попадает 7200 значений, уменьшив их будет 5000, среди них около 600 (это я очень грубо) лишних, ну это я оставляю для тех, кому интересно найти ошибку в алгоритме сферы…
4400 точек… Ну сам я их буду вбивать…

А так image вроде всё нормально…

И она никак не закрыта от GLSL, если надо её перемещать, поворачивать использую все прелести большого кол-ва ядер GPU — никаких проблем…

У меня просто эта сфера и на JS не то что летает, это какой то сумашедший шарик…
Пока для теста использую requestAnimationFrame
Так вот он только на первых 10 секундах плавно, а потом…
Так вот он только на первых 10 секундах плавно, а потом…

Похоже на простую утечку) Например, накапливаются операции, или типа того.

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

В целом, есть задачи, в которых приходится дублировать вычисления, которые делает GPU — это рассчет коллизий. Но тут свои тонкости, например, дико упрощенная геометрия. Но в этом случае есть смысл строить стек преобразований аналогично тому, что на видеокарте. Чтобы пользоваться им одинаково.
Ужас, первое что приходит в голову, у автора проблема с «матчастью».

К примеру:

При перемещении мы должны у каждой точки объекта изменить нужные координаты на необходимое значение.

Данный подход приемлем только для редактора вершин, не самого передового. На практике убивает все, что дает нам WebGL а вернее OpenGL ES. Так как обычно преобразование координат вершины происходит в вершинном шейдере (VERTEX_SHADER) а не средствами JavaScript браузера. Данные модели тоже не стоит хранить на стороне приложения, для этого есть так называемые VertexBufferObject или в народе VBO, куда записывается массив вершин 3D объекта, и лежит все это на стороне видеокарты, и выводится в разы быстрее.
Если же возникнет непреодолимое желание потрогать данные объекта, то можно разметить их в виде массива в обычную память.

В общем с точки зрения производительности и современных технологий ваше решение не самое удачное.

Здесь я начинаю использовать данную матрицу.

Я использую данную матрицу не только для перемещения объекта, но и для первичного подсчета координат объекта. В дальнейшем нет никаких затруднений данную матрицу совмещать с GLSL механизмами, так как по мимо всего прочего у матрицы остается — .source.

В остальном прошу прощения и спасибо за критику. Меня сподвигло написать серию статей приблизительно следующее:
В «стандартном уроке» от сплошного кода автор начал делить на функции, я решил чуть чуть развить тему упрощения.
Воодушевленный успехом, а особенно когда получился примитив — сфера (я не думал, что он так легко и быстро получится), я решил поделиться простой мыслью.

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

Весь код — это возможно грубая, но просто «черновая» реализация данной идеи.
Это не то, что я должен каждый раз лесть во внутренний механизм webgl, если хочу добавить какой-нибудь объект.

В дальнейшем естественно буду улучшать — с учетом критики в этой и предыдущей статье, а также по мере изучения webgl.
Sign up to leave a comment.

Articles