原文链接: regl 多实例绘制ANGLE_instanced_arrays 和 instances
上一篇: regl vao 三角形交替
下一篇: regl batch 批量绘制三角形
https://developer.mozilla.org/zh-CN/docs/Web/API/ANGLE_instanced_arrays
http://www.jiazhengblog.com/blog/2017/03/20/3104/
说的很明确了, 主要是绘制相似的图形
ANGLE_instanced_arrays 是
属于 WebGL API 的一个扩展API,
它允许多次绘制相同的对象或相似对象组,前提是它们共享相同的顶点数据、基本图形的个数和类型。
divisor 表示每个属性应用到几个实例上, angle的divisor是5, 表示一个角度的数值应用到5个实例上
import createREGL from "regl";
export default (canvas: HTMLCanvasElement) => {
const regl = createREGL({ canvas, extensions: ["angle_instanced_arrays"] });
const N = 10; // N triangles on the width, N triangles on the height.
const divisor = 1;
const angle = Array(N * N)
.fill(0)
.map(() => Math.random() * (2 * Math.PI));
// This buffer stores the angles of all
// the instanced triangles.
const angleBuffer = regl.buffer({
length: angle.length * 4,
type: "float",
usage: "dynamic",
});
const draw = regl({
frag: `
precision mediump float;
varying vec3 vColor;
void main() {
gl_FragColor = vec4(vColor, 1.0);
}`,
vert: `
precision mediump float;
attribute vec2 position;
// These three are instanced attributes.
attribute vec3 color;
attribute vec2 offset;
attribute float angle;
varying vec3 vColor;
void main() {
gl_Position = vec4(
cos(angle) * position.x + sin(angle) * position.y + offset.x,
-sin(angle) * position.x + cos(angle) * position.y + offset.y, 0, 1);
vColor = color;
}`,
attributes: {
position: [
[0.0, -0.05],
[-0.05, 0.0],
[0.05, 0.05],
],
offset: {
buffer: regl.buffer(
Array(N * N)
.fill(0)
.map((_, i) => {
const x = -1 + (2 * Math.floor(i / N)) / N + 0.1;
const y = -1 + (2 * (i % N)) / N + 0.1;
return [x, y];
})
),
divisor, // one separate offset for every triangle.
},
color: {
buffer: regl.buffer(
Array(N * N)
.fill(0)
.map((_, i) => {
const r = Math.floor(i / N) / N;
const g = (i % N) / N;
return [r, g, r * g + 0.2];
})
),
divisor, // one separate color for every triangle
},
angle: {
buffer: angleBuffer,
divisor, // one separate angle for every triangle
},
},
depth: {
enable: false,
},
// Every triangle is just three vertices.
// However, every such triangle are drawn N * N times,
// through instancing.
count: 3,
instances: N * N,
});
regl.frame(function () {
regl.clear({
color: [0, 0, 0, 1],
});
// rotate the triangles every frame.
for (let i = 0; i < N * N; i++) {
angle[i] += 0.01;
}
angleBuffer.subdata(angle);
draw();
});
};