Skip to content

tessapower/sfx

Repository files navigation

sfx - Shader Playground

A water shader experiment running in the browser

A hot-reloadable shader playground built with Vite, React, TypeScript, Three.js, and lil-gui.

Features

  • Hot reload shaders when files change
  • Multiple shader programs with dropdown selection
  • Real-time compilation feedback
  • GUI controls via lil-gui
  • Auto-discovery of shader files

Setup

  1. Install dependencies:
npm install
  1. Start the dev server:
npm run dev
  1. Open your browser to http://localhost:5173

Creating Shaders

  1. Create a new directory in shaders/:
shaders/
  └── myshader/
      └── fragment.glsl
  1. Write your fragment shader using these uniforms:

    • u_time - Time in seconds (float)
    • u_resolution - Canvas resolution (vec2)
    • vUv - UV coordinates (vec2, varying)
  2. The shader will automatically appear in the dropdown!

Example Shader

uniform float u_time;
uniform vec2 u_resolution;
varying vec2 v_uv;

void main() {
    vec2 p = v_uv * 2.0 - 1.0;
    p.x *= u_resolution.x / u_resolution.y;
    
    float d = length(p);
    float c = sin(d * 10.0 - u_time * 2.0);
    
    vec3 col = vec3(c);
    gl_FragColor = vec4(col, 1.0);
}

Project Structure

sfx/
├── shaders/          # Shader programs (auto-discovered)
│   ├── plasma/
│   │   └── fragment.glsl
│   ├── circles/
│   │   └── fragment.glsl
│   └── gradient/
│       └── fragment.glsl
├── src/
│   ├── components/
│   │   └── ShaderCanvas.tsx
│   ├── shaders/
│   │   └── shared.vs.glsl
│   ├── utils/
│   │   ├── ShaderLoader.ts
│   │   └── AsciiArt.ts
│   ├── App.tsx
│   └── main.tsx
├── index.html
├── package.json
├── tsconfig.json
└── vite.config.ts

Error Handling

  • Compilation errors show a red ASCII art error message with details
  • Loading states display an animated ASCII loading indicator
  • Hot reload automatically applies when you save shader files

Tips

  • Use v_uv for UV coordinates (0-1 range)
  • Normalize coordinates with v_uv * 2.0 - 1.0 for centered effects
  • Account for aspect ratio: p.x *= u_resolution.x / u_resolution.y
  • Use u_time for animations
  • Check the browser console for detailed error messages

Building for Production

npm run build
npm run preview

Future Improvements

Currently I don't plan on making any future improvements to this project. It's a small tool I made for my own personal use to experiment with WebGL shaders. It's also a fun way to show off any shaders I have written, and doesn't rely on ShaderToy or some other online sandbox. You can run this completely offline on your own machine, and host it on your own website. If you also find this tool useful and have ideas on how to improve it, feel free to create an issue.