three.js:获得带有骨骼动画的更新顶点



与此堆栈溢出问题中的问题类似。骨骼动画。

我尝试打印出位置值,但是从未实际更新它们(正如我要理解的那样,这是因为它们是在GPU上计算的,而不是CPU(。上面提到的问题的答案是在CPU上与GPU上相同的计算以获取变形目标动画的最新顶点位置,但是是否有一种方法可以为骨骼动画做相同的方法?如果是这样,怎么样??

对于变形目标,有人指出,该代码已经存在于mesh.raycast函数中(https://github.com/mrdoob/three.js/blob/blob/master/master/src/objects/mesh。JS#L115(。但是,我看不出射线广播如何与骨骼动画网格一起使用 - 它如何知道面部的更新位置?

谢谢!

一段时间前,在三分之二的论坛中讨论了类似的主题。我在那里介绍了一个小提琴,该小提琴计算AABB的每个框架的皮肤网格。该代码实际上通过JavaScript执行相同的顶点位移,就像顶点着色器中一样。例程看起来像:

function updateAABB( skinnedMesh, aabb ) {
    var skeleton = skinnedMesh.skeleton;
    var boneMatrices = skeleton.boneMatrices;
    var geometry = skinnedMesh.geometry;
    var index = geometry.index;
    var position = geometry.attributes.position;
    var skinIndex = geometry.attributes.skinIndex;
    var skinWeigth = geometry.attributes.skinWeight;
    var bindMatrix = skinnedMesh.bindMatrix;
    var bindMatrixInverse = skinnedMesh.bindMatrixInverse;
    var i, j, si, sw;
    aabb.makeEmpty();
    // 
    if ( index !== null ) {
        // indexed geometry
        for ( i = 0; i < index.count; i ++ ) {
            vertex.fromBufferAttribute( position, index[ i ] );
            skinIndices.fromBufferAttribute( skinIndex, index[ i ] );
            skinWeights.fromBufferAttribute( skinWeigth, index[ i ] );
            // the following code section is normally implemented in the vertex shader
            vertex.applyMatrix4( bindMatrix ); // transform to bind space
            skinned.set( 0, 0, 0 );
            for ( j = 0; j < 4; j ++ ) {
                si = skinIndices.getComponent( j );
                sw = skinWeights.getComponent( j );
                boneMatrix.fromArray( boneMatrices, si * 16 );
                // weighted vertex transformation
                temp.copy( vertex ).applyMatrix4( boneMatrix ).multiplyScalar( sw );
                skinned.add( temp );
            }
            skinned.applyMatrix4( bindMatrixInverse ); // back to local space
            // expand aabb
            aabb.expandByPoint( skinned );
        }
    } else {
        // non-indexed geometry
        for ( i = 0; i < position.count; i ++ ) {
            vertex.fromBufferAttribute( position, i );
            skinIndices.fromBufferAttribute( skinIndex, i );
            skinWeights.fromBufferAttribute( skinWeigth, i );
            // the following code section is normally implemented in the vertex shader
            vertex.applyMatrix4( bindMatrix ); // transform to bind space
            skinned.set( 0, 0, 0 );
            for ( j = 0; j < 4; j ++ ) {
                si = skinIndices.getComponent( j );
                sw = skinWeights.getComponent( j );
                boneMatrix.fromArray( boneMatrices, si * 16 );
                // weighted vertex transformation
                temp.copy( vertex ).applyMatrix4( boneMatrix ).multiplyScalar( sw );
                skinned.add( temp );
            }
            skinned.applyMatrix4( bindMatrixInverse ); // back to local space
            // expand aabb
            aabb.expandByPoint( skinned );
        }
    }
    aabb.applyMatrix4( skinnedMesh.matrixWorld );
}

此外,对于"变形"目标,有人指出此代码已经存在于网格播放函数

是的,您可以针对变形的网格进行播放。尚未支持针对皮肤网眼的射线播放。Mesh.raycast()中的代码已经非常复杂。我认为它需要进行一些认真的重构,然后才能进一步增强。同时,您可以使用呈现的代码片段自己构建解决方案。顶点位移逻辑实际上是最复杂的部分。

实时演示:https://jsfiddle.net/fnjkeg9x/1/

three.js R107

最新更新