2014-07-24 34 views
1

我正在使用Three.js JavaScript库。为了测试它,我从here下载了一个例子。与three.js显示几次相同的3D对象

我试图显示几次相同的元素使用循环。有两个相关的问题(1,2),但它不完全是我想要的。我的问题是,如果我在循环内创建元素,它将只显示迭代的最后一个元素。在这种特殊情况下,元素位于(12,12)。

但是,如果我执行类似的警报,它将显示所有元素。此外,如果我有任何其他功能,延迟执行。

我看到一些示例运行,因为mrdoob的例子,但我想运行这段代码,因为我需要加载几个网格,而不是生成原始数字。

// Set up the scene, camera, and renderer as global variables. 
var scene, camera, renderer; 
var group; 

// Call functions 
init(); 
animate(); 

// Sets up the scene. 
function init() { 

    // Iterator 
    var i, j; 

    // Create the scene and set the scene size. 
    scene = new THREE.Scene(); 
    var WIDTH = window.innerWidth, 
     HEIGHT = window.innerHeight; 

    // Create a renderer and add it to the DOM. 
    renderer = new THREE.WebGLRenderer({antialias:true}); 
    renderer.setSize(WIDTH, HEIGHT); 
    document.body.appendChild(renderer.domElement); 

    // Create a camera, zoom it out from the model a bit, and add it to the scene. 
    camera = new THREE.PerspectiveCamera(45, WIDTH/HEIGHT, 0.1, 20000); 
    camera.position.set(0,20,20); 
    scene.add(camera); 

    // Create an event listener that resizes the renderer with the browser window. 
    window.addEventListener('resize', function() { 
    var WIDTH = window.innerWidth, 
     HEIGHT = window.innerHeight; 
    renderer.setSize(WIDTH, HEIGHT); 
    camera.aspect = WIDTH/HEIGHT; 
    camera.updateProjectionMatrix(); 
    }); 

    // Set the background color of the scene. 
    renderer.setClearColor(0x333F47, 1); 

    // Create a light, set its position, and add it to the scene. 
    var light = new THREE.PointLight(0xffffff); 
    light.position.set(-100,200,100); 
    scene.add(light); 


    group = new THREE.Object3D(); 

    for(i=0; i < 15; i+=3) { 
    for(j=0; j < 15; j+=3) { 

     var loader = new THREE.JSONLoader(); 
     loader.load("models/treehouse_logo.js", function(geometry){ 
     var material = new THREE.MeshLambertMaterial({color: 0x55B663}); 
     var mesh = new THREE.Mesh(geometry, material); 
     mesh.position.set(i,0,j); 
     group.add(mesh); 
     }); 
    //alert("iteration"+i+" "+j); 
    } 
    } 

    scene.add(group); 

    // Add OrbitControls so that we can pan around with the mouse. 
    controls = new THREE.OrbitControls(camera, renderer.domElement); 
} 

// Renders the scene and updates the render as needed. 
function animate() { 

    // Read more about requestAnimationFrame at http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/ 
    requestAnimationFrame(animate); 

    // Render the scene. 
    renderer.render(scene, camera); 
    controls.update(); 

} 

回答

6

你在做什么在这里是非常低效的:

for(i=0; i < 15; i+=3) { 
    for(j=0; j < 15; j+=3) { 

     var loader = new THREE.JSONLoader(); 
     loader.load("models/treehouse_logo.js", function(geometry){ 
     var material = new THREE.MeshLambertMaterial({color: 0x55B663}); 
     var mesh = new THREE.Mesh(geometry, material); 
     mesh.position.set(i,0,j); 
     group.add(mesh); 
     }); 
    //alert("iteration"+i+" "+j); 
    } 
    } 

这将这样来更好的完成(未经测试):

var loader = new THREE.JSONLoader(); 
    loader.load("models/treehouse_logo.js", function(geometry){ 
    var material, mesh, i, j, instance; 
    material = new THREE.MeshLambertMaterial({ color: 0x55B663 }); 
    mesh = new THREE.Mesh(geometry, material); 
    for (i = 0; i < 15; i += 3) { 
     for (j = 0; j < 15; j += 3) { 
     instance = mesh.clone(); 
     instance.position.set(i, 0, j); 
     group.add(instance); 
     } 
    } 
    }); 

你需要做重复此每个独特网格的图案。

你目前的做法有问题是:由GPU为每个相同的网格需要

  • 更多的内存
  • 通过浏览器记住每个相同的网格需要更多的内存
  • 要求
  • 更强的处理能力GPU需要处理更多内存
  • 每次调用加载程序时,都会指示浏览器执行请求。你的情况大概有25个相同的请求。它们应该来自缓存,但它仍然会很慢。
  • 您可能也有变量范围问题,这会给加载程序回调带来问题,但我并不完全确定。

alert()通过改变浏览器的反应方式,使其成为一个非常糟糕的调试工具:它在警报打开时会停止执行JavaScript,并且会影响加载程序和类似的事情。使用Console日志记录方法更好。

0

我会说这是因为你在循环的每次迭代中设置加载器变量,它将覆盖上次迭代的加载器。

为什么实际加载是在循环中完成的?为什么不加载一次并克隆它?
例如。

group = new THREE.Object3D(); 
     var loader = new THREE.JSONLoader(); 
     loader.load("models/treehouse_logo.js", function(geometry){ 
     var material = new THREE.MeshLambertMaterial({color: 0x55B663}); 
     for(i=0; i < 15; i+=3) { 
      for(j=0; j < 15; j+=3) { 
      var mesh = new THREE.Mesh(geometry.clone(), material); 
      mesh.position.set(i,0,j); 
      group.add(mesh); 
      } 
     } 
     }); 
    scene.add(group); 

上面的代码是未经测试

+0

似乎当我在写我的Leeft已经回答了:) – 2pha