Aframe 中用于对象模型的 Alpha 动画

Alpha Animation in Aframe for a-object-model

我有一个 3d 对象及其在 Aframe 中显示的 obj 和 mtl 文件。我想在其上应用动画,逐渐改变其 Alpha 值以实现淡出效果。

我浏览了 AFrame 文档。但找不到任何与 3d 对象 alpha 动画相关的内容。

内置的 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 and writing a component 上的文档。

对我来说,material 是全白的,所以我不得不通过 Don 更改组件以支持数字:

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;
        })
      }
    });
  }
});