npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zylem/shaders

v0.8.8

Published

WebGPU-compatible TSL shaders and postprocessing effects for the Zylem game framework.

Readme

@zylem/shaders

WebGPU-compatible TSL shaders and postprocessing effects for the Zylem game framework.

Every shader is a ZylemTSLShader ({ colorNode, positionNode?, transparent? }) — structurally identical to the type in @zylem/game-lib/graphics — so it can be passed directly to game-lib:

import { createWaterSurface, createMagicalLandscape } from '@zylem/shaders';

// As an entity material
const water = createWaterSurface({ waveSpeed: 0.8 });
// ... material: { shader: water }

// As a stage background
const landscape = createMagicalLandscape({ speed: 3 });
// ... createStage({ backgroundShader: landscape }, camera)

// Runtime tweaks via uniforms
water.uniforms.waveStrength.value = 2.0;
landscape.uniforms.color1.value.set('#ff8800');

Shaders

| Factory | Use | Source / inspiration | | --- | --- | --- | | createMagicalLandscape(options) | Fullscreen background | Magical Landscape by Sabo Sugi | | createStarryNight(options) | Skybox background | Procedural: star layers, Milky Way band, nebula tint | | createAlienSky(options) | Skybox background | Zylem examples arena Mars skybox (stars, galaxy, moon, mountains) | | createPlanetSurface(options) | Mesh surface (UV sphere) | Zylem examples planet demo | | createPlanetRing(options) | Transparent disk/annulus | Zylem examples planet demo | | createEnergyShield(options) | Transparent shell (sphere) | Halo-style shield (fresnel rim, hex cells, recharge wave, impact flare/ripple); grew out of the 3d-asteroids ship shield | | createDissolve(options) | Mesh surface (any) | r3f dissolve-effect sandbox (CSM + gl-noise) | | createFoliage(options) | Collapsed-quad leaf cluster | Stylized bush sandbox — pair with createFoliageClusterGeometry | | createHolographic(options) | Transparent mesh surface | ektogamat/threejs-vanilla-holographic-material by Anderson Mancini, plus an optional vertex/color glitch (glitchIntensity) | | createArcadeDissolve(options) | Subdivided mesh surface | Robotron 2084 enemy-destruction effect (X/Y band shredding, arcade color flash) | | createWaterSurface(options) | Mesh surface (XZ water plane) | jeantimex/threejs-water surface shaders | | createLava(options) | Mesh surface (UV-mapped) | three.js webgl_shader_lava by TheGameMaker | | createShadertoyWaterNoise(options) | Mesh surface | Shadertoy Mt2SzR | | createShadertoyFire(options) | Mesh surface (transparent) | Shadertoy 3tcBzH | | createStageTransition(options) | Stage transition (game.nextStage({ transition })) | three.js webgpu_postprocessing_transition |

All factories accept an options object and return the shader with a uniforms bag for runtime tweaking.

createStageTransition returns a ZylemTransitionShader (not a ZylemTSLShader): pass it as game.nextStage({ transition: { shader: createStageTransition({ pattern: 'noise' }) } }). Patterns: fade, wipe, radial, noise, cells; pass a grayscale texture mix map to drive the wipe instead (dark texels transition first).

createWaterSurface also returns a positionNode that displaces vertices by the wave heightfield, so apply it to a subdivided plane (e.g. createPlane({ subdivisions: 160, ... })). Set waveAmplitude: 0 for a flat, normal-mapped-only surface, and pass envMap (a cube texture) to reflect an environment instead of the built-in horizon/zenith sky gradient.

Shadertoy transpiler

Turn raw Shadertoy GLSL into a consumable shader at runtime (wraps the three.js addons Transpiler + ShaderToyDecoder + TSLEncoder):

import { parseShadertoy } from '@zylem/shaders';

const shader = parseShadertoy(`
  void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord.xy / iResolution.xy;
    fragColor = vec4(uv, 0.5 + 0.5 * sin(iTime), 1.0);
  }
`);

Supported inputs: iTime, iResolution, fragCoord. Channels, mouse, and multipass buffers are not supported.

Postprocessing

import { createAfterimageEffect } from '@zylem/shaders/postprocessing';

const trails = createAfterimageEffect({ damp: 0.9 });
// stage config: postProcessingEffects: [trails.effect]
trails.uniforms.damp.value = 0.97;

| Factory | Effect | Source / inspiration | | --- | --- | --- | | createAfterimageEffect(options) | Motion trails | three.js AfterImageNode (TSL port of AfterimageShader.js) | | createVhsGrainEffect(options) | VHS tape: grain, tracking band, color fringe, scanlines | Composed from three.js CRT helpers + FilmNode-style grain | | createPixelationEffect(options) | Pixel-art with normal/depth edge outlines | three.js webgpu_postprocessing_pixel by Kody King | | createRetroEffect(options) | PS1/CRT: vertex snapping, affine textures, dither, curvature | three.js webgpu_postprocessing_retro |

Effects implement ZylemPostEffect(inputNode, { scenePass, scene, camera }) => outputNode — and plug into game-lib's render pipeline via the stage postProcessingEffects option or rendererManager.setPostProcessingEffects().

createPixelationEffect and createRetroEffect are pass-replacing effects: they render their own scene pass (for extra channels or altered rasterization) rather than transforming the incoming node, so place them first in the postProcessingEffects array.

Install

pnpm add @zylem/shaders three

three is a peer dependency: the library and @zylem/game-lib must share a single Three.js copy, because TSL nodes are not interchangeable across copies.

Repository

This repo is the library itself — src/ builds to the published dist/ — plus a nested showcase/ Solid/Vite app that exercises every shader on top of @zylem/game-lib. The showcase resolves @zylem/shaders to source, so shader edits hot-reload without rebuilding.

Requires Node >= 22.12.0, pnpm >= 10.32.1, and a WebGPU-capable browser for the showcase.

pnpm install

pnpm build          # bundle the library to dist/
pnpm dev            # rebuild the library on change
pnpm typecheck
pnpm lint

pnpm showcase:dev   # showcase on http://localhost:3332
pnpm showcase:build

The showcase deploys as a Render static site (see render.yaml); the library publishes to npm from .github/workflows/publish.yml on a v* tag.