【问题标题】:three.js: Get updated vertices with skeletal animations?three.js:使用骨骼动画获取更新的顶点?
【发布时间】:2019-12-11 10:16:18
【问题描述】:

与此堆栈溢出问题Three.js: Get updated vertices with morph targets 中的问题类似,我对如何使用骨骼动画获取网格顶点的“实际”位置感兴趣。

我尝试打印出位置值,但它们从未真正更新(据我了解,这是因为它们是在 GPU 上计算的,而不是在 CPU 上)。上述问题的答案提到在 CPU 上和在 GPU 上进行相同的计算以获得变形目标动画的最新顶点位置,但是有没有办法对骨骼动画执行相同的方法?如果是这样,怎么办??

另外,对于变形目标,有人指出此代码已经存在于 Mesh.raycast 函数中(https://github.com/mrdoob/three.js/blob/master/src/objects/Mesh.js#L115)。但是,我看不到光线投射如何与骨骼动画网格一起工作——它如何知道面部的更新位置?

谢谢!

【问题讨论】:

    标签: animation graphics three.js


    【解决方案1】:

    前段时间three.js forum 讨论过类似的话题。我在那里展示了一个小提琴,它计算每帧蒙皮网格的 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 函数中

    是的,您可以针对变形网格进行光线投射。尚不支持针对蒙皮网格的光线投射。 Mesh.raycast() 中的代码已经很复杂了。我认为在进一步增强之前,它需要进行一些认真的重构。同时,您可以使用提供的代码 sn-p 自行构建解决方案。顶点位移逻辑其实是最复杂的部分。

    现场演示:https://jsfiddle.net/fnjkeg9x/1/

    three.js R107

    【讨论】:

    猜你喜欢
    • 2014-10-16
    • 2014-09-23
    • 2021-08-03
    • 1970-01-01
    • 2014-12-15
    • 2013-12-24
    • 2013-11-03
    • 2016-09-13
    • 2013-09-22
    相关资源
    最近更新 更多