我是three.js的新手,只是尝试了一些想法。现在问题是我在场景中创建了一条线并将其用作克隆和转换的基础。这样克隆的那些将在场景中显示为一系列变换。
简化代码如下:
var line, scene, camera, light, renderer;
var frame = 0;
var random_degree = Math.round(Math.random() * 360);
var container = document.getElementById( 'container' );
init();
animate();
function init() {
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
scene.add( camera );
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 200;
var material = new THREE.LineBasicMaterial({
transparent: true,
color: 0x0000ff
});
var geometry = new THREE.Geometry();
geometry.vertices.push(
new THREE.Vector3( -100, 0, 0 ),
new THREE.Vector3( 0, 100, 0 ),
new THREE.Vector3( 100, 0, 0 )
);
line = new THREE.Line( geometry, material );
//borrowed the code from http://threejs.org/docs/#Reference/Objects/Line
//just wanted to make it simple
}
function animate() {
requestAnimationFrame( animate );
frame ++;
if( frame < 1500){
var newCurve = line.clone();
newCurve.rotation.x = ((random_degree + frame * 0.25) % 360) * Math.PI / 180;
newCurve.rotation.y = ((random_degree + frame * 0.25) % 360) * Math.PI / 180;
newCurve.rotation.z = ((random_degree + frame * 0.25) % 360) * Math.PI / 180;
newCurve.material.opacity = 0.2;
scene.add(newCurve);
}
renderer.render( scene, camera );
}
和html部分只是<div id='container'></div>
这一切都运行良好,但是你可以看到我只能将新的行号限制为1500,当行号超过2000时,我开始出现渲染问题,fps在此之后迅速下降线数增加。
我尝试合并:
var totalGeometry = new THREE.Geometry();
....
function init(){
....
for(var i=0; i< 1500; i++){
var newCurve = line.clone();
newCurve.rotation.x = ((random_degree + frame * 0.25) % 360) * Math.PI / 180;
newCurve.rotation.y = ((random_degree + frame * 0.25) % 360) * Math.PI / 180;
newCurve.rotation.z = ((random_degree + frame * 0.25) % 360) * Math.PI / 180;
newCurve.updateMatrix();
totalGeometry.merge(newCurve.geometry, newCurve.matrix);
}
var totalLine = new THREE.Line(totalGeometry, material);
....
}
但我只能在init进程中合并而不是在渲染过程中。如果我在function animate()
中使用上面的代码,它只渲染一行而不是整行行:
function animate(){
.....
if( frame < 1500){
var newCurve = curve1.clone();
newCurve.rotation.x = ((random_degree + frame * 0.25) % 360) * Math.PI / 180;
newCurve.rotation.y = ((random_degree + frame * 0.25) % 360) * Math.PI / 180;
newCurve.rotation.z = ((random_degree + frame * 0.25) % 360) * Math.PI / 180;
newCurve.material.opacity = 0.2;
newCurve.updateMatrix();
totalGeo.merge(newCurve.geometry, newCurve.matrix);
totalMesh = new THREE.Line(totalGeo, newCurve.material);
scene.add(totalMesh);
}
}
有人有建议吗?感谢。
答案 0 :(得分:1)
您可以使用THREE.BufferGeometry
更新线几何图形,而无需合并几何图形或向场景添加新的线条对象。像这样你将节省大量的内存,它将使你获得相同的效果。
我更新了 your fiddle here 来演示。
首先,您需要创建一个缓冲区几何体(在getBufferGeometry
函数中完成):
/**
* Create a buffer geometry
* Positions attribute with 3 vertices per point
*/
function getBufferGeometry() {
var geometry = new THREE.BufferGeometry();
positions = new Float32Array(total * 3);
geometry.addAttribute(
'position', new THREE.BufferAttribute(positions, 3)
);
return geometry;
}
然后魔术发生在addLine
函数:
/**
* Add a new line to the geometry on each call
*/
function addLine() {
if (count < total) {
vertices = getVertices();
var index = count * 9;
positions[index] = vertices[0].x;
positions[index++] = vertices[0].y;
positions[index++] = vertices[0].z;
positions[index++] = vertices[1].x;
positions[index++] = vertices[1].y;
positions[index++] = vertices[1].z;
positions[index++] = vertices[2].x;
positions[index++] = vertices[2].y;
positions[index++] = vertices[2].z;
var start = count * 3;
var end = start + 3;
bufferGeometry.addGroup(start, end);
line.geometry.attributes.position.needsUpdate = true
count++;
}
}
此解决方案基于 @WestLangley 他的回答on another related question here。
您仍需要在示例中设置最大点数,此值在代码顶部设置为total
。