【数据篇】31 # 如何对海量数据进行优化性能?

news2024/12/27 14:56:36

说明

【跟月影学可视化】学习笔记。

渲染动态的地理位置

用随机的小圆点模拟地图的小圆点,实现呼吸灯效果

在这里插入图片描述

最简单的做法:先创建圆的几何顶点数据,然后对每个圆设置不同的参数来分别一个一个圆绘制上去。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>渲染动态的地理位置</title>
        <style>
            canvas {
                border: 1px dashed #fa8072;
            }
        </style>
    </head>
    <body>
        <canvas width="500" height="500"></canvas>
        <script src="./common/lib/gl-renderer.js"></script>
        <script>
            const canvas = document.querySelector("canvas");
            const renderer = new GlRenderer(canvas);

            const vertex = `
                attribute vec2 a_vertexPosition;
                uniform vec2 xy;
                uniform float uTime;
                uniform float bias;

                void main() {
                    vec3 pos = vec3(a_vertexPosition, 1);
                    float scale = 0.7 + 0.3 * sin(6.28 * bias + 0.003 * uTime);
                    mat3 m = mat3(
                        scale, 0, 0,
                        0, scale, 0,
                        xy, 1
                    );
                    gl_Position = vec4(m * pos, 1);
                }
            `;

            const fragment = `
                #ifdef GL_ES
                precision highp float;
                #endif

                uniform vec4 u_color;
                
                void main() {
                    gl_FragColor = u_color;
                }
            `;
            const program = renderer.compileSync(fragment, vertex);
            renderer.useProgram(program);

            function circle(radius = 0.05) {
                const delta = (2 * Math.PI) / 32;
                const positions = [];
                const cells = [];
                for (let i = 0; i < 32; i++) {
                    const angle = i * delta;
                    positions.push([
                        radius * Math.sin(angle),
                        radius * Math.cos(angle),
                    ]);
                    if (i > 0 && i < 31) {
                        cells.push([0, i, i + 1]);
                    }
                }
                return { positions, cells };
            }

            const COUNT = 500;
            function init() {
                const meshData = [];
                const { positions, cells } = circle();
                for (let i = 0; i < COUNT; i++) {
                    const x = 2 * Math.random() - 1;
                    const y = 2 * Math.random() - 1;
                    const rotation = 2 * Math.PI * Math.random();
                    const uniforms = {};

                    uniforms.u_color = [
                        Math.random(),
                        Math.random(),
                        Math.random(),
                        1,
                    ];

                    uniforms.xy = [
                        2 * Math.random() - 1,
                        2 * Math.random() - 1,
                    ];

                    uniforms.bias = Math.random();

                    meshData.push({
                        positions,
                        cells,
                        uniforms,
                    });
                }
                renderer.uniforms.uTime = 0;
                renderer.setMeshData(meshData);
            }
            init();

            function update(t) {
                renderer.uniforms.uTime = t;
                renderer.render();
                requestAnimationFrame(update);
            }

            update(0);
        </script>
    </body>
</html>

效果如下:在绘制 500 个圆的时候,浏览器的帧率就掉到 7 fps 左右了。

在这里插入图片描述

优化大数据渲染的常见方法

1、使用批量渲染优化

绘制大量同种几何图形的时候,通过减少渲染次数来提升性能最好的做法是直接使用批量渲染。

