我想在ThreeJS中为bezier曲线制作动画。开始,结束和控制点将更新。最终我需要一次制作许多曲线动画。最有效的方法是什么?
如果您运行下面的代码段,您会看到我每次渲染帧时都会创建Bezier对象,几何和直线。我从场景中删除了上一行,然后添加了新的更新行。有没有更好的办法?也许只更新几何体而不再添加线?
var camera, scene, renderer, geometry, material, mesh;
init();
animate();
/**
Create the scene, camera, renderer
*/
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 500;
scene.add(camera);
addCurve();
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
/**
Add the initial bezier curve to the scene
*/
function addCurve() {
testPoint = 0;
curve = new THREE.CubicBezierCurve3(
new THREE.Vector3( testPoint, 0, 0 ),
new THREE.Vector3( -5, 150, 0 ),
new THREE.Vector3( 20, 150, 0 ),
new THREE.Vector3( 10, 0, 0 )
);
curveGeometry = new THREE.Geometry();
curveGeometry.vertices = curve.getPoints( 50 );
curveMaterial = new THREE.LineBasicMaterial( { color : 0xff0000 } );
curveLine = new THREE.Line( curveGeometry, curveMaterial );
scene.add(curveLine);
}
/**
On each frame render, remove the old line, create new curve, geometry and add the new line
*/
function updateCurve() {
testPoint ++;
scene.remove(curveLine);
curve = new THREE.CubicBezierCurve3(
new THREE.Vector3( testPoint, 0, 0 ),
new THREE.Vector3( -5, 150, 0 ),
new THREE.Vector3( 20, 150, 0 ),
new THREE.Vector3( 10, 0, 0 )
);
curveGeometry = new THREE.Geometry();
curveGeometry.vertices = curve.getPoints( 50 );
curveLine = new THREE.Line( curveGeometry, curveMaterial );
scene.add(curveLine);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
updateCurve();
renderer.render(scene, camera);
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.min.js"></script>
&#13;
答案 0 :(得分:3)
每帧创建新行是非常广泛的操作。
创建动画曲线的最佳方法是什么?
可能使用shaders。但是实施起来需要花费更多的时间,所以如果我的下一个建议对你来说足够了,那就是他们。
改善代码中的曲线更新
我尽量不改变你的很多代码。使用“// EDITED
”注释标记已修改的地点。我添加了一个数组,因为你说会有很多曲线。
<强>解释强>
new
关键字。CubicBezierCurve3
具有v0
,v1
,v2
和v3
属性。那些是你从一开始就提供的THREE.Vector3
。 .getPoints()
使用它们返回顶点数组。因此,您只需更改它们即可,无需new
个关键字。 See this line for more details. geometry.verticesNeedUpdate = true
或Three.js将忽略您的更改。
var camera, scene, renderer, geometry, material, mesh, curves = [];
init();
animate();
/**
Create the scene, camera, renderer
*/
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 500;
scene.add(camera);
addCurve();
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
/**
Add the initial bezier curve to the scene
*/
function addCurve() {
testPoint = 0;
curve = new THREE.CubicBezierCurve3(
new THREE.Vector3( testPoint, 0, 0 ),
new THREE.Vector3( -5, 150, 0 ),
new THREE.Vector3( 20, 150, 0 ),
new THREE.Vector3( 10, 0, 0 )
);
curveGeometry = new THREE.Geometry();
curveGeometry.vertices = curve.getPoints( 50 );
curveMaterial = new THREE.LineBasicMaterial( { color : 0xff0000 } );
curveLine = new THREE.Line( curveGeometry, curveMaterial );
scene.add(curveLine);
// EDITED
curves.push(curveLine); // Add curve to curves array
curveLine.curve = curve; // Link curve object to this curveLine
}
/**
On each frame render, remove the old line, create new curve, geometry and add the new line
*/
function updateCurve() {
testPoint ++;
// EDITED
for (var i = 0, l = curves.length; i < l; i++) {
var curveLine = curves[i];
// Update x value of v0 vector
curveLine.curve.v0.x = testPoint;
// Update vertices
curveLine.geometry.vertices = curveLine.curve.getPoints( 50 );
// Let's three.js know that vertices are changed
curveLine.geometry.verticesNeedUpdate = true;
}
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
updateCurve();
renderer.render(scene, camera);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.min.js"></script>