2016-12-16 75 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