Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在浏览器中显示400万个二维正方形的最有效方式是什么?_Javascript_Html_Canvas_Three.js_Webgl - Fatal编程技术网

Javascript 在浏览器中显示400万个二维正方形的最有效方式是什么?

Javascript 在浏览器中显示400万个二维正方形的最有效方式是什么?,javascript,html,canvas,three.js,webgl,Javascript,Html,Canvas,Three.js,Webgl,我的显示器的分辨率为7680x4320像素。我想显示多达400万个不同颜色的方块。我想用滑块改变正方形的数目。如果当前有两个版本。一个是canvas fillRect,看起来像这样: var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); for (var i = 0; i < num_squares; i ++) { ctx.fillStyle

我的显示器的分辨率为7680x4320像素。我想显示多达400万个不同颜色的方块。我想用滑块改变正方形的数目。如果当前有两个版本。一个是canvas fillRect,看起来像这样:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

for (var i = 0; i < num_squares; i ++) {

   ctx.fillStyle = someColor;
   ctx.fillRect(pos_x, pos_y, pos_x + square_width, pos_y + square_height);

   // set pos_x and pos_y for next square
}
var c=document.getElementById(“myCanvas”);
var ctx=c.getContext(“2d”);
对于(变量i=0;i
还有一个是webGL和三个.js。相同的循环,但我为每个正方形创建了长方体几何体和网格:

var geometry = new THREE.BoxGeometry( width_height, width_height, 0);

for (var i = 0; i < num_squares; i ++) {

   var material = new THREE.MeshLambertMaterial( { color: Math.random() * 0xffffff } );
   material.emissive = new THREE.Color( Math.random(), Math.random(), Math.random() );

   var object = new THREE.Mesh( geometry, material );

}
var geometry=new THREE.BoxGeometry(width\u height,width\u height,0);
对于(变量i=0;i
它们在几千个方格上都能很好地工作。第一个版本最多可以完成一百万个方块,但是超过一百万的速度太慢了。我想动态更新颜色和方块数

是否有人提供了如何使用three.js/WebGL/Canvas提高效率的技巧

EDIT1:第二个版本:这是我在开始和滑块更改时所做的:
//从场景中删除所有对象
var obj,i;
对于(i=scene.children.length-1;i>=0;i--){
obj=场景。儿童[i];
if(obj!==摄像机){
场景。移除(obj);
}
}
//用新对象填充场景
num_squares=gui_dat.squaresnum;
var window_pixel=window.innerWidth*window.innerHeight;
var pixel_per_square=窗口像素/num_square;
var width_height=Math.floor(Math.sqrt(每平方像素));
var geometry=新的三个.BoxGeometry(宽度\高度,宽度\高度,0);
var pos_x=宽度和高度/2;
var pos_y=宽度和高度/2;
对于(变量i=0;i窗口内部宽度){
位置x=宽度x高度/2;
位置y+=宽度和高度;
}
场景。添加(对象);
}

我建议尝试pixi框架(如上述评论所述)

它有webgl渲染器,一些基准测试非常有前途

它可以处理动画精灵的分配。
如果你的应用程序只显示方块,而不设置动画,而且它们是非常简单的精灵(只有一种颜色),那么它的性能将比上面的演示链接更好。

到目前为止,我看到的最高点数是potree

,

尝试一些演示,我能够以20-30fps的速度在3D中观察到500万个点。我相信这也是目前的技术限制

我没有自己测试potree,所以我不能对这项技术说太多。但是有数据转换器和查看器(基于threejs),所以应该只知道如何转换数据

简单谈谈你的问题

处理大型数据的最佳方法是将它们分组为四叉树(2d)或oct树(3d)。这将使您不必为距离摄影机太远或根本看不见的零件而费心编程

另一方面,当您执行太多webgl调用时,程序不喜欢。试着这样理解它,你需要每秒创建约60幅图像。但每次为GPU设置一些参数时,程序都必须进行一些同步。拆分数据意味着您需要进行更多的设置,所以树不能太详细

最后,有人说:

您可能希望传递一个值数组作为一个着色器

我不建议,这是个坏主意。纹理查找相当快,但属性总是更快。如果我们谈论的是400万点,你就负担不起从制服上读取数据


很抱歉,我无法帮助您编写代码,我可以在没有threejs的情况下完成,我不是threejs专家:)

绘制正方形的最快方法是使用gl.POINTS原语,然后将gl\u PointSize设置为像素大小

在three.js中,gl.POINTS被包装在three.PointCloud对象中。 您必须为每个点创建一个具有一个位置的几何体对象,并将其传递给点云构造函数

下面是THREE.PointCloud运行的一个示例:

geometry=new THREE.geometry();
对于(i=0;i

我没有仔细阅读所有的代码,但我已经将粒子数设置为2m,据我所知,生成了5个点云,因此生成了2m*5=10m的粒子,我得到了大约30fps的速度。

怎么办?这是一个2D加速框架。我认为400万对于今天的计算能力来说是一个非常巨大的数字…第二个屏幕可以显示多少个方块?只更新发生了什么变化?如果每秒只有很少的方块变化,这会有所帮助。画布对于许多填充都会很慢。对于三种方法,是否在每帧重新创建长方体?我不能
// Remove all objects from scene
            var obj, i;
            for ( i = scene.children.length - 1; i >= 0 ; i -- ) {
                obj = scene.children[ i ];
                if ( obj !== camera) {
                    scene.remove(obj);
                }
            }

            // Fill scene with new objects
            num_squares = gui_dat.squareNum;

            var window_pixel = window.innerWidth * window.innerHeight;
            var pixel_per_square = window_pixel / num_squares;
            var width_height = Math.floor(Math.sqrt(pixel_per_square));

            var geometry = new THREE.BoxGeometry( width_height, width_height, 0);

            var pos_x = width_height/2;
            var pos_y = width_height/2;

            for (var i = 0; i < num_squares; i ++) {

                //var object = new THREE.Mesh( geometry,  );

                var material = new THREE.Material()( { color: Math.random() * 0xffffff } );
                material.emissive = new THREE.Color( Math.random(), Math.random(), Math.random() );

                var object = new THREE.Mesh( geometry, material );

                object.position.x = pos_x;
                object.position.y = pos_y;

                pos_x += width_height;
                if (pos_x > window.innerWidth) {

                    pos_x = width_height/2;
                    pos_y += width_height;
                }

                scene.add( object );

            }
geometry = new THREE.Geometry();

for (i = 0; i < particleCount; i++) {

    var vertex = new THREE.Vector3();
    vertex.x = Math.random() * 2000 - 1000;
    vertex.y = Math.random() * 2000 - 1000;
    vertex.z = Math.random() * 2000 - 1000;

    geometry.vertices.push(vertex);
}

...

materials[i] = new THREE.PointCloudMaterial({size:size});
particles = new THREE.PointCloud(geometry, materials[i]);