WebGL 2 shader
This commit is contained in:
commit
61faec2e92
4 changed files with 194 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
.make.*
|
42
fragshader.glsl
Normal file
42
fragshader.glsl
Normal file
|
@ -0,0 +1,42 @@
|
|||
#version 300 es
|
||||
#define PI 3.1415926538
|
||||
#define maxIterations 100
|
||||
precision mediump float;
|
||||
uniform float t;
|
||||
uniform vec2 screen_size;
|
||||
in vec4 v_pos;
|
||||
out vec4 fragColor;
|
||||
|
||||
vec2 squareImaginary(vec2 number){
|
||||
return vec2(
|
||||
pow(number.x,2.)-pow(number.y,2.),
|
||||
2.*number.x*number.y
|
||||
);
|
||||
}
|
||||
|
||||
float iterateMandelbrot(vec2 coord) {
|
||||
vec2 z = vec2(0.,0.);
|
||||
for(int i=0; i<maxIterations; i++) {
|
||||
float l = length(z);
|
||||
z = squareImaginary(z) + coord;
|
||||
if(l > 2.) {
|
||||
return float(i)/float(maxIterations);
|
||||
}
|
||||
}
|
||||
return 1.;
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
float aspect = screen_size.x / screen_size.y;
|
||||
mat2 squash = mat2(aspect, 0., 0., 1.);
|
||||
vec2 pos = squash * v_pos.xy;
|
||||
float r = length(pos.xy);
|
||||
vec2 centre = vec2(0.367,0.6955);
|
||||
float bounce = 1.;//(cos(t*0.1) + 1.)/2.;
|
||||
float zoom = 0.5 / (1. + 200.*(1.-bounce));
|
||||
//float zoom = 1.;
|
||||
float m = iterateMandelbrot(pos * zoom + centre);
|
||||
float c = m==1. ? 1. : m*0.8;
|
||||
vec4 color = vec4(c, c, c, 1.0);
|
||||
fragColor = color;
|
||||
}
|
23
index.html
Normal file
23
index.html
Normal file
|
@ -0,0 +1,23 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>A thing made by CLP</title>
|
||||
<script type="module" src="script.js"></script>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
canvas {
|
||||
width: 100svw;
|
||||
height: 100svh;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="glCanvas" width="600" height="450"></canvas>
|
||||
<p><a href="https://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf">WebGL reference card</a></p>
|
||||
<pre id="errors"></pre>
|
||||
</body>
|
||||
</html>
|
128
script.js
Normal file
128
script.js
Normal file
|
@ -0,0 +1,128 @@
|
|||
console.clear();
|
||||
|
||||
function error(...msgs) {
|
||||
const msg = msgs.join('\n');
|
||||
console.error(msg);
|
||||
document.getElementById('errors').textContent = msg;
|
||||
}
|
||||
|
||||
function loadShader(gl, type, source) {
|
||||
const shader = gl.createShader(type);
|
||||
|
||||
gl.shaderSource(shader, source);
|
||||
gl.compileShader(shader);
|
||||
|
||||
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
||||
error('An error occurred compiling the shaders:', gl.getShaderInfoLog(shader));
|
||||
gl.deleteShader(shader);
|
||||
return null;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
function initShaderProgram(gl, vs, fs) {
|
||||
const shaderProgram = gl.createProgram();
|
||||
gl.attachShader(shaderProgram, vs);
|
||||
gl.attachShader(shaderProgram, fs);
|
||||
gl.linkProgram(shaderProgram);
|
||||
|
||||
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
|
||||
error('Unable to initialize the shader program:', gl.getProgramInfoLog(shaderProgram));
|
||||
return null;
|
||||
}
|
||||
|
||||
return shaderProgram;
|
||||
}
|
||||
|
||||
function initBuffers(gl) {
|
||||
const vertices = new Float32Array([
|
||||
-1, 1,
|
||||
1, 1,
|
||||
-1, -1,
|
||||
-1, -1,
|
||||
1, 1,
|
||||
1, -1
|
||||
]);
|
||||
|
||||
const vertexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
|
||||
|
||||
return vertexBuffer;
|
||||
}
|
||||
|
||||
async function init() {
|
||||
|
||||
const vsSource = `#version 300 es
|
||||
in vec4 aVertexPosition;
|
||||
|
||||
out vec4 v_pos;
|
||||
|
||||
void main(void) {
|
||||
gl_Position = aVertexPosition;
|
||||
v_pos = gl_Position;
|
||||
}
|
||||
`;
|
||||
|
||||
const fsSource = await (await fetch('fragshader.glsl')).text();
|
||||
|
||||
console.log(fsSource);
|
||||
|
||||
|
||||
function set_canvas_size() {
|
||||
const dpr = window.devicePixelRatio;
|
||||
const {clientWidth: width, clientHeight: height} = canvas;
|
||||
canvas.width = Math.round(width * dpr);
|
||||
canvas.height = Math.round(height * dpr);
|
||||
}
|
||||
|
||||
function drawScene() {
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
const vertexPosition = gl.getAttribLocation(shaderProgram, 'aVertexPosition');
|
||||
const tLoc = gl.getUniformLocation(shaderProgram, "t");
|
||||
const screen_sizeLoc = gl.getUniformLocation(shaderProgram, "screen_size");
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
|
||||
const t = (new Date() - t1) / 1000;
|
||||
gl.uniform1f(tLoc, t);
|
||||
gl.uniform2fv(screen_sizeLoc, [canvas.width, canvas.height]);
|
||||
gl.vertexAttribPointer(vertexPosition, 2, gl.FLOAT, false, 0, 0);
|
||||
gl.enableVertexAttribArray(vertexPosition);
|
||||
|
||||
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
|
||||
|
||||
gl.useProgram(shaderProgram);
|
||||
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
||||
|
||||
requestAnimationFrame(drawScene);
|
||||
}
|
||||
|
||||
let mx = 0, my = 0;
|
||||
|
||||
const canvas = document.getElementById('glCanvas');
|
||||
set_canvas_size();
|
||||
const gl = canvas.getContext('webgl2');
|
||||
|
||||
if (!gl) {
|
||||
throw new Error('Unable to initialize WebGL. Your browser may not support it.');
|
||||
}
|
||||
if (gl) {
|
||||
gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
|
||||
const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
|
||||
|
||||
const shaderProgram = initShaderProgram(gl, vertexShader, fragmentShader);
|
||||
|
||||
const vertexBuffer = initBuffers(gl);
|
||||
const t1 = new Date();
|
||||
drawScene();
|
||||
|
||||
const resize_observer = new ResizeObserver((entries) => set_canvas_size());
|
||||
resize_observer.observe(canvas);
|
||||
}
|
||||
|
||||
init();
|
Loading…
Add table
Add a link
Reference in a new issue