ether-shaders
Skill0 starsChanged 28 days agoMITView on GitHub
Premium shader and postprocessing stack for ether-engine WebGL. Documents the LDR-composer bloom + dither preset, the iridescent fresnel + cheap-noise vertex displacement material, the extruded-word text pipeline, and the engine-vs-site shader boundary. Use this — not ether-threejs — whenever the task is writing GLSL or tuning an existing shader, a ShaderMaterial, an iridescent fresnel material, vertex displacement, MSDF/extruded 3D text, or the bloom+dither composer (ether-threejs owns scene architecture; this owns the shader and material layer). Triggers on GLSL, fragment shader, vertex shader, custom material, dither, bloom, postprocessing, fresnel, iridescent, displacement, surface noise, extruded text, 3D type, premium material, raw GLSL import, sculpture material, ExtrudeGeometry, brand-as-form. Do NOT use when "bloom", "displacement", or "dither" appear outside a GLSL/WebGL material context, or when the existing engine postfx composer already covers the need — reference it, don't rebuild.
In this repository3 other files it gives its agents.
- ether-scrollSkill
- ether-threejsSkill
- studio-onboardSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 1 is distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 57
Default materials (MeshBasicMaterial, MeshStandardMaterial) on hero elements.
- Distinctive: line 77
Test against the hero composer: If your material needs HDR values, the LDR composer clips them — rework to 0..1 (preferred) or use the …
- Very specific: line 78
Run
premium-review: before reporting complete. - Very specific: line 82
Run the premium-review subagent on any shader work before reporting complete.
- Very specific: line 83
If the shader is scroll-bound, also invoke ether-scroll for the bridge pattern.
- Very specific: line 84
If creating a new dimensional-type treatment, cite the extrudedWord options you chose in the commit message — future grep will find the …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
ether-shaders
Technique reference for the shader + postprocessing + extruded-text stack in the ether engine. Invoke before writing any shader, postprocessing change, or text-as-form work on a site built on it.
When to use
Any of:
- Writing a new
ShaderMaterial, vertex shader, or fragment shader. - Modifying postprocessing (bloom, dither, color grading, new effects).
- Adding or tuning extruded text — hero treatments, chapter heads.
- Diagnosing a banding / glow / type-ghosting / displacement-blur issue.
Invoke alongside ether-threejs (the general slop checklist) — this skill specializes, the other generalizes.
Read first
- The
ether-threejsSKILL.md — the general "no AI-slop three.js" checklist applies first. recipes.mdin this directory — nine numbered recipes.- Your studio's taste doc, if the repo has one — what lands vs. what doesn't.
The engine / site boundary
- Engine owns (ether
src/):postfx/composer.ts—createComposer, the one composer shape: render → your effects → (ACES whenhdr) → dither, fused into a singleEffectPass.postfx/heroComposer.ts— three tunings of it:createHeroComposer(restrained LDR bloom for a dark scene with one bright accent),createNightComposer(hotter bloom for scenes whose light IS emissive geometry; exposes the optionalhdrflag),createLightComposer(dither only — bloom on a pale ground just lifts the ground).postfx/DitherEffect.ts— per-pixel hash grain applied through the sRGB transfer. Separately,shaders/dither.glslis a standalone 8×8 Bayer chunk for your own materials; the effect does not use it.primitives/ShaderQuad— backdrop plane with auto-wireduTime/uAspect.text/extrudedWord— opentype → SVGLoader → ExtrudeGeometry pipeline (type as form).text/msdf—msdfText, a troika-backed MSDF mesh (type as text), on its own entry so the optional peer stays optional.
- Your site owns (
src/shaders/<scene>/):- The hero material shaders — your identity. Site-specific until a second consumer needs them.
- Backdrop shaders (caustics, gradients, generative fields).
The engine is brand-free by construction: it ships wiring and takes the palette as uniforms, so the site injects its own colors. Don't promote site shaders to the engine without a generalization pass (uniform-driven palettes, no hardcoded brand-token vec3s).
Hard rules
- Follow the project's configured shader import convention —
vite-plugin-glsl,?raw(import frag from './x.frag.glsl?raw'), or inline strings. When adding a shader, use what the codebase already does; don't mix strategies without a reason. optimizeDeps.exclude: ['ether']is mandatory in yourastro.config.ts(or Vite config) for a git /file:install, which ships raw.ts. esbuild's dep-scan can't parse the engine's Vite-only?rawGLSL imports; excluding it routes those files through Vite's full plugin pipeline instead.- Never set
preserveSymlinks: truefor afile:layout — it pins the engine at its node_modules path, which Vite ignores for file-watching, so engine edits never hot-reload and it gets served as a stale cached external dep. Its one job (resolving the engine's barethree/postprocessingimports into the site's node_modules) is done correctly byresolve.dedupe: ['three', 'postprocessing', …]— set that instead. Both rules live together inastro.config.ts. - Three composer presets exist — pick one, don't mutate one into the other. All three are thin tunings over
createComposer; if none fits, write a fourth oncreateComposerrather than parameterising an existing one.createHeroComposertakesPresetOptionsand is LDR by design — it never passeshdr, so values clip at 1.0 deliberately as bloom containment. OnlycreateNightComposerre-exposeshdr(NightComposerOptions), which switches onHalfFloatTypebuffers + an ACESToneMappingEffectand makestoneMappingExposurelive.createLightComposeris dither-only. - Edge AA comes from the composer's
multisampling, never the contextantialiasflag. Post-processing renders into textures that bypass the canvas framebuffer, so context MSAA is visually dead the moment a composer runs (the quality profile setsantialias: falseand carriesmsaaSamplesinstead — wire viacreateHeroComposer(renderer, scene, camera, { multisampling: quality.msaaSamples })). - Dither runs on every tier. The quality profile ships
enablePostFX: trueandenableDither: trueon LOW, MID and HIGH alike — tiers differ only inmsaaSamples(HIGH 4 / MID 2 / LOW 0). It merges into the SAME fullscreen pass as bloom (a few ALU ops — effectively free) and kills the dark-gradient banding that reads as posterized color on mobile OLED. Never gate it on tier at a call site. - Bloom intensity
0.06is the hero-preset ceiling. Higher = glow-spam. RaiseluminanceThresholdto gate harder if you need more visible bloom. The night preset ships0.38by design — its own ceiling, not a license to raise the hero's. - Custom
ShaderMaterialonly on hero elements. NoMeshBasicMaterial/MeshStandardMaterialfor hero content. Seeether-threejs. - Brand tokens through uniforms. Pull colors from your site's constants module — the engine never names a color. If tokens are mirrored in CSS, update both when a color changes.
- Wire
uTimethrough the scene tick. Material uniforms updated fromtick()or via a wrapper'stickUniforms. Never via setInterval. - Add
precision highp float;at the top of fragment shaders explicitly — three.js prepends it by default, but stating it inline keeps the intent durable across pipeline changes.
Slop indicators (do not ship)
- Default materials (
MeshBasicMaterial,MeshStandardMaterial) on hero elements. - Bloom
intensity > 0.1on the hero preset, orluminanceThreshold < 0.5(the night preset ships 0.38 by design). - Hardcoded
vec3(...)colors in shaders. - Ambient particle fields with no narrative function (see
ether-threejs). - ShaderMaterial without
uTimewired through the engine's tick. dat.guileft in production builds.console.loginside shader hot paths.- ExtrudedWord with
curveSegments < 6on hero treatments. - Single-color iridescent rim (must be a dual-color mix by normal direction).
- Promoting a site shader to the engine without uniformising the color palette.
- Vertex displacement strong enough to blur bevels on letter-extrusion geometry.
Procedure for a new ShaderMaterial
- Confirm against the
ether-threejsslop checklist first — general rules apply before specifics. - Decide ownership — is the shader reusable across sites (engine) or brand-specific (site)? Default: site, until a second consumer exists.
- Place files —
src/shaders/<scene>/<name>.{vert,frag}.glsl. Import them by the project's existing convention. - Wire uniforms through your constants module — brand colors, displacement amplitudes, fresnel exponents.
- Tick uniforms from the scene's
tick()(or a wrapping class'stickUniforms). - Add
precision highp float;to fragment shaders. - Test against the hero composer. If your material needs HDR values, the LDR composer clips them — rework to 0..1 (preferred) or use the night preset.
- Run
premium-reviewbefore reporting complete.
After the skill
- Run the
premium-reviewsubagent on any shader work before reporting complete. - If the shader is scroll-bound, also invoke
ether-scrollfor the bridge pattern. - If creating a new dimensional-type treatment, cite the
extrudedWordoptions you chose in the commit message — future grep will find the lineage.
Files
SKILL.md— this file (the script).recipes.md— nine numbered technique recipes, each ending in a file + symbol citation index.evals/triggers.json— should/shouldn't-trigger regression set for the description.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

