【问题标题】:Update normals of animated skinned mesh in three.js?在 three.js 中更新动画蒙皮网格的法线?
【发布时间】:2020-02-16 21:03:50
【问题描述】:

我有一个简单的动画模型,通过蒙皮动画,我给它一个 ShaderMaterial 来显示它的法线:

gl_FragColor = vec4(vNormal, 1.0);

https://codepen.io/marco_fugaro/pen/ZEEBjKz?editors=0010

问题是法线不会随着模型的蒙皮而更新,并且它们在对象的非动画位置始终保持不变(请参阅VertexNormalsHelper)。

如何更新法线,或者如何获得动画顶点的法线?

model.geometry.computeVertexNormals() 不起作用

【问题讨论】:

  • 使用ShaderMaterial 似乎不会显示正常情况。也许使用MeshNormalMaterial。否则,如果您想修改标准材质,您需要使用Material.onBeforeCompile,以便获得所有蒙皮和其他功能。有使用onBeforeCompilehere的例子
  • 我正在用法线做其他事情,所以我需要使用自定义着色器。你知道我应该在 onBeforeCompile 的着色器中注入什么吗?
  • 完成,谢谢!您的回答很有帮助!

标签: animation three.js shader normals


【解决方案1】:

我最终猴子修补了MeshNormalMaterial 顶点着色器,并删除了法线相对于相机的逻辑,这是最终代码:

import * as THREE from 'three'
import normalVert from 'three/src/renderers/shaders/ShaderLib/normal_vert.glsl'

// like MeshNormalMaterial, but the normals are relative to world not camera
const normalMaterialGlobalvert = normalVert.replace(
  '#include <defaultnormal_vertex>',
  THREE.ShaderChunk['defaultnormal_vertex'].replace(
    'transformedNormal = normalMatrix * transformedNormal;',
    // take into consideration only the model matrix
    'transformedNormal =  mat3(modelMatrix) * transformedNormal;'
  )
)

然后像这样使用它:

mesh.material = new THREE.ShaderMaterial({
  vertexShader: normalMaterialGlobalvert,
  fragmentShader: `
    varying vec3 vNormal;

    void main() {
      gl_FragColor = vec4(vNormal, 1.0);
    }
  `,
})

感谢gman 为我指明了正确的方向!

【讨论】:

    猜你喜欢
    • 2019-08-23
    • 2015-08-03
    • 2013-06-26
    • 2018-01-12
    • 2020-10-10
    • 2013-10-01
    • 2014-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多