更新THREE.Points几何的最佳方法

时间:2018-05-17 22:57:39

标签: three.js blender gltf

我有一个搅拌器型号,上面有一些形状键。我导出这个模型并在threejs中使用它。让我们说这是一个立方体。然后我创建Three.Points,在这个模型的顶点(即Cube)上绘制小球。

https://www.sixt.ie/php/reservation?tab_identifier=1526583730&uci=1385&rci=1385&uli=IE&rli=IE&layout=list&posl=IE&is_corpcust=&has_social_login=&pu_eq_ret=1&uda=25.05.2018&uti=10%3A00&geo_del_name=&geo_del_street=&geo_del_postcode=&geo_del_town=&geo_del_country=AT&del_note=&rda=26.05.2018&rti=09%3A30&geo_col_name=&geo_col_street=&geo_col_postcode=&geo_col_town=&geo_col_country=AT&col_note=

现在使用morphTargets,我为多维数据集设置动画。到目前为止一切都很好。

var cube = loadGLTFFromBlender(gltfFile); // This loads the model
var points = new THREE.Points(cube.geometry, pointMaterial); //got my points

但我期待这些点也会变形/动画,因为这些点使用的是相同的几何图形。但似乎没有开箱即用。

一些谷歌搜索建议变形发生在GPU级别,而对象中的几何数据并未真正修改。在其中一个StackOverflow问题(Three.js: Get updated vertices with morph targets)中,@ WestLangley建议在CPU上执行相同的几何更新,然后使用它。

我的问题:

  1. 在解决此问题时还有其他选择。
  2. CPU变形计算似乎更慢,我试图看看是否有任何其他方法可以让我的Three.Points与变形立方体保持同步?使用morphtargets动画的立方体,我期待Three.Points做同样的事情。
  3. 如果混合器中的形状关键动画更复杂,我猜#1不是真正的选择吗?

    理想情况下,以下内容会有所帮助:

    //Some code that uses the shapee keys 
    cube.morphTargetInfluences[0] = 0.2; // <-- I animate this value
    

1 个答案:

答案 0 :(得分:1)

回答我自己的问题,这将有助于其他人。

我能找到几个解决方案:

  1. 基于CPU(慢) - 使用函数将变形复制到位置

        function updatePointsGeometry(points,weight) {
            if (!points.geometry.attributes.morphTarget0) {
                return;
            }
            for (var i = 0; i < points.geometry.attributes.position.count; i++) {
                points.geometry.attributes.position.array[i+0] =  weight * points.geometry.attributes.morphTarget0.array[i+0];
                points.geometry.attributes.position.array[i+1] =  weight * points.geometry.attributes.morphTarget0.array[i+1];
                points.geometry.attributes.position.array[i+2] =  weight * points.geometry.attributes.morphTarget0.array[i+2];
            }
            points.geometry.attributes.position.needsUpdate = true;
        }
    
  2. 基于GPU(推荐) - 使用自定义着色器,使用morphtargets和morphinfluence来更改点

            var shaderPoint = THREE.ShaderLib.points;
            var uniforms = THREE.UniformsUtils.clone(shaderPoint.uniforms);
            uniforms.map.value = imageTexture;
            uniforms.size.value = 10;
            //Custom Shader
            customPointMaterial = new THREE.ShaderMaterial({
                uniforms: uniforms,
                morphTargets: true,
                defines: {
                    USE_MAP: ""
                },
                transparent: false,
                opacity: 1,
                alphaTest: 0.5,
                fog: false,
                vertexShader: document.getElementById( 'vertexShader' ).textContent,
                fragmentShader: shaderPoint.fragmentShader
            });
            //copy over the morph data from original geometry to the points
            myPoints = new THREE.Points(mesh.geometry, customPointMaterial);
            myPoints.morphTargetInfluences = mesh.morphTargetInfluences;
            myPoints.morphTargetDictionary = mesh.morphTargetDictionary;
    
  3. 这是顶点着色器

        uniform float size;
        uniform float scale;
        uniform float morphTargetInfluences[ 4 ];
    
        #include <common>
        #include <color_pars_vertex>
        #include <fog_pars_vertex>
        #include <shadowmap_pars_vertex>
        #include <logdepthbuf_pars_vertex>
        #include <clipping_planes_pars_vertex>
        void main() {
            #include <color_vertex>
            #include <begin_vertex>
            #include <project_vertex>
            #ifdef USE_SIZEATTENUATION
                gl_PointSize = size * ( scale / - mvPosition.z );
            #else
                gl_PointSize = size;
            #endif
            vec3 morphed = vec3( 0.0 , 0.0 , 0.0 );
            morphed += ( morphTarget0 - position ) * morphTargetInfluences[0];
            morphed += position;
            gl_Position = projectionMatrix * modelViewMatrix * vec4( morphed, 1.0 );
            #include <logdepthbuf_vertex>
            #include <clipping_planes_vertex>
            #include <worldpos_vertex>
            #include <shadowmap_vertex>
            #include <fog_vertex>
        }