代码如下:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>使用批量渲染优化</title>
        <style>
            canvas {
                border: 1px dashed #fa8072;
            }
        </style>
    </head>
    <body>
        <canvas width="500" height="500"></canvas>
        <script src="./common/lib/gl-renderer.js"></script>
        <script>
            const canvas = document.querySelector("canvas");
            const renderer = new GlRenderer(canvas);

            const vertex = `
                attribute vec2 a_vertexPosition;
                attribute vec4 color;
                attribute vec2 xy;
                attribute float bias;
                uniform float uTime;

                varying vec4 vColor;

                void main() {
                    vec3 pos = vec3(a_vertexPosition, 1);
                    float scale = 0.7 + 0.3 * sin(6.28 * bias + 0.003 * uTime);
                    mat3 m = mat3(
                        scale, 0, 0,
                        0, scale, 0,
                        xy, 1
                    );
                    vColor = color;
                    gl_Position = vec4(m * pos, 1);
                }
            `;

            const fragment = `
                #ifdef GL_ES
                precision highp float;
                #endif

                varying vec4 vColor;
                
                void main() {
                    gl_FragColor = vColor;
                }
            `;

            const program = renderer.compileSync(fragment, vertex);
            renderer.useProgram(program);

            function circle(radius = 0.05) {
                const delta = (2 * Math.PI) / 32;
                const positions = [];
                const cells = [];
                for (let i = 0; i < 32; i++) {
                    const angle = i * delta;
                    positions.push([
                        radius * Math.sin(angle),
                        radius * Math.cos(angle),
                    ]);
                    if (i > 0 && i < 31) {
                        cells.push([0, i, i + 1]);
                    }
                }
                return { positions, cells };
            }

            const COUNT = 20000;
            function init() {
                const { positions, cells } = circle();
                const colors = [];
                const pos = [];
                const bias = [];
                for (let i = 0; i < COUNT; i++) {
                    const x = 2 * Math.random() - 1;
                    const y = 2 * Math.random() - 1;
                    const rotation = 2 * Math.PI * Math.random();

                    colors.push([
                        Math.random(),
                        Math.random(),
                        Math.random(),
                        1,
                    ]);

                    pos.push([2 * Math.random() - 1, 2 * Math.random() - 1]);

                    bias.push(Math.random());
                }

                renderer.uniforms.uTime = 0;
                renderer.setMeshData({
                    positions,
                    cells,
                    instanceCount: COUNT,
                    attributes: {
                        color: { data: [...colors], divisor: 1 },
                        xy: { data: [...pos], divisor: 1 },
                        bias: { data: [...bias], divisor: 1 },
                    },
                });
            }
            init();

            function update(t) {
                renderer.uniforms.uTime = t;
                renderer.render();
                requestAnimationFrame(update);
            }

            update(0);
        </script>
    </body>
</html>

渲染20000个点效果:

在这里插入图片描述

2、使用点图元优化

在 WebGL 中,点图元是最简单的图元,它用来显示画布上的点,在顶点着色器里,可以通过设置 gl_PointSize(单位是像素)来改变点图元的大小。

利用点图元绘制圆的过程:

  1. 先通过点图元,改变 gl_PointSize 来设置顶点的大小,只需要一个顶点就可以绘制出矩形
  2. 然后通过计算到圆心的距离得出距离场,然后通过 smoothstep 将一定距离内的图形绘制出来,这样就得到图形圆。
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>使用点图元优化</title>
        <style>
            canvas {
                border: 1px dashed #fa8072;
            }
        </style>
    </head>
    <body>
        <canvas width="500" height="500"></canvas>
        <script src="./common/lib/gl-renderer.js"></script>
        <script>
            const canvas = document.querySelector("canvas");
            const renderer = new GlRenderer(canvas);

            const vertex = `
                attribute vec2 a_vertexPosition;
                attribute vec4 color;
                attribute float bias;

                uniform float uTime;
                uniform vec2 uResolution;

                varying vec4 vColor;
                varying vec2 vPos;
                varying vec2 vResolution;
                varying float vScale;

                void main() {
                    float scale = 0.7 + 0.3 * sin(6.28 * bias + 0.003 * uTime);
                    gl_PointSize = 0.05 * uResolution.x * scale;
                    vColor = color;
                    vPos = a_vertexPosition;
                    vResolution = uResolution;
                    vScale = scale;
                    gl_Position = vec4(a_vertexPosition, 1, 1);
                }
            `;

            const fragment = `
                #ifdef GL_ES
                precision highp float;
                #endif

                varying vec4 vColor;
                varying vec2 vPos;
                varying vec2 vResolution;
                varying float vScale;
                
                void main() {
                    vec2 st = gl_FragCoord.xy / vResolution;
                    st = 2.0 * st - vec2(1);
                    float d = step(distance(vPos, st), 0.05 * vScale);
                    gl_FragColor = d * vColor;
                }
            `;
            const program = renderer.compileSync(fragment, vertex);
            renderer.useProgram(program);

            const COUNT = 20000;
            function init() {
                const colors = [];
                const pos = [];
                const bias = [];
                for (let i = 0; i < COUNT; i++) {
                    const x = 2 * Math.random() - 1;
                    const y = 2 * Math.random() - 1;
                    const rotation = 2 * Math.PI * Math.random();

                    colors.push([
                        Math.random(),
                        Math.random(),
                        Math.random(),
                        1,
                    ]);

                    pos.push([2 * Math.random() - 1, 2 * Math.random() - 1]);

                    bias.push(Math.random());
                }

                renderer.uniforms.uTime = 0;
                renderer.uniforms.uResolution = [canvas.width, canvas.height];

                renderer.setMeshData({
                    mode: renderer.gl.POINTS,
                    enableBlend: true,
                    positions: pos,
                    attributes: {
                        color: { data: [...colors] },
                        bias: { data: [...bias] },
                    },
                });
            }
            init();

            function update(t) {
                renderer.uniforms.uTime = t;
                renderer.render();
                requestAnimationFrame(update);
            }

            update(0);
        </script>
    </body>
