数据篇31 # 如何对海量数据进行优化性能?
Posted 凯小默
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据篇31 # 如何对海量数据进行优化性能?相关的知识,希望对你有一定的参考价值。
说明
【跟月影学可视化】学习笔记。
渲染动态的地理位置
用随机的小圆点模拟地图的小圆点,实现呼吸灯效果
最简单的做法:先创建圆的几何顶点数据,然后对每个圆设置不同的参数来分别一个一个圆绘制上去。
<!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(单位是像素)来改变点图元的大小。
利用点图元绘制圆的过程:
- 先通过点图元,改变 gl_PointSize 来设置顶点的大小,只需要一个顶点就可以绘制出矩形
- 然后通过计算到圆心的距离得出距离场,然后通过 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以上是关于数据篇31 # 如何对海量数据进行优化性能?的主要内容,如果未能解决你的问题,请参考以下文章
使用用户定义的函数在 BigQuery 数据集中插入海量数据时如何优化性能