Как обновлять объекты в «Вердж3Д»

Все объекты по умолчанию автоматически обновляют свои матрицы, если они были добавлены на сцену с помощью

var object = new v3d.Object3D(); scene.add(object); или если они являются дочерними объектами другого объекта, который был добавлен в сцену: var object1 = new v3d.Object3D(); var object2 = new v3d.Object3D(); object1.add(object2); scene.add(object1); //object1 and object2 will automatically update their matrices

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

object.matrixAutoUpdate = false; object.updateMatrix();

Геометрические параметры

BufferGeometry

BufferGeometries хранят информацию (такую как позиции вершин, индексы граней, нормали, цвета, UV развертки и любые пользовательские атрибуты) в buffers — то есть, typed arrays. Это делает их в целом быстрее стандартной Геометрии, ценой того, что с ними несколько сложнее работать.

Что касается обновления BufferGeometries, самое важное, что нужно понять, это то, что вы не можете изменять размер буферов (это очень затратно, и эквивалентно созданию новой геометрии). Однако вы можете обновить содержимое буферов.

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

Мы будем использовать пример линии, которая удлиняется во время рендеринга. Мы выделим место в буфере для 500 вершин, но сначала нарисуем только две, используя BufferGeometry.drawRange.

var MAX_POINTS = 500; // geometry var geometry = new v3d.BufferGeometry(); // attributes var positions = new Float32Array(MAX_POINTS * 3); // 3 vertices per point geometry.addAttribute('position', new v3d.BufferAttribute(positions, 3)); // draw range var drawCount = 2; // draw the first 2 points, only geometry.setDrawRange(0, drawCount); // material var material = new v3d.LineBasicMaterial({ color: 0xff0000, linewidth: 2 }); // line var line = new v3d.Line(geometry, material); scene.add(line);

Далее мы произвольно добавим точки к линии, используя паттерн, например:

var positions = line.geometry.attributes.position.array; var x, y, z, index; x = y = z = index = 0; for (var i = 0, l = MAX_POINTS; i < l; i++) { positions[index ++] = x; positions[index ++] = y; positions[index ++] = z; x += (Math.random() - 0.5) * 30; y += (Math.random() - 0.5) * 30; z += (Math.random() - 0.5) * 30; }

Если вы хотите изменить количество точек отображаемых после первого рендеринга, сделайте следующее:

line.geometry.setDrawRange(0, newValue);

Если вы хотите изменить значения данных о позиции после первого рендеринга, вам необходимо установить параметр needsUpdate следующим образом:

line.geometry.attributes.position.needsUpdate = true; // required after the first render

Если вы измените значения данных о положении после первоначального рендеринга, вам может потребоваться вызвать .computeBoundingSphere(), чтобы заново рассчитать геометрическую сферу.

line.geometry.computeBoundingSphere();

[link:http://jsfiddle.net/w67tzfhx/ Здесь показана анимированная строка, которую вы можете адаптировать к своему кейсу.

Примеры:

WebGL / custom / attributes
WebGL / buffergeometry / custom / attributes / particles

Geometry

Следующие флаги управляют обновлением различных атрибутов геометрии. Флаги устанавливаются только при изменении буферов, эти флаги автоматически сбрасываются обратно в false. Вам нужно постоянно устанавливать их в true, если вы хотите продолжать обновлять буферы. Обратите внимание, что это относится только к Geometry, но не к BufferGeometry.

var geometry = new v3d.Geometry(); geometry.verticesNeedUpdate = true; geometry.elementsNeedUpdate = true; geometry.morphTargetsNeedUpdate = true; geometry.uvsNeedUpdate = true; geometry.normalsNeedUpdate = true; geometry.colorsNeedUpdate = true; geometry.tangentsNeedUpdate = true;

В версиях, предшествующих r66 для мешей требуется включенный флажок dynamic (для хранения внутренних типовых массивов):

//removed after r66 geometry.dynamic = true;

Примеры:

WebGL / geometry / dynamic

Материалы

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

Также параметры, связанные с GLstate, могут изменяться в любое время (depthTest, blending, polygonOffset и т.д.).

Плоское/гладкое затенение запекается в нормали. Необходимо сбросить буфер нормалей (см. выше).

Следующие свойства не могут быть легко изменены во время выполнения (после того, как материал будет отрисован хотя бы один раз):

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

material.needsUpdate = true

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

Для более плавного восприятия вы можете в некоторой степени эмулировать изменения этих характеристик, используя "фиктивные" значения, такие как освещение нулевой интенсивности, белые текстуры или туман нулевой плотности.

Вы можете свободно изменять материал, используемый для геометрических фрагментов, однако вы не можете изменить способ разделения объекта на фрагменты (в соответствии с материалами фейсов).

Если вам необходимо иметь различные конфигурации материалов во время работы:

Если количество материалов / фрагментов невелико, можно предварительно разделить объект (например, волосы / лицо / тело / верхняя одежда / брюки для человека, перед / бока / верх / стекло / шины / салон для автомобиля).

Если их количество велико (например, каждое лицо может быть потенциально разным), рассмотрите другое решение, например, использование атрибутов/текстур для управления различным внешним видом каждого лица.

Примеры:

WebGL / materials / cars
WebGL / webgl_postprocessing / dof

Текстуры

Текстуры изображений, canvas, видео и данных должны иметь следующий параметр, если они изменяются:

texture.needsUpdate = true;

Render targets обновляются автоматически.

Примеры:

WebGL / materials / video
WebGL / rtt

Камеры

Положение и цель камеры обновляются автоматически. Если вам необходимо изменить

то вам нужно будет заново вычислить матрицу проекции:

camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix();