我有一个搅拌器型号,上面有一些形状键。我导出这个模型并在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不是真正的选择吗?
理想情况下,以下内容会有所帮助:
//Some code that uses the shapee keys
cube.morphTargetInfluences[0] = 0.2; // <-- I animate this value
答案 0 :(得分: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;
}
基于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;
这是顶点着色器
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>
}