Public
Edited
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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more