diff options
Diffstat (limited to 'tools/shadertoy/README.md')
| -rw-r--r-- | tools/shadertoy/README.md | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/tools/shadertoy/README.md b/tools/shadertoy/README.md new file mode 100644 index 0000000..e734684 --- /dev/null +++ b/tools/shadertoy/README.md @@ -0,0 +1,191 @@ +# ShaderToy Conversion Guide + +Quick guide to convert ShaderToy shaders to demo effects. + +## Quick Start (Automated) + +```bash +# Save ShaderToy code to a file +cat > tunnel.txt << 'EOF' +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + vec2 uv = fragCoord / iResolution.xy; + vec3 col = 0.5 + 0.5 * cos(iTime + uv.xyx + vec3(0,2,4)); + fragColor = vec4(col, 1.0); +} +EOF + +# Generate effect files +./tools/shadertoy/convert_shadertoy.py tunnel.txt Tunnel + +# Follow printed instructions to integrate +``` + +## Files + +**Automated Script:** +- `convert_shadertoy.py` - Generates all files from ShaderToy code +- `example.txt` - Example ShaderToy shader for testing + +**Manual Templates:** +- `template.h` - Header boilerplate +- `template.cc` - Implementation boilerplate +- `template.wgsl` - Shader boilerplate with conversion notes + +## Manual Steps + +### 1. Copy Templates + +```bash +# Choose effect name (e.g., "tunnel", "plasma", "warp") +EFFECT_NAME="myeffect" + +cp tools/shadertoy/template.h src/gpu/effects/${EFFECT_NAME}_effect.h +cp tools/shadertoy/template.cc src/gpu/effects/${EFFECT_NAME}_effect.cc +cp tools/shadertoy/template.wgsl workspaces/main/shaders/${EFFECT_NAME}.wgsl +``` + +### 2. Rename Class + +In both `.h` and `.cc`: +- `ShaderToyEffect` → `MyEffectEffect` +- `SHADERTOY_EFFECT_H_` → `MYEFFECT_EFFECT_H_` +- `shadertoy_effect.h` → `myeffect_effect.h` + +### 3. Convert Shader + +In `.wgsl`, paste ShaderToy `mainImage()` into `fs_main()`: + +**ShaderToy:** +```glsl +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + vec2 uv = fragCoord / iResolution.xy; + fragColor = vec4(uv, 0.5, 1.0); +} +``` + +**WGSL:** +```wgsl +@fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { + let uv = p.xy / uniforms.resolution; + return vec4<f32>(uv, 0.5, 1.0); +} +``` + +### 4. Update Asset Name + +In `.cc`, update `AssetId::ASSET_SHADERTOY_SHADER` to match your shader filename: +```cpp +AssetId::ASSET_MYEFFECT_SHADER +``` + +### 5. Add to Assets + +In `workspaces/main/assets.txt`: +``` +shaders/myeffect.wgsl +``` + +### 6. Register Effect + +In `src/gpu/demo_effects.h`: +```cpp +#include "gpu/effects/myeffect_effect.h" +``` + +In `workspaces/main/timeline.seq`: +``` +SEQUENCE 0.0 0 + EFFECT MyEffectEffect 0.0 10.0 0 +``` + +### 7. Update Tests + +In `tests/test_demo_effects.cc`: +- Add `"MyEffectEffect"` to test list +- Increment `EXPECTED_*_COUNT` + +### 8. Build & Test + +```bash +cmake --build build -j4 +./build/demo64k + +# Run tests +cmake -S . -B build -DDEMO_BUILD_TESTS=ON +cmake --build build -j4 +cd build && ctest +``` + +## Example Conversion + +**Input ShaderToy:** +```glsl +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + vec2 uv = fragCoord / iResolution.xy; + vec3 col = 0.5 + 0.5 * cos(iTime + uv.xyx + vec3(0,2,4)); + fragColor = vec4(col, 1.0); +} +``` + +**Generated WGSL (after script + manual fixes):** +```wgsl +@fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { + let uv = p.xy / uniforms.resolution; + let col = vec3<f32>(0.5) + 0.5 * cos(uniforms.time + uv.xyx + vec3<f32>(0.0, 2.0, 4.0)); + return vec4<f32>(col, 1.0); +} +``` + +## Common Conversions + +| ShaderToy | WGSL | +|-----------|------| +| `iResolution.xy` | `uniforms.resolution` | +| `iTime` | `uniforms.time` | +| `fragCoord` | `p.xy` | +| `float` | `f32` | +| `vec2` | `vec2<f32>` | +| `mod(x, y)` | `x % y` | +| `texture(iChannel0, uv)` | `textureSample(txt, smplr, uv)` | +| `fragColor = ...` | `return ...` | +| `vec2 p = ...` | `let p = vec2<f32>(...)` or `var p: vec2<f32> = ...` | + +## Custom Parameters + +For tunable values: + +**C++ (`.h`):** +```cpp +struct MyEffectParams { + float speed; + float scale; + float _pad[2]; +}; +static_assert(sizeof(MyEffectParams) == 16, "..."); +``` + +**WGSL:** +```wgsl +struct MyEffectParams { + speed: f32, + scale: f32, + _pad0: f32, + _pad1: f32, +} +@group(0) @binding(3) var<uniform> params: MyEffectParams; +``` + +## Available Uniforms + +Always available in `uniforms: CommonUniforms`: +- `resolution: vec2<f32>` - Screen resolution +- `aspect_ratio: f32` - Width/height +- `time: f32` - Demo time (seconds) +- `beat: f32` - Music beat sync (0-1) +- `audio_intensity: f32` - Audio reactivity + +## Next Steps + +- See `doc/CONTRIBUTING.md` for commit policy +- See `doc/SEQUENCE.md` for timeline syntax +- See existing effects in `src/gpu/effects/` for examples |
