THREE.js动态添加点到点几何不显示 [英] THREE.js dynamically add points to a Points geometry does not render

查看:455
本文介绍了THREE.js动态添加点到点几何不显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Three.js r83。

我试图动态地将点添加到几何图形,但场景永远不会更新。



这样做:

  var tmaterial = new THREE.PointsMaterial({
color :0xff0000,
size:5,
opacity:1
});

var tgeometry = new THREE.Geometry();
var pointCloud = new THREE.Points(tgeometry,tmaterial); (var i = 0; i <1000; i ++){
x =(Math.random()* 200) - 100;


y =(Math.random()* 200) - 100;
z =(Math.random()* 200) - 100;
tgeometry.vertices.push(new THREE.Vector3(x,y,z));
}
tgeometry.verticesNeedUpdate = true;
tgeometry.computeVertexNormals();

scene.add(pointCloud);

这不起作用:

 var tmaterial = new THREE.PointsMaterial({
color:0xff0000,
size:5,
opacity:1
});

var tgeometry = new THREE.Geometry();
var pointCloud = new THREE.Points(tgeometry,tmaterial);
scene.add(pointCloud); (var i = 0; i <1000; i ++){
x =(Math.random()* 200) - 100;


y =(Math.random()* 200) - 100;
z =(Math.random()* 200) - 100;
tgeometry.vertices.push(new THREE.Vector3(x,y,z));
}
tgeometry.verticesNeedUpdate = true;
tgeometry.elementsNeedUpdate = true;
tgeometry.computeVertexNormals();
renderer.render(scene,camera);

正如您所看到的,唯一的区别是我添加了场景.add(pointCloud); 在添加顶点之前。



我错过了什么?

您可以找到小提琴感谢@hectate



看看我的意思,只需要替换

init();
setPoints();
animate();



by

init );
animate();
setPoints();

解决方案

我不知道为什么 THREE。几何对象在初始渲染后不会更新点,但是我使用 THREE.BufferGeometry 来代替。



感谢 @Hectate 对我有帮助, @WestLangley 我的提示,这里是工作小提琴



BufferGeometry具有固定数量的顶点,但您可以决定要渲染的数量。诀窍是利用 geometry.attributes.position.needsUpdate = true; geometry.setDrawRange(0,nbPointsYouWantToDisplay);

  var MAX_POINTS = 1000000; 
var geometry = new THREE.BufferGeometry();
var positions = new Float32Array(MAX_POINTS * 3);
geometry.addAttribute('position',new THREE.BufferAttribute(positions,3));

然后您可以创建您的云点并将其添加到场景中:

  //定义的材质和场景
pointCloud = new THREE.Points(geometry,material);
scene.add(pointCloud);

现在我想添加并渲染 500 每个 10 毫秒的新点数。

  var nbPoints = 500; 
var INTERVAL_DURATION = 10;

所有我需要做的是:

<$ ()函数setPoints(){$ b($)函数setPoints();
},INTERVAL_DURATION)

var set = setInterval
$ b var positions = pointCloud.geometry.attributes.position.array;

var x,y,z,index;

var l = currentPoints + nbPoints;
if(l> = MAX_POINTS){
clearInterval(interval); (数学。随机() - 0.5)* 300;(b)b $ b b

为(var i = currentPoints; i <1; i ++){
x =
y =(Math.random() - 0.5)* 300;
z =(Math.random() - 0.5)* 300;
职位[currentPointsIndex ++] = x;
职位[currentPointsIndex ++] = y;
职位[currentPointsIndex ++] = z;
}
currentPoints = 1;
pointCloud.geometry.attributes.position.needsUpdate = true;
pointCloud.geometry.setDrawRange(0,currentPoints);
controls.update();
renderer.render(scene,camera);

}


I am using Three.js r83.

I am trying to dynamically add points to a geometry, but the scene never gets updated.

This works :

var tmaterial = new THREE.PointsMaterial({
    color: 0xff0000,
    size: 5,
    opacity: 1
});

var tgeometry = new THREE.Geometry();
var pointCloud = new THREE.Points(tgeometry, tmaterial);

for(var i = 0; i< 1000; i++) {
    x = (Math.random() * 200) - 100;
    y = (Math.random() * 200) - 100;
    z = (Math.random() * 200) - 100;
    tgeometry.vertices.push(new THREE.Vector3(x, y, z));
}
tgeometry.verticesNeedUpdate = true;
tgeometry.computeVertexNormals();

scene.add(pointCloud);

This doesn't work:

var tmaterial = new THREE.PointsMaterial({
    color: 0xff0000,
    size: 5,
    opacity: 1
});

var tgeometry = new THREE.Geometry();
var pointCloud = new THREE.Points(tgeometry, tmaterial);
scene.add(pointCloud);

for(var i = 0; i< 1000; i++) {
    x = (Math.random() * 200) - 100;
    y = (Math.random() * 200) - 100;
    z = (Math.random() * 200) - 100;
    tgeometry.vertices.push(new THREE.Vector3(x, y, z));
}
tgeometry.verticesNeedUpdate = true;
tgeometry.elementsNeedUpdate = true;
tgeometry.computeVertexNormals();
renderer.render(scene, camera);

As you can see, the only difference is the fact that I add scene.add(pointCloud); before adding vertexes.

What do I miss?

You can find a fiddle Thanks to @hectate

To see what I means, just replace

init(); setPoints(); animate();

by

init(); animate(); setPoints();

解决方案

I am not sure why the THREE.Geometry object doesn't update Points after initial rendering, but I got it working with a THREE.BufferGeometry instead.

Thanks to @Hectate who got a working fiddle for me and @WestLangley who directed me to the hints, here is the working fiddle

BufferGeometry has a fixed number of Vertices, but you can decide how many of them you want to render. The trick is to make use of geometry.attributes.position.needsUpdate = true; and geometry.setDrawRange( 0, nbPointsYouWantToDisplay );

var MAX_POINTS = 1000000;
var geometry = new THREE.BufferGeometry();
var positions = new Float32Array( MAX_POINTS * 3 ); 
geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );

Then you can create your cloudpoints and add it to the scene:

//material and scene defined in question
pointCloud = new THREE.Points(geometry, material);
scene.add(pointCloud);

Now I want to add and render 500 new points every 10 milliseconds.

var nbPoints = 500;
var INTERVAL_DURATION = 10;

All I have to do is :

var interval = setInterval(function() {
  setPoints();
}, INTERVAL_DURATION)

function setPoints() {

  var positions = pointCloud.geometry.attributes.position.array;

  var x, y, z, index;

  var l  = currentPoints + nbPoints;
  if(l >= MAX_POINTS) {
    clearInterval(interval);
  }

  for ( var i = currentPoints; i < l; i ++ ) {
    x = ( Math.random() - 0.5 ) * 300;
    y = ( Math.random() - 0.5 ) * 300;
    z = ( Math.random() - 0.5 ) * 300;
    positions[ currentPointsIndex ++ ] = x;
    positions[ currentPointsIndex ++ ] = y;
    positions[ currentPointsIndex ++ ] = z;
  }
  currentPoints = l;
  pointCloud.geometry.attributes.position.needsUpdate = true;   
  pointCloud.geometry.setDrawRange( 0, currentPoints );  
  controls.update();
  renderer.render(scene, camera);

}

这篇关于THREE.js动态添加点到点几何不显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