Show HN: GSS – Write 3D scenes in CSS, compiled to a raymarching shader
gss-lang.dev
You declare shapes in an @scene block, style them with selectors, and the compiler turns the whole stylesheet into one fragment shader: signed distance fields, It was implemented using WebGL2, or through WebGPU (using WGSL) with a fallback to WebGL2. Three.js was not used, nor was it. meshes, no UVs. ``` @scene { torus#ring; sphere#ball; } #ball { color: #ff5a36; radius: .55; material: jelly(.6); } animation: float 2s ease-in-out alternate; } ```
What carries over from CSS, with the same behavior: specificity and the cascade, Important: nesting with &, combinators, and :hover/:active with transition, @keyframes and every easing (cubic-bezier, linear(), steps), calc()/clamp()/trig, custom properties and @property, oklch()/color-mix(), gradients, @media (live), Animations driven by scrolling, with offset-path. Since CSS or SVG already have such a concept, GSS copies its syntax instead of inventing one (noise() is modeled on The turbulence is processed by means of displace() on the feDisplacementMap, and the prism or lathe takes a path.
How it works: the compiler (TypeScript, runs in the browser or at build time via a Vite plugin) resolves the cascade per object, then emits an SDF per shape Put them together. The animations are assessed in the shader, not in JavaScript. Objects are arranged in space, with those far away being omitted on a per-ray basis. A scene that doesn't move doesn't redraw.
How to use it: include a <gss-scene src="x.gss"> tag from a CDN and mount(canvas, source) from npm, or precompile with Vite (the runtime is ~15 KB gzipped; the compiler About 110 KB when you compile it onto the page).
The latest version is 0.0.5 and SDFs do not support mesh or glTF imports. Raymarching is expensive on weak integrated GPUs (without a GPU, a scene waits for a click Rather than freezing the page) the scene obscures the page behind it.
Playground: https://www.gss-lang.dev/playground Docs: https://www.gss-lang.dev/docs Code (Apache-2.0): https://github.com/LukyVj/GSS
I'd love feedback on the language design: where the CSS analogy holds, and The point at which it breaks or is misleading.