首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Three.js高效地绘制大量对象

如何使用Three.js高效地绘制大量对象
EN

Stack Overflow用户
提问于 2014-04-05 17:44:12
回答 3查看 1.4K关注 0票数 0

我是WebGL和Three.js的新手。我正在尝试可视化一个大的圆圈网格,一次改变颜色。

随着我增加实例的数量,它会明显变慢,需要几秒钟才能更新。有什么建议可以改进我的代码?我可以一次更新4000个圆圈吗?

下面是我现有的实现:

代码语言:javascript
复制
<html>
    <head>
        <title>My first Three.js app</title>
        <style></style>
    </head>
    <body>
        <script src="./three.js"></script>
        <script>
        var ROWS = 40
        var COLS = 100
        var SEGMENTS = 10;

        var windowWidth = window.innerWidth, windowHeight = window.innerHeight;

        var camera, scene, renderer;
        var group, text, plane;

        function init() {
            // create and append container/canvas
            container = document.createElement( 'div' );
            document.body.appendChild( container );

            // create camera    
            camera = new THREE.PerspectiveCamera(100, windowWidth / windowHeight, 0.1, 1000 );
            // set position of camera
            camera.position.z = 500;
            camera.position.x = windowWidth/2
            camera.position.y = windowHeight/2

            // Create a scene
            scene = new THREE.Scene();


            renderer = new THREE.CanvasRenderer();
            renderer.setClearColor( 0xf0f0f0 );
            renderer.setSize( windowWidth, windowHeight );
            renderer.sortElements = false;
            container.appendChild( renderer.domElement );

            document.addEventListener( 'mousedown', onDocumentMouseDown, false );
        }

        function addCircle(color, x, y, z, s , radius) {    
            var geometry = new THREE.CircleGeometry(radius, SEGMENTS, SEGMENTS)
            var material = new THREE.MeshBasicMaterial( { color: color, overdraw: true } );

            var mesh = new THREE.Mesh( geometry, material );
            mesh.position.set( x, y, z );
            mesh.scale.set( s, s, s );
            scene.add( mesh );
        }

        function toHex(d) {
            var valueStr = d.toString(16); 
            valueStr = valueStr.length < 2 ? "0"+valueStr : valueStr; 
            var fillColor = "0x00" + valueStr + "00"; 
            return parseInt(fillColor);
        }

        function drawData(data) {
            var rows = data.length;
            var cols = data[0].length;

            distanceBetweenCircles = Math.min(windowWidth/(cols), windowHeight/(rows));
            var radius = distanceBetweenCircles/2.0

            for(var i = 0; i < data.length; i++) {
                for (var j = 0; j < data[0].length; j++) {
                    var color = toHex(data[i][j])
                    var x = distanceBetweenCircles*j - radius
                    var y = distanceBetweenCircles*i - radius
                    addCircle( color, x, y, 0, 1 , radius-3);
                }
            }
        }

        function newData(){
            var newData = []
            for (var i = 0; i < ROWS; i++) {
                var row = [];
                for (var j = 0; j < COLS; j ++) {
                    row.push(Math.floor(Math.random()*255));
                }
                newData.push(row);
            }
            return newData;
        }

        function onDocumentMouseDown ( event ) {
            event.preventDefault();

            // Update circles 
            var randomData = newData()
            drawData(randomData);
        }

        var render = function() {
            requestAnimationFrame(render);
            renderer.render(scene, camera);
        }

        init(); 
        render();
        </script>
    </body>
</html>
EN

回答 3

Stack Overflow用户

发布于 2014-09-13 08:41:49

若要将绘制对象添加到场景中,需要将圆绘制为。将圆的图像/纹理添加到场景中需要将圆打印为。

再乘以4000,绘图就会变得相当昂贵。

票数 0
EN

Stack Overflow用户

发布于 2016-12-13 05:09:51

与每次单击鼠标都创建一组新的几何体、材质和网格相比,维护一组网格并更新其属性会更快。

票数 0
EN

Stack Overflow用户

发布于 2014-04-08 00:14:09

内存管理在软件设计中非常重要。您引入的每个变量都是有成本的,特别是那些在API调用后实例化调用级联分配的变量。这是使用三层的缺点,它隐藏了复杂性,但也隐藏了使用其调用的后果。不要避免使用THREE并自己完成所有的WebGL管道(在忽略管道之前,这总是一个很好的第一步,只使用像THREE这样的填充程序),在调用任何WebGL时,做一些功课来确定正在创建的是什么。为对象创建内部循环变量,这些变量应该在调用之间重用。对于你的问题,是的,一旦仔细考虑过你的架构,你可以很容易地在每个动画事件循环时间片上更新4000个圆,特别是如果你使用着色器来制作你的对象,并避免在CPU中进行这样的计算。

为了纯粹的速度,我建议你通过手工编写OpenGL/WebGL来学习图形,而不是通过更高级别的抽象库Three.js……太容易使用的代价是更高的计算负载不必要的逻辑,这是可以削减,如果手工编写

这是我做的一个没有Three.js的WebGL玩具...它可以实时更新上千个对象的几何形状,还可以使用Web audio API渲染音频

https://github.com/scottstensland/webgl-3d-animation

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22879206

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档