const canvas = document.createElement("canvas")
const gl = canvas.getContext("webgl2")
document.body.innerHTML = ""
document.body.appendChild(canvas)
document.body.style = "margin: 0;overflow: hidden;"
canvas.style.width = "100%"
canvas.style.height = "auto"
const dpr = window.devicePixelRatio
function resize() {
const {
innerWidth: width,
innerHeight: height
} = window
canvas.width = width * dpr
canvas.height = height * dpr
gl.viewport(0, 0, width * dpr, height * dpr)
}
window.onresize = resize
const vertexSource = `#version 300 es
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
in vec4 position;
void main(void) {
gl_Position = position;
}
`
const fragmentSource = `#version 300 es
/*********
* made by Matthias Hurrle (@atzedent)
*/
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
out vec4 fragColor;
uniform vec2 resolution;
uniform float time;
#define T time
#define S smoothstep
float box(vec3 p, vec3 s, float r) {
p = abs(p)-s;
return length(max(p,.0))+
min(.0,max(max(p.x,p.y),p.z))-r;
}
float map(vec3 p) {
p.y += sin(p.z*.2-.6)*1.25;
p.x -= sin(p.z*.125+.05)*4.;
return -box(p, vec3(1,1.65,20), .05);
}
void main(void) {
vec2 uv = (
gl_FragCoord.xy -.5 * resolution
) / min(resolution.x, resolution.y);
vec3 col = vec3(0),
rd = normalize(vec3(uv,1)),
p = vec3(1,0,0);
const float steps = 400.;
for (float i=.0; i<steps; i++) {
float d=map(p);
if (d<1e-3) {
col += (steps-i)/steps;
col *= S(.05,.0,sin(p.z+sin(p.z*.1)*2.+T*6.));
break;
}
p += rd*d;
}
fragColor = vec4(col, 1);
}
`
function compile(shader, source) {
gl.shaderSource(shader, source)
gl.compileShader(shader)
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error(gl.getShaderInfoLog(shader))
}
}
let program
function setup() {
const vs = gl.createShader(gl.VERTEX_SHADER)
const fs = gl.createShader(gl.FRAGMENT_SHADER)
compile(vs, vertexSource)
compile(fs, fragmentSource)
program = gl.createProgram()
gl.attachShader(program, vs)
gl.attachShader(program, fs)
gl.linkProgram(program)
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error(gl.getProgramInfoLog(program))
}
}
let vertices, buffer;
function init() {
vertices = [
-1,-1, 1,
-1,-1, 1,
-1, 1, 1,
-1, 1, 1
]
buffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW)
const position = gl.getAttribLocation(program, "position")
gl.enableVertexAttribArray(position)
gl.vertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0)
program.resolution = gl.getUniformLocation(program, "resolution")
program.time = gl.getUniformLocation(program, "time")
}
function loop(now) {
gl.clearColor(0, 0, 0, 1)
gl.clear(gl.COLOR_BUFFER_BIT)
gl.useProgram(program)
gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
gl.uniform2f(program.resolution, canvas.width, canvas.height)
gl.uniform1f(program.time, now * 1e-3)
gl.drawArrays(gl.TRIANGLES, 0, vertices.length * 0.5)
requestAnimationFrame(loop)
}
setup()
init()
resize()
loop(0)
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.