Public
Edited
Jun 5, 2024
Insert cell
Insert cell
Insert cell
Insert cell
canvas = DOM.canvas(width, 500)
Insert cell
Insert cell
Insert cell
Insert cell
regl.frame(function (context) {
regl.clear({
color: [0, 0, 0, 1]
});

// updated using tick (continuous update regardless of resizing)
const tick = context.tick;
for (var i = 0; i < N * N; i++) {
angle[i] = tick * 0.02 + angleInit[i]; //
}

angleBuffer.subdata(angle);

draw();
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
draw = regl({
frag: `
precision mediump float;
varying vec3 vColor;
void main() {
gl_FragColor = vec4(vColor, 1.0);
}`,

vert: `
precision mediump float;
attribute vec2 position;

// 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(offsetArray),
divisor: 1 // one separate offset for every triangle.
},

color: {
buffer: regl.buffer(colorArray),
divisor: 1 // one separate color for every triangle
},

angle: {
buffer: angleBuffer, // dynamic 으로 설정됨
divisor: 1 // 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
})
Insert cell
offsetArray = Array(N * N) // 길이가 N * N인 배열을 생성
.fill() // fill()로 모든 요소를 undefined로 채우기
.map((_, i) => {
// _는 요소 값(undefined), i는 인덱스
var x = -1 + (2 * Math.floor(i / N)) / N + 0.1; // 행 (소수점버림)
var y = -1 + (2 * (i % N)) / N + 0.1; // 열
return [x, y];
})
Insert cell
colorArray = Array(N * N)
.fill()
.map((_, i) => {
var r = Math.floor(i / N) / N;
var g = (i % N) / N;
return [r, g, r * g + 0.2];
})
Insert cell
Insert cell
// 각 삼각형의 회전 각도를 저장할 버퍼를 생성
// 버퍼는 GPU 메모리에 데이터를 저장하고, 이 데이터를 셰이더 프로그램에서 사용할 수 있게 함
// This buffer stores the angles of all the instanced triangles
angleBuffer = regl.buffer({
length: angle.length * 4, // float 데이터 타입의 크기는 4바이트
type: "float",
usage: "dynamic" // static, dynamic (데이터가 자주 변경), stream (데이터가 매 프레임마다 변경)
})
Insert cell
Insert cell
angle = Array.from(angleInit)
Insert cell
angleInit = {
let angleArray = [];
for (var i = 0; i < N * N; i++) {
angleArray[i] = Math.random() * (2 * Math.PI); // random initial angle
}
return angleArray;
}
Insert cell
N = 10 // N은 가로와 세로에 배치된 삼각형의 수
Insert cell
Insert cell
regl = (await import("https://cdn.skypack.dev/regl@2")).default({
canvas,
extensions: ["angle_instanced_arrays"]
})
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more