2016-12-16 161 views
2

我正在使用Three.js r83。THREE.js动态添加点到点几何不会渲染

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

这工作:

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); 

这不起作用:

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); 

正如你看到的,唯一的区别是,我加入顶点前加scene.add(pointCloud);

我错过了什么?

你可以找到一个fiddle由于@hectate

要明白我的意思,只是更换

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

通过

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

+0

你是什么three.js所的版本?检查文档[这里](https://github.com/mrdoob/three。js/wiki /更新)如何更新的东西... – Wilt

+1

请参阅http://stackoverflow.com/questions/36699389/verticesneedupdate-in-three-js/36699654#36699654和http://stackoverflow.com/questions/ 31399856 /绘图一个行与 - 三JS-动态/ 31411794#31411794。 – WestLangley

+0

@WestLangley我目前正在探索BufferGeometry,看起来像点的数量是固定的。 – Ant

回答

1

我不确定为什么THREE.Geometry对象在初始渲染后没有更新点数,但是我改用THREE.BufferGeometry代替它。

感谢@Hectate谁得到了工作捣鼓我和@WestLangley谁指示我的提示,here is the working fiddle

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)); 

然后你就可以创建你浊点,并将其添加到场景:

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

现在我想添加和渲染每10毫秒500新点。

var nbPoints = 500; 
var INTERVAL_DURATION = 10; 

所有我需要做的就是:

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); 

} 
1

这里是您的第一个提琴设置安装:https://jsfiddle.net/87wg5z27/236/

var scene, renderer, camera; 
var cube; 
var controls; 

init(); 
animate(); 

function init() 
{ 
    renderer = new THREE.WebGLRenderer({antialias:true}); 
    var width = window.innerWidth; 
    var height = window.innerHeight; 
    renderer.setSize (width, height); 
    document.body.appendChild (renderer.domElement); 

    scene = new THREE.Scene(); 

    camera = new THREE.PerspectiveCamera (45, width/height, 1, 10000); 
    camera.position.y = 160; 
    camera.position.z = 400; 
    camera.lookAt (new THREE.Vector3(0,0,0)); 

    controls = new THREE.OrbitControls (camera, renderer.domElement); 

    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); 

    window.addEventListener ('resize', onWindowResize, false); 
} 

function onWindowResize() 
{ 
    camera.aspect = window.innerWidth/window.innerHeight; 
    camera.updateProjectionMatrix(); 
    renderer.setSize (window.innerWidth, window.innerHeight); 
} 

function animate() 
{ 
    controls.update(); 
    requestAnimationFrame (animate); 
    renderer.render (scene, camera); 
} 

这里有一个与你的第二个:https://jsfiddle.net/87wg5z27/237/

var scene, renderer, camera; 
var cube; 
var controls; 

init(); 
animate(); 

function init() 
{ 
    renderer = new THREE.WebGLRenderer({antialias:true}); 
    var width = window.innerWidth; 
    var height = window.innerHeight; 
    renderer.setSize (width, height); 
    document.body.appendChild (renderer.domElement); 

    scene = new THREE.Scene(); 

    camera = new THREE.PerspectiveCamera (45, width/height, 1, 10000); 
    camera.position.y = 160; 
    camera.position.z = 400; 
    camera.lookAt (new THREE.Vector3(0,0,0)); 

    controls = new THREE.OrbitControls (camera, renderer.domElement); 

    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); 

    window.addEventListener ('resize', onWindowResize, false); 
} 

function onWindowResize() 
{ 
    camera.aspect = window.innerWidth/window.innerHeight; 
    camera.updateProjectionMatrix(); 
    renderer.setSize (window.innerWidth, window.innerHeight); 
} 

function animate() 
{ 
    controls.update(); 
    requestAnimationFrame (animate); 
    renderer.render (scene, camera); 
} 

在这两种情况下,点云显示了我完美的罚款(释放82)。也许还有其他的东西在你忽略渲染的地方?我注意到你的第一个例子没有显示你调用render()的哪一步。我希望这有帮助!

+1

嗨@Hectate,非常感谢你的小提琴,我应该创造一个 - 非常感谢你。我做了另一个提示案例我的问题 - 看到更新的问题。 https://jsfiddle.net/jjjaLv3e/2/ 我想在点云渲染完成后更新PointCloud。 – Ant