</html>

渲染20000个点效果:

在这里插入图片描述

其他方法

1、使用后期处理通道优化

后期处理通道十分强大,它最重要的特性就是可以把各种数据存储在纹理图片中。这样在迭代处理的时候,我们就可以用 GPU 将这些数据并行地读取和处理,从而达到非常高效地渲染。

用后期处理通道实现了粒子流的效果:https://oframe.github.io/ogl/examples/?src=post-fluid-distortion.html

在这里插入图片描述

2、使用 GPGPU 优化

OGL 官网例子:https://oframe.github.io/ogl/examples/gpgpu-particles.html就是用了 GPGPU 的方式,也叫做通用 GPU 方式,就是把每个粒子的速度保存到纹理图片里,实现同时渲染几万个粒子并产生运动的效果。

在这里插入图片描述

3、使用服务端渲染优化

https://github.com/akira-cn/node-canvas-webgl 它可以在 Node.js 中启动一个 Canvas2D 和 WebGL 环境,可以在服务端进行渲染,然后再将结果缓存起来直接提供给客户端。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/137336.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何使用python删除一个文件?别说,还挺好用....

嗨害大家好鸭&#xff01;我是小熊猫~ 若想利用python删除windows里的文件&#xff0c;这里需要使用os模块&#xff01;那接下来就看看利用os模块是如何删除文件的&#xff01; 具体实现方法如下&#xff01; 更多学习资料:点击此处跳转文末名片获取 os.remove(path) 删除文…

Java位运算符:Java移位运算符、复合位赋值运算符及位逻辑运算符

Java 定义的位运算&#xff08;bitwise operators&#xff09;直接对整数类型的位进行操作&#xff0c;这些整数类型包括 long&#xff0c;int&#xff0c;short&#xff0c;char 和 byte。位运算符主要用来对操作数二进制的位进行运算。按位运算表示按每个二进制位&#xff08…

GitLab安装使用(SSH+Docker两种方式)

GitLab安装使用1、在ssh下安装gitlab1.1 安装依赖1.2 配置镜像1.3 开始安装1.4 gitlab常用命令2、在docker下安装gitlab2.1 安装docker2.1.1 更新yum源2.1.2 安装依赖2.1.3 添加镜像2.1.4 查看源中可用版本2.1.5 安装指定版本2.1.6 配置开机启动项2.2 使用容器安装gitlab2.2.1 …

车载以太网 - DoIP头部信息检测逻辑 - 03

通过前面的文章我们已经了解了DoIP所具备的Payload类型,基础的信息都已经具备了,今天我们就要进一步的去了解DoIP的处理逻辑了;按照正常的逻辑来看,处理无论是我们人眼去看书,还是计算机处理一段数据,都是从前到后依次进行处理;而DoIP的信息处理也不例外,也是从头开始进…

2023跨境出海指南:印度网红营销白皮书

前不久&#xff0c;联合国预测印度人口将在4个月后超过中国&#xff0c;成为全球第一人口大国。印度这个国家虽然有些奇葩&#xff0c;但他们的经济实力确实不能小觑&#xff0c;这也是众多国际公司大力发展印度的原因。出海印度容易&#xff0c;但攻克印度市场太难&#xff0c…

Python Tutorial——类

与其它编程语言相比&#xff0c;Python的类机制添加了最小的新语法和语义。它是C和Modula-3中的类机制的混合。Python的类提供了面向对象编程的所有的标准特性&#xff0c;类继承机制允许有多个基类&#xff0c;一个子类可以重写基类中的任何方法&#xff0c;一个方法可以调用基…

编程思想图书推荐,新手入门应该看些啥

编程思想图书推荐&#xff0c;新手入门应该看些啥 导入 元旦的时候&#xff0c;学校社团的指导老师&#xff0c;咨询我有没有什么可以推荐的编程思想的学习书籍&#xff0c;可以值得推荐精读。 说实话&#xff0c;我个人是买过很多书的&#xff0c;但是很少读书&#xff0c;如果…

搭建redis主从复制+哨兵高可用

从服务器连接主服务器&#xff0c;发送SYNC命令&#xff1b;主服务器接收到SYNC命名后&#xff0c;开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令&#xff1b;主服务器BGSAVE执行完后&#xff0c;向所有从服务器发送快照文件&#xff0c;并在发送期间继续…

Window下安装oracle12C

