Обновить нормали анимированной сетки со скинами в three.js?

У меня есть простая анимированная модель, анимированная с помощью скининга, и я даю ей ShaderMaterial, которая отображает ее нормали:

gl_FragColor = vec4(vNormal, 1.0);

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

Проблема в том, что нормали не обновляются при скиннинге модели, и они всегда остаются неизменными из неанимированного положения объекта (см. VertexNormalsHelper).

Как мне обновить нормали или как получить нормали анимированных вершин?

model.geometry.computeVertexNormals() не работает

модель


person Pontiacks    schedule 20.10.2019    source источник
comment
Использование ShaderMaterial не похоже на то, что оно покажет вам нормали. Возможно, используйте MeshNormalMaterial. В противном случае, если вы хотите изменить стандартные материалы, вам нужно использовать Material.onBeforeCompile, чтобы получить все скины и другие функции. Пример использования onBeforeCompile здесь   -  person gman    schedule 20.10.2019
comment
Я делаю другие вещи с нормалями, поэтому мне нужно использовать собственный шейдер. Вы знаете, что я должен ввести в шейдер в onBeforeCompile?   -  person Pontiacks    schedule 20.10.2019
comment
Готово, спасибо! Ваш ответ был полезен!   -  person Pontiacks    schedule 22.10.2019


Ответы (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 за то, что указали мне правильное направление!

person Pontiacks    schedule 22.10.2019