gltf 动画不使用平面着色器

Posted

技术标签:

【中文标题】gltf 动画不使用平面着色器【英文标题】:gltf animations are not playing with flat shader 【发布时间】:2022-01-16 20:33:01 【问题描述】:

我正在使用 A-Frame 1.2.0。我在场景中有一个 gltf 模型,我想为这个模型添加平面着色器。

 <a-scene vr-mode-ui="enabled: false;"gltf-model="dracoDecoderPath: js/draco/; "renderer="colorManagement: true; alpha: true;">
      <a-entity id="camera-rig">
                <a-camera id="camera" position="0 1.65 0" pivot="0 0 0" cursor="fuse:false;"></a-camera>
      </a-entity>
      <a-assets timeout="10000">
                <a-asset-item id="CesiumMan" src="assets/models/CesiumMan.gltf" response-type="arraybuffer"></a-asset-item>
      </a-assets>
      <a-gltf-model src="#CesiumMan" flat-shader="true" position='0 0 0' animation-mixer="clip:*"></a-gltf-model>
</a-scene>

我的平面着色器代码来自here

const FlatShader = 
    schema: default: true ,

  init() 
    this.el.addEventListener('object3dset', this.update.bind(this));
  ,//init

  update() 
    const mesh = this.el.getObject3D('mesh');
    const  data  = this;
    if (!mesh) 
      return;
    
    mesh.traverse(function(node) 
      if (node.isMesh && data) 
        const mat1 = new THREE.MeshBasicMaterial();
        node.material = mat1;
        node.material.needsUpdate = true;
      
    );

  ,//update

; // FlatShader

export default FlatShader

平面着色器工作,但添加平面着色器后,模型动画不工作。模型保持静态姿势。

任何想法可能导致问题?我可能遗漏了一些东西,但我不知道如何解决这个问题。

【问题讨论】:

【参考方案1】:

a-frames 版本的threejs(修改为125)中,您需要“告诉”材质,您的模型使用“蒙皮”来制作动画:

 material.skinning = true;

自从三个r.129this is no longer necessary


因此,您只需将 Materials skinning 属性更改为 true

<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/donmccurdy/aframe-extras@v6.1.1/dist/aframe-extras.min.js"></script>
<script>
  AFRAME.registerComponent("foo", 
    init: function() 
      // wait for the model to load
      this.el.addEventListener("model-loaded", evt => 
        // create new material - with it skinning flag raised
        const new_material = new THREE.MeshNormalMaterial(skinning: true);
        const mesh = this.el.getObject3D('mesh');

        // traverse the mesh and apply the material
        mesh.traverse(node => 
          if (!node.isMesh) return;
          node.material = new_material;
          node.material.needsUpdate = true;
        )
      )
    
  )

</script>
<a-scene>
  <a-assets>
    <a-asset-item id="model" src="https://rawcdn.githack.com/KhronosGroup/glTF-Sample-Models/20656ea38ce797a8dff0d2915b656aff75d32a71/2.0/CesiumMan/glTF-Binary/CesiumMan.glb"></a-asset-item>
  </a-assets>
    <a-entity position="1 0 -3" gltf-model="#model" animation-mixer="clip: *" foo></a-entity>
  <a-entity position="-1 0 -3" gltf-model="#model" animation-mixer="clip: *"></a-entity>
</a-scene>

铯人模型来自Kronos Group glTF sample models repo

【讨论】:

以上是关于gltf 动画不使用平面着色器的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL - 动画是由着色器完成的吗?

自定义着色器不接收光线

如何使用在质心处计算的光来实现平面着色?

使用顶点着色器动画四边形

如何使用OpenGL着色器在平面上绘制没有透视的纹理?

GLSL着色器,来玩