WebGL Изменить анимацию формы
Я создаю трехмерный глобус с картой, которая должна распутаться и заполнить экран через несколько секунд.
Мне удалось создать глобус с помощью three.js и webGL, но у меня возникли проблемы с поиском какой-либо информации о возможности анимировать изменение формы. Может ли кто-нибудь помочь? Это вообще возможно?
3 ответа
В 3D все возможно.;)
У вашей геометрии сферы есть свои вершины, и в основном вам просто нужно анимировать их положение, поэтому после анимации они все сидят на одной плоской поверхности.
Попробуйте создать геометрию сферы и плоскости с одинаковым количеством вершин и анимировать вершины сферы с интерполированными значениями исходных значений сферы и плоскости. Таким образом, в начале вы получите форму сферы, а в конце плоскую форму.
Надеюсь, это поможет, скажите мне, если вам нужно больше директив, как это сделать.
myGlobe.geometry.vertices[index].position = something_calculated;
// myGlobe is instance of THREE.Mesh and something_calculated would be THREE.Vector3 instance that you can calculate in some manner (sphere-plane interpolation over time)
(Ответы абстрактного алгоритма и Кевина Рейда хороши, и не хватает только одного: некоторого реального кода Three.js.)
По сути, вам нужно вычислить, где будет отображаться каждая точка исходной сферы после того, как она выровняется в плоскость. Эти данные являются атрибутом шейдера: фрагмент данных, прикрепленный к каждой вершине, который отличается от вершины к вершине геометрии. Затем, чтобы анимировать переход от исходной позиции к конечной позиции, в цикле анимации вам нужно будет обновить количество прошедшего времени. Эти данные являются униформой шейдера: фрагмент данных, который остается постоянным для всех вершин в течение каждого кадра анимации, но может меняться от одного кадра к следующему. Наконец, существует удобная функция, называемая "смесь", которая будет линейно интерполировать между исходной позицией и конечной / целевой позицией каждой вершины.
Я написал для вас два примера: первый просто "выравнивает" сферу, отправляя точку (x,y,z) в точку (x, 0, z).
http://stemkoski.github.io/Three.js/Shader-Attributes.html
Второй пример следует предложению абстрактного алгоритма в комментариях: "развернуть вершины сферы обратно на плоскую поверхность, как УФ-отображение в обратной сфере". В этом примере мы можем легко вычислить конечную позицию по UV-координатам, поэтому в этом случае нам фактически не нужны атрибуты.
http://stemkoski.github.io/Three.js/Sphere-Unwrapping.html
Надеюсь это поможет!
(Ответ абстрактного алгоритма хорош, но я думаю, что одна вещь нуждается в улучшении: использование вершинных шейдеров.)
Вы делаете набор вершин текстурированных с изображением карты. Затем разработайте расчет для интерполяции между формой сферы и плоской формой. Это не обязательно должна быть линейная интерполяция - например, один из подходящих способов - поместить карту на небольшую часть сферы с увеличивающимся радиусом, пока она не будет выглядеть плоской (получить всю дорогу будет сложно).
Затем запишите это вычисление в свой вершинный шейдер. Положение каждой вершины может быть полностью вычислено из координат текстуры (так как это определяет, на каком месте карты вершина идет и подразумевает ее положение) и однородной переменной, содержащей значение времени.
Использование вершинного шейдера будет гораздо более эффективным, чем повторный расчет и повторная загрузка координат с использованием JavaScript, что позволит идеально плавно выполнять анимацию с большим количеством запасных ресурсов для выполнения других задач.
К сожалению, я недостаточно знаком с Three.js, чтобы подробно описать, как это сделать, но все вышеперечисленное является простым в базовом WebGL и должно быть возможно в любой достойной среде.