Note
This is one of 199 standalone projects, maintained as part of the @thi.ng/umbrella monorepo and anti-framework.
🚀 Please help me to work full-time on these projects by sponsoring me on GitHub. Thank you! ❤️
Basic WebGL scaffolding for running interactive fragment shaders via @thi.ng/shader-ast. This is a support package for @thi.ng/webgl.
ALPHA - bleeding edge / work-in-progress
Search or submit any issues for this package
- @thi.ng/shader-ast - DSL to define shader code in TypeScript and cross-compile to GLSL, JS and other targets
- @thi.ng/shader-ast-stdlib - Function collection for modular GPGPU / shader programming with @thi.ng/shader-ast
- @thi.ng/webgl - WebGL & GLSL abstraction layer
yarn add @thi.ng/webgl-shadertoy
ESM import:
import * as ws from "@thi.ng/webgl-shadertoy";
Browser ESM import:
<script type="module" src="https://esm.run/@thi.ng/webgl-shadertoy"></script>
Package sizes (brotli'd, pre-treeshake): ESM: 693 bytes
Note: @thi.ng/api is in most cases a type-only import (not used at runtime)
Three projects in this repo's /examples directory are using this package:
Screenshot | Description | Live demo | Source |
---|---|---|---|
Shader-AST meta-programming techniques for animated function plots | Demo | Source | |
Evolutionary shader generation using genetic programming | Demo | Source | |
Shadertoy-like WebGL setup | Demo | Source |
import {
$xy, add, distance, eq, float, FloatSym, fract,
int, min, mix, mul, neg, ret, sin, sym,
Vec2Sym, Vec2Term, vec3, Vec3Sym, vec4
} from "@thi.ng/shader-ast";
import { aspectCorrectedUV, fit1101 } from "@thi.ng/shader-ast-stdlib";
import { glCanvas } from "@thi.ng/webgl";
import { MainImageFn, shaderToy } from "@thi.ng/webgl-shadertoy";
const mainImage: MainImageFn = (gl, unis) => {
// predeclare local vars / symbols
let uv: Vec2Sym;
let mp: Vec2Sym;
let d1: FloatSym;
let d2: FloatSym;
let col: Vec3Sym;
// Inline function to create ring pattern with center at `p`
const rings = (p: Vec2Term, speed = 0.25, freq = 50) =>
sin(mul(add(distance(uv, p), fract(mul(unis.time, speed))), freq));
return [
// let's work in [-1..+1] range (based on vertical resolution)
(uv = sym(aspectCorrectedUV($xy(gl.gl_FragCoord), unis.resolution))),
(mp = sym(aspectCorrectedUV(unis.mouse, unis.resolution))),
// compute ring colors
(d1 = sym(rings(mp))),
(d2 = sym(rings(neg(mp)))),
// combine rings and multiply with target color based on
// mouse button state
(col = sym(
mul(
vec3(fit1101(min(d1, d2))),
mix(
vec3(1),
vec3(d1, 0, d2),
float(eq(unis.mouseButtons, int(1)))
)
)
)),
// return as vec4 (mandatory)
ret(vec4(col, 1))
];
};
// create WebGL canvas
const canvas = glCanvas({
width: window.innerWidth,
height: window.innerHeight,
parent: document.body,
version: 1
});
// init shader toy with canvas & shader fn
const toy = shaderToy({
canvas: canvas.canvas,
gl: canvas.gl,
main: mainImage
});
toy.start();
If this project contributes to an academic publication, please cite it as:
@misc{thing-webgl-shadertoy,
title = "@thi.ng/webgl-shadertoy",
author = "Karsten Schmidt",
note = "https://thi.ng/webgl-shadertoy",
year = 2019
}
© 2019 - 2024 Karsten Schmidt // Apache License 2.0