index.vert
#version 300 es
void main() {
float x = float((gl_VertexID & 1) << 2);
float y = float((gl_VertexID & 2) << 1);
gl_Position = vec4(x - 1.0, y - 1.0, 0, 1);
}
index.frag
#version 300 es
precision highp float;
uniform vec2 uResolution;
uniform float uTime;
out vec4 fragColor;
const uint UINT_MAX = 0xffffffffu;
uvec3 k = uvec3(0x456789abu, 0x6789ab45u, 0x89ab4567u);
uvec3 u = uvec3(1, 2, 3);
uvec2 uhash22(uvec2 n){
n ^= (n.yx << u.xy);
n ^= (n.yx >> u.xy);
n *= k.xy;
n ^= (n.yx << u.xy);
return n * k.xy;
}
vec2 hash22(vec2 b) {
uvec2 n = floatBitsToUint(b);
return vec2(uhash22(n)) / vec2(UINT_MAX);
}
const float cos_pi_in_8 = 0.923879533;
const float sin_pi_in_8 = 0.382683432;
float gtable2(vec2 lattice, vec2 p){
uvec2 n = floatBitsToUint(lattice);
uint ind = uhash22(n).x >> 29;
float u = ind < 4u ? p.x : p.y;
float v = ind < 4u ? p.y : p.x;
u *= cos_pi_in_8;
v *= sin_pi_in_8;
return ((ind & 1u) == 0u? u: -u) + ((ind & 2u) == 0u? v : -v);
}
vec2 hermite5(vec2 x) {
return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);
}
float pnoise21(vec2 p) {
vec2 p0 = floor(p);
vec2 p1 = p0 + vec2(1.0, 0.0);
vec2 p2 = p0 + vec2(0.0, 1.0);
vec2 p3 = p0 + vec2(1.0, 1.0);
vec2 f = fract(p);
vec2 d0 = f;
vec2 d1 = f - vec2(1.0, 0.0);
vec2 d2 = f - vec2(0.0, 1.0);
vec2 d3 = f - vec2(1.0, 1.0);
float dh0 = gtable2(p0, d0);
float dh1 = gtable2(p1, d1);
float dh2 = gtable2(p2, d2);
float dh3 = gtable2(p3, d3);
vec2 w = hermite5(f);
float i = mix(mix(dh0, dh1, w.x), mix(dh2, dh3, w.x), w.y);
return i * 0.5 + 0.5;
}
void main() {
vec2 pos = gl_FragCoord.xy / min(uResolution.x, uResolution.y);
pos *= 10.0;
pos += uTime;
float noise = pnoise21(pos);
fragColor = vec4(vec3(noise), 1.0);
}
render.ts
import { SketchFrg, type FragmentSketchConfig, type FragmentSketchFn } from "sketchgl"
import { Timer } from "sketchgl/interactive"
import { Uniforms } from "sketchgl/program"
import frag from "./index.frag?raw"
const sketch: FragmentSketchFn = ({ gl, canvas, program, renderToCanvas }) => {
const uniforms = new Uniforms(gl, ["uResolution", "uTime"])
uniforms.init(program)
const timer = new Timer()
timer.start()
gl.clearColor(0.0, 0.0, 0.0, 1.0)
gl.clearDepth(1.0)
return {
drawOnFrame() {
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height)
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
uniforms.float("uTime", timer.elapsed * 0.001)
uniforms.fvector2("uResolution", [canvas.width, canvas.height])
renderToCanvas()
}
}
}
export const onload = () => {
const config: FragmentSketchConfig = {
frag,
canvas: {
el: "gl-canvas",
fit: "screen",
autoResize: true
}
}
SketchFrg.init(config, sketch)
}