var program, colorsLoc, modelLoc, loc, text = " interpolation. Click for ", model = "RGB"; // or sRGB
const vertSrc = `#version 300 es
in vec2 verts;
out vec2 coord2D;
void main() {
coord2D = verts * 0.5 + 0.5; // convert to quad space 0,0 <=> 1, 1
gl_Position = vec4(verts, 1, 1);
}`;
const fragSrc = `#version 300 es
#define channelMax 255.0
// color location indexes
#define TR 3
#define TL 2
#define BR 1
#define BL 0
precision mediump float;
uniform vec3 colors[4];
uniform bool isRGB;
in vec2 coord2D;
out vec4 pixel;
void main() {
if (isRGB) {
pixel = vec4(vec3(mix(
mix(colors[BL], colors[BR], coord2D.x),
mix(colors[TL], colors[TR], coord2D.x),
coord2D.y
)) / channelMax, 1);
} else {
pixel = vec4(vec3(sqrt(mix(
mix(colors[BL], colors[BR], coord2D.x),
mix(colors[TL], colors[TR], coord2D.x),
coord2D.y
))) / channelMax, 1);
}
}`;
const fArr = arr => new Float32Array(arr);
const colors = [64,140,190, 224,81,141, 247,223,140, 245,245,245];
const gl = canvas.getContext("webgl2", {premultipliedAlpha: false, antialias: false, alpha: false});
addEventListener("resize", draw);
addEventListener("click", draw);
setup();
draw();
function compileShader(src, type, shader = gl.createShader(type)) {
gl.shaderSource(shader, src);
gl.compileShader(shader);
return shader;
}
function setup() {
program = gl.createProgram();
gl.attachShader(program, compileShader(vertSrc, gl.VERTEX_SHADER));
gl.attachShader(program, compileShader(fragSrc, gl.FRAGMENT_SHADER));
gl.linkProgram(program);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([0,1,2,0,2,3]), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, fArr([-1,-1,1,-1,1,1,-1,1]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(loc = gl.getAttribLocation(program, "verts"));
gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);
colorsLoc = gl.getUniformLocation(program, "colors");
modelLoc = gl.getUniformLocation(program, "isRGB");
gl.useProgram(program);
}
function draw() {
[info.textContent, model] = model != "RGB"? [`RGB${text}~sRGB.`, "RGB"]: [`~sRGB${text}RGB.`, "~sRGB"];
if (canvas.width !== innerWidth || canvas.height !== innerHeight) {
[canvas.width, canvas.height] = [innerWidth, innerHeight];
gl.viewport(0, 0, canvas.width, canvas.height);
}
gl.uniform3fv(colorsLoc, fArr(colors.map(v => model=="RGB"? v: v*v)), 0, 12);
gl.uniform1i(modelLoc, model=="RGB");
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
}
body {
padding: 0px;
margin: 0px;
font-family: arial;
color: white;
}
canvas {
position: absolute;
top: 0px;
left: 0px;
}
h2 {
position: absolute;
bottom: 0px;
left: 0px;
right: 0px;
text-align: center;
}
<canvas id="canvas"></canvas>
<h2 id="info"></h2>