1.Window下安装oracle12C 官网下载地址&#xff1a; Database Software Downloads | Oracle 页面顶部选择 “接受许可协议” 后&#xff0c;我想选择下载 12c 版的企业版&#xff0c;文件1和文件2都需要下载。&#xff08;如果提示登录 Oracle&#xff0c;则需要先登录才能下…

java家装网装修网站装修系统源码

简介 本平台主要是家装网站。管理员发布装修案例&#xff0c;看工地&#xff0c;装修设计师&#xff0c;装修攻略&#xff0c;装修知识文章等&#xff0c;嵌入3d全景图。普通用户注册&#xff0c;填写装修房型报价等。 演示视频&#xff1a; https://www.bilibili.com/video/…

Kotlin基础入门 - 静态变量、常量 And 静态函数、方法

2022一晃而过&#xff0c;2023悄然而至&#xff0c;有天晚上看第一行代码&#xff08;第三版&#xff09;的时候&#xff0c;又看到了Kotlin中静态方法的几种使用方式&#xff0c;蹭着过年还有一些时间&#xff0c;写了个Demo简单测试记录一下 在 Kotlin 中使用静态的方式不止一…

JavaScript基础系列之原型链

1. 前言 今天的重点复习的是JavaScript原型链。所谓是"基础不牢&#xff0c;地动山摇"&#xff0c;原型链作为继承等相关知识的基础&#xff0c;就显得尤为重要了。接下来以手绘原型链为基础&#xff0c;详解讲解下原型链以及相关的属性 2. 原型 以及原型链 2.1 pro…

vs 生成前事件 生成后事件命令

为了提高编译生成后的事件效率&#xff0c;不需要手动的拷贝到固定目录。可以在项目->属性中设备生成后事件。输入相应的命令行&#xff0c;即可。 Visual Studio中&#xff0c;可以在项目-》属性-》生成事件-》生成后事件命令行 xcopy 复制文件&#xff1b; /y/e 如果只复…

JavaEE【Spring】:MyBatis查询数据库

文章目录一、理论储备1、MyBatis 的概念2、MyBatis 的作用二、第⼀个MyBatis查询1、创建数据库和表2、添加MyBatis框架支持① 老项目添加MyBatisⅠ. 新增功能Ⅱ. EditStarters插件② 新项目添加MyBatis3、配置连接字符串和MyBatis① 配置连接字符串② 配置 MyBatis 中的 XML 路…

数据标注平台如何保护用户数据安全?

近期&#xff0c;在《麻省理工科技评论》在一篇万字长文调查中&#xff0c;一位年轻女子坐在自家的马桶上的图片也被扫地机器人拍摄下来&#xff0c;并被流传到网上、大范围传播。但事实上&#xff0c;这也并非是一件新鲜事了。例如&#xff0c;2020年秋&#xff0c;一系列从低…

为什么MySQL 要选择 B+树

一、什么是索引 在关系数据库中&#xff0c;索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构。再直白点就是我们可以把索引理解成图书或者字典的目录。 既然索引是数据的一种存储结构&#xff0c;那么我们必然要对其进行存储&#xff0c;同时&…

你可以不用Git,但不能不会Git(二)基础(上)

目录 一.环境配置 二.本地初始化仓库 三.文件的两种状态 四.文件加入暂存区 五.文件提交与删除 1.提交文件 2.删除文件 一.环境配置 当安装Git后首先要做的事情是设置用户名称和email地址。这是非 常重要的&#xff0c;因为每次Git提交都会使用该用户信息。 设置用户信…

#G. 红旗招展

Description小J占山为王有一段时间了&#xff0c;他决定把自己的地盘打扮一下---将各种颜色的旗插在山头上当然某一座的山头只能用一种颜色的旗。整个地盘有N个山头&#xff0c;可看成是一棵有N个节点的树。小J还是有一点艺术细胞的&#xff0c;他不想整个地盘杂乱无章。于是他…

Kubernetes安装ingress-controller

IngressController 1. 安装 1.1 查看ingress-nginx的版本匹配 https://github.com/kubernetes/ingress-nginx/blob/main/README.md#readme 下载配置 wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.2/deploy/static/provider/cloud/de…

【回答问题】ChatGPT上线了!给我推荐20个比较流行的图像实例分割模型

给我推荐20个比较流行的图像实例分割模型 U-Net Mask R-CNN FCN SegNet PSPNet DeepLabv3 DenseASPP LinkNet RefineNet ENet ICNet BiSeNet CRF-RNN GCN Tiramisu FRRN DeepLabv3 PANet MaskLab Hybrid Task Cascade给我推荐20个比较流行的图像实例分割模型源码 好的&#x…