Playground
Write a TypeShade TypeScript file, compile it in your browser, and inspect the generated WGSL and diagnostics.
Start from an example
Each tile is one of the .shade.ts files in the compiler repository. Open one, change it, add files beside it, and bind your own images to its textures.
Blank file
A fragment shader that reads time, resolution and mouse.
Stages and IO structs
-
Hello triangle The smallest complete TypeShade program. -
Hello varyings The triangle again, now carrying a uvvarying from the vertex stage into the fragment stage through a sharedVsOutclass. - No preview Hello vertex attributes Vertex input from a buffer rather than from
vertex_index. -
A vertex that returns only the position The smallest render pair. -
Twin IO structs Two IO structs with identical fields, a vertex output and a fragment input, with object literals in all three positions that declare which one they build. -
An integer varying, and the interpolation it has no choice about Entry IO as WGSL declares it. - No preview User clip planes Four user clip planes through
@builtin("clip_distances"), the vertex output the rasterizer reads before it rasterizes.
Resources
- No preview Hello uniform A bare
declare const scale: uniform<f32>. - No preview Hello uniform block The uniform that does have a GLSL ES 3.00 form.
- No preview Hello camera uniform A
Cameraclass ofmat4+vec3behinduniform<Camera>, read by a plain helper function. - No preview Texture, sampler and overrides A fullscreen triangle sampling a
texture_2d<f32>through asampler, tinted by twooverride<f32>specialization constants. - No preview Runtime array length The bounds guard every kernel over a runtime-sized storage array needs.
- No preview A storage texture An image a compute entry writes by texel coordinate, with no sampler and no filtering.
- No preview A shadow map, read by comparison A depth texture read through a
sampler_comparisonwithtextureSampleCompareandtextureSampleCompareLevel, on a plain 2D shadow map and on a cascade array. - No preview Cube and 3D textures, bias and gradients An environment map as a
texture_cube<f32>looked up by direction, a colour-grading table as atexture_3d<f32>the shaded colour indexes,textureSampleBiasandtextureSampleGrad, and a point light’s shadow as atexture_depth_cubecompared by the direction from the light. - No preview The WGSL-only textures A colour ramp as a
texture_1d<f32>, two environment maps as atexture_cube_array<f32>picked by layer, a hand-written percentage-closer filter fromtextureGatherCompare, atextureGatherof one channel from four texels, and a point light’s shadow as atexture_depth_cube_array. - No preview A multisampled texture, resolved by hand An MSAA render target as a
texture_multisampled_2d<f32>read one sample at a time withtextureLoad(t, coords, sampleIndex)and averaged overtextureNumSamples, and its depth attachment as atexture_depth_multisampled_2d. - No preview A uniform holding a list A
uniformholdingarray<f32, 4>. - No preview A sample under a branch, and the directive that allows it WGSL requires
textureSampleto be called from uniform control flow.
Values and control flow
-
Module constants A module-scope constant of every scalar type the compiler allows. -
Module vector and array constants A fullscreen triangle banded by a module-scope array<vec4, 3>palette and anarray<f32, 3>of stops, with avec3constant built from an earlier scalar one. -
Array literals A fullscreen triangle whose corners come from two array<f32, 3>lists and whose colour comes from anarray<vec3, 3>of stops weighted by anarray<i32, 3>. -
Converting constructors A fullscreen triangle whose corner comes from vec2(vec2u(...))and whose colour comes from anf32→u32→f32round trip. - No preview Matrices beyond mat4 Every
matCxRis a type. - No preview Emulated doubles The
f64surface as source. -
Bitfield bands A fullscreen triangle whose colour is chosen by a switchover a band index built with&=,|=,<<=,>>=and^=, withlet x: f32declared before it is assigned and the varyings returned as{ pos, uv }shorthand. -
Block scope Two sequential loops over i, apin a loop body beside apin anifarm, and an innerpthat shadows the outer one. -
A conditional on a struct and on an array Two arms that are structs, and two that are fixed-length arrays, chosen at run time. -
Cutout (source language) discardin a helper the fragment entry calls, withfwidthsoftening the rim andsaturate,exp2and**shaping the falloff. -
Default parameter values Three helpers with default parameters, each called with a different argument omitted. - No preview Builtin breadth
reflect,refractandfaceForwardlight a bump,transposeanddeterminantread the host matrix, and the bit builtins (firstLeadingBit,reverseBits,countOneBits,extractBits,insertBits) band the screen, withfwidthCoarsemarking where a band starts. -
Boolean vectors A comparison of two vectors is a vector of bools. - No preview Integer abs and dot The two builtins the registry called portable and are not.
-
Packing, bitcast and the constructors The portable builtins WGSL has that this surface lacked. - No preview Packed 4x8 integer builtins The eight builtins that read a
u32as four bytes or write four back. -
Local functions that read and write the variables around them ringreadspandwidthfrom the fragment entry and adds to itsglow, as a TypeScript closure does. -
Functions that take a function coverandaround4take a distance field as a function,f: Field, and are compiled once for each function a call hands them, as a generic function is once per set of type arguments (Rule 8.18). -
Return types the body says No function here writes a return type, and each returns what its body does, as TypeScript infers it (Rule 8.19). -
An array's methods Three lights in an array<Light, 3>, lit with the methods a TypeScript author reaches for first (Rule 8.18, surface §63). - No preview Loops over data The three loops a program over data writes, through Tint and a real WebGL2 context.
- No preview Path tracer A small path tracer as ordinary TypeScript.
Classes and generics
-
Class methods A class Raywith a constructor, a method and a static function, and aclass Spherewhosehit(ray)method returns the distance along the ray. -
A method that changes its object A class Bodywhosestep,turnandadvanceassign tothis, so each takes its object by reference. - No preview Methods that change their object A
class Particlewhosestep,bounceandtickassign tothis, called on a storage element. -
Inheritance An abstract class Shapewith a concrete method and an abstract one, two classes that extend it, and one that extends a subclass and callssuper. -
The mixin pattern A function Tinted(Base)whose body is onereturn class extends Base { ... }, applied to two different geometry classes. -
Generics by monomorphisation Three generic helpers, each compiled once per set of argument types the file calls it with. -
A generic class by monomorphisation A class Slot<T>used at f32 and at vec3, so the module carriesSlot_f32andSlot_vec3as separate structs, each with its own constructor and its own copy of every method. -
A tuple and a branded alias A tuple is a list of a length the type fixes, which is what array<T, N>is, so[f32, f32]isarray<f32, 2>. -
Getters, setters, private names and parameter properties A class Ringwritten the way TypeScript classes are. -
Class-based Capsule Corp. spaceship on Namek A class-based conversion of a Dragon Ball Z Capsule Corp. -
A method that changes its object and returns a value A class Rngwhosenext()advances the generator's state and returns the draw. -
A builder chain, super on accessors, and statics a subclass inherits a.at(p).tinted(c)runs each call ona, in order, because a method whose everyreturnisreturn thishands back its own object, andnew Disc().at(p).sized(r)holds whatnewbuilt in a temporary (Rule 8.10). -
Objects inside objects, a const that holds one, a field that holds a function, and an interface as a contract ring.advance(dt)moves the ring by callingstepon theMoverit holds, soadvancechanges its own object and takes it by reference, whichever classstepbelongs to (Rule 8.10). - No preview Class-based 3D SDF ray tracer A 3D signed-distance-field renderer built with an abstract SdfShape base class and concrete Sphere, Box, Torus and Plane subclasses.
Imports
Several passes
Module state and compute
-
Per-invocation state A plain top-level let seed: u32is WGSL'svar<private>, one copy per invocation that every function of the invocation shares. - No preview Workgroup scratch memory
let tile: workgroup<array<f32, 64>>is WGSL'svar<workgroup>, one copy per workgroup its invocations share, here as scratch each invocation owns a slot of, beside a workgroup array of atomics and a per-invocation counter. - No preview Workgroup reduction 64 invocations sum 64 values into one through workgroup memory, with
workgroupBarrier()ordering the rounds. - No preview Atomic histogram Many invocations count into one bin at once with
atomicAdd(bins[bin], 1), one indivisible step each; a storage struct field and a barestorage<atomic<u32>>binding show the other two shapes of location, and the value an atomic returns is what it held before. - No preview Console from the GPU
console.log("i =", gid.x, p)inside a compute kernel. - No preview Compare-exchange, uniform load, texture barrier The three synchronisation builtins WGSL has and this surface lacked.
- No preview Compute reduction (source twin)
compute-reduction.tswritten in the source language. - No preview Two-dimensional workgroup
@compute([8, 8])is WGSL's@workgroup_size(8, 8).
Loops as kernels
- No preview A loop that runs as a kernel The roadmap's terrain.
- No preview Reductions in a loop A sum, a mean and a variance, and a histogram, each a loop over an array.
- No preview A loop over an array of structs The particle step as a loop over
array<Particle>. - No preview Loops that run on the CPU One loop for each rule of the independence proof (R1 to R6) that the proof refuses.
Source twins
-
Hillshade (source twin) hillshade.tswritten in the source language. -
Plasma (source twin) shadertoy-plasma.tswritten in the source language. -
Julia set (source twin) julia.tswritten in the source language. -
Mandelbrot set (source twin) mandelbrot.tswritten in the source language. -
Domain warping (source twin) domain-warp.tswritten in the source language. -
Tunnel (source twin) tunnel.tswritten in the source language. -
Ocean horizon (source twin) ocean.tswritten in the source language. -
Starfield (source twin) starfield.tswritten in the source language. -
Kaleidoscope (source twin) kaleidoscope.tswritten in the source language. -
Gradient pass (source twin) gradient-pass.tswritten in the source language instead of built withfn()/module(). -
Voronoi (source twin) voronoi.tswritten in the source language, and the gate for issue #40. -
fp64 deep zoom (source twin) fp64-deep-zoom.tswritten in the source language. - No preview fp64 checker plane (source twin)
fp64-checker-plane.tswritten in the source language. - No preview fp64 hyperbolic navigation (source twin)
fp64-loran.tswritten in the source language. - No preview fp64 relative-to-center (source twin)
fp64-rtc.tswritten in the source language. - No preview fp64 Julia set (source twin)
fp64-julia.tswritten in the source language. - No preview fp64 Burning Ship (source twin)
fp64-burning-ship.tswritten in the source language. - No preview fp64 Newton fractal (source twin)
fp64-newton.tswritten in the source language. - No preview fp64 distance estimate (source twin)
fp64-mandelbrot-de.tswritten in the source language. -
fp64 long-uptime clock (source twin) fp64-clock.tswritten in the source language. -
fp64 catastrophic cancellation (source twin) fp64-cancellation.tswritten in the source language. -
fp64 sine sweep (source twin) fp64-sine-sweep.tswritten in the source language.
If VS Code did not open, the TypeShade extension may be missing. How to install it.
DiagnosticsReady to compile
Compile a module with a vertex entry and a fragment entry to see it drawn.
Run the fragment entry once per pixel, with no GPU.
Call console.log in a shader to see its lines here. A compute module logs every invocation. In a module that draws, click a pixel of the canvas, or record the whole frame on WebGPU.