Альфа-анимация в Aframe для модели объекта
У меня есть один 3d-объект с его файлом obj и mtl, который отображается с помощью Aframe. Я хочу применить анимацию, которая постепенно меняет значение альфа-канала для эффекта затухания.
Я прошел AFrame док. но не смог найти ничего связанного с альфа-анимацией 3D-объекта.
3 ответа
Встроенный material
компонент в основном работает с примитивами, поэтому material="opacity: 0.5"
и так же opacity="0.5"
не будет работать здесь. Вам нужно будет изменить материалы THREE.js, созданные вашей моделью, используя пользовательский компонент. Пример:
AFRAME.registerComponent('model-opacity', {
schema: {default: 1.0},
init: function () {
this.el.addEventListener('model-loaded', this.update.bind(this));
},
update: function () {
var mesh = this.el.getObject3D('mesh');
var data = this.data;
if (!mesh) { return; }
mesh.traverse(function (node) {
if (node.isMesh) {
node.material.opacity = data;
node.material.transparent = data < 1.0;
node.material.needsUpdate = true;
}
});
}
});
Затем вы можете использовать и анимировать компонент следующим образом:
<a-entity obj-model="obj: model.obj; mtl: model.mtl;" model-opacity="1">
<a-animation attribute="model-opacity"
dur="10000"
from="1"
to="0"
repeat="indefinite"></a-animation>
</a-entity>
Подробнее о том, как это работает, смотрите документацию по THREE.Material и написание компонента.
Для меня материал был полностью белым, поэтому мне пришлось изменить компонент Дона, чтобы поддержать число:
AFRAME.registerComponent("model-opacity", {
schema: {
opacity: { type: "number", default: 0.5 }
},
init: function() {
this.el.addEventListener("model-loaded", this.update.bind(this));
},
update: function() {
var mesh = this.el.getObject3D("mesh");
var data = this.data;
if (!mesh) {
return;
}
mesh.traverse(function(node) {
if (node.isMesh) {
console.log(node);
node.material.opacity = data.opacity;
node.material.transparent = data.opacity < 1.0;
node.material.needsUpdate = true;
}
});
}
});
Мне пришлось изменить приведенные выше примеры, так как у меня было несколько материалов, поэтому мне пришлось использовать forEach и настроить для каждого из них:
AFRAME.registerComponent("model-opacity", {
schema: {
opacity: { type: "number", default: 0.5 }
},
init: function() {
this.el.addEventListener("model-loaded", this.update.bind(this));
},
update: function() {
var mesh = this.el.getObject3D("mesh");
var data = this.data;
if (!mesh) {
return;
}
mesh.traverse(function(node) {
if (node.isMesh) {
console.log(node);
node.material.forEach( (mtl) =>{
mtl.opacity = data.opacity;
mtl.transparent = data.opacity < 1.0;
mtl.needsUpdate = true;
})
}
});
}
});