"use strict";
var gl = twgl.getWebGLContext(document.getElementById("c"));
var programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);
// make a rainbow circle texture from a 2d canvas as it's easier than downloading
var ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = 128;
ctx.canvas.height = 128;
var gradient = ctx.createRadialGradient(64,64,60,64,64,0);
for (var i = 0; i <= 12; ++i) {
gradient.addColorStop(i / 12,"hsl(" + (i / 12 * 360) + ",100%,50%");
}
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 128, 128);
// make points and segment data
var numSegmentsAcross = 6;
var numSegmentsDown = 5;
var positions = [];
var segments = [];
for (var y = 0; y < numSegmentsDown; ++y) {
for (var x = 0; x < numSegmentsAcross; ++x) {
positions.push(x / (numSegmentsAcross - 1) * 2 - 1, y / (numSegmentsDown - 1) * 2 - 1);
segments.push(x, y);
}
}
var arrays = {
position: { size: 2, data: positions },
segment: { size: 2, data: segments },
};
var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);
var tex = twgl.createTexture(gl, { src: ctx.canvas });
var uniforms = {
u_numSegments: [numSegmentsAcross, numSegmentsDown],
u_texture: tex,
};
gl.useProgram(programInfo.program);
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
twgl.setUniforms(programInfo, uniforms);
twgl.drawBufferInfo(gl, gl.POINTS, bufferInfo);
canvas { border: 1px solid black; }
<script id="vs" type="notjs">
attribute vec4 position;
attribute vec2 segment;
varying vec2 v_segment;
void main() {
gl_Position = position;
v_segment = segment;
gl_PointSize = 20.0;
}
</script>
<script id="fs" type="notjs">
precision mediump float;
varying vec2 v_segment;
uniform vec2 u_numSegments;
uniform sampler2D u_texture;
void main() {
vec2 uv = (v_segment + vec2(gl_PointCoord.x, 1.0 - gl_PointCoord.y)) / u_numSegments;
gl_FragColor = texture2D(u_texture, uv);
}
</script>
<script src="https://twgljs.org/dist/twgl.min.js"></script>
<canvas id="c"></canvas>