From bc1beb58ba259263eb98d43d2aa742307764591c Mon Sep 17 00:00:00 2001 From: skal Date: Sat, 28 Feb 2026 09:25:35 +0100 Subject: fix(tools/shadertoy): sync templates and script to current codebase conventions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - template.h/cc: new Effect constructor/render signatures, RAII wrappers, HEADLESS_RETURN_IF_NULL, #pragma once - template.wgsl: sequence_uniforms + render/fullscreen_uv_vs includes, UniformsSequenceParams at binding 2, VertexOutput in fs_main - convert_shadertoy.py: paths src/effects/ + src/shaders/, new Effect pattern (create_post_process_pipeline, pp_update_bind_group), correct field names (beat_time/beat_phase), updated next-steps instructions - README.md: streamlined to quick-ref; accurate GLSL→WGSL table and uniforms Co-Authored-By: Claude Sonnet 4.6 --- tools/shadertoy/README.md | 211 +++++++++++----------------------------------- 1 file changed, 48 insertions(+), 163 deletions(-) (limited to 'tools/shadertoy/README.md') diff --git a/tools/shadertoy/README.md b/tools/shadertoy/README.md index 1ce42e8..878b53c 100644 --- a/tools/shadertoy/README.md +++ b/tools/shadertoy/README.md @@ -1,137 +1,48 @@ # ShaderToy Conversion Guide -Quick guide to convert ShaderToy shaders to demo effects. - -**For complete workflow:** See `doc/EFFECT_WORKFLOW.md` for full integration checklist. +Convert ShaderToy shaders to demo effects. See `doc/EFFECT_WORKFLOW.md` for full integration checklist. ## 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 +# Generate effect files from ShaderToy code ./tools/shadertoy/convert_shadertoy.py tunnel.txt Tunnel +./tools/shadertoy/convert_shadertoy.py blur.txt Blur --post-process +./tools/shadertoy/convert_shadertoy.py tunnel.txt Tunnel --shader-only # regen shader only -# Regenerate only shader (if .h/.cc already exist) -./tools/shadertoy/convert_shadertoy.py tunnel.txt Tunnel --shader-only - -# Follow printed instructions to integrate +# Follow printed instructions to integrate (assets.txt, shaders.h, CMakeLists.txt, timeline.seq) ``` -## Files - -**Automated Script:** -- `convert_shadertoy.py` - Generates all files from ShaderToy code -- `example.txt` - Example ShaderToy shader for testing +Generates: `src/effects/_effect.{h,cc}` + `src/shaders/.wgsl` -**Manual Templates:** -- `template.h` - Header boilerplate -- `template.cc` - Implementation boilerplate -- `template.wgsl` - Shader boilerplate with conversion notes - -## Manual Steps - -### 1. Copy Templates +## Manual Templates ```bash -# Choose effect name (e.g., "tunnel", "plasma", "warp") -EFFECT_NAME="myeffect" - -cp tools/shadertoy/template.h src/effects/${EFFECT_NAME}_effect.h -cp tools/shadertoy/template.cc src/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) -> @location(0) vec4 { - let uv = p.xy / uniforms.resolution; - return vec4(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 +cp tools/shadertoy/template.h src/effects/myeffect_effect.h +cp tools/shadertoy/template.cc src/effects/myeffect_effect.cc +cp tools/shadertoy/template.wgsl src/shaders/myeffect.wgsl ``` -### 6. Register Effect +Then rename `ShaderToyEffect` → `MyeffectEffect` in `.h` and `.cc`, paste shader code into `fs_main()`, and follow `doc/EFFECT_WORKFLOW.md`. -In `src/gpu/demo_effects.h`: -```cpp -#include "effects/myeffect_effect.h" -``` - -In `workspaces/main/timeline.seq`: -``` -SEQUENCE 0.0 0 - EFFECT + MyEffectEffect 0.0 10.0 -``` - -### 7. Update CMakeLists.txt - -Add effect source to `CMakeLists.txt` GPU_SOURCES (both headless and normal mode sections): -```cmake -src/effects/myeffect_effect.cc -``` +## GLSL → WGSL Conversions -### 8. Update Tests - -In `src/tests/gpu/test_demo_effects.cc`: -- Add to `post_process_effects` list (lines 80-93) if it's a post-process effect -- OR add to `scene_effects` list (lines 125-137) if it's a scene effect -- Example: `{"MyEffectEffect", std::make_shared(fixture.ctx())},` - -### 9. 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 -``` +| ShaderToy | WGSL | +|-----------|------| +| `iResolution.xy` | `uniforms.resolution` | +| `iTime` | `uniforms.time` | +| `fragCoord` | `in.position.xy` (pixel) or `in.uv * uniforms.resolution` | +| `float` | `f32` | +| `vec2/vec3/vec4` | `vec2f/vec3f/vec4f` | +| `mat2/mat3/mat4` | `mat2x2f/mat3x3f/mat4x4f` | +| `mod(x, y)` | `x % y` | +| `texture(iChannel0, uv)` | `textureSample(txt, smplr, uv)` | +| `fragColor = col;` | `return col;` | +| `float foo(vec2 p)` | `fn foo(p: vec2f) -> f32` | -## Example Conversion +## Example -**Input ShaderToy:** +**Input:** ```glsl void mainImage(out vec4 fragColor, in vec2 fragCoord) { vec2 uv = fragCoord / iResolution.xy; @@ -140,65 +51,39 @@ void mainImage(out vec4 fragColor, in vec2 fragCoord) { } ``` -**Generated WGSL (after script + manual fixes):** +**Output WGSL:** ```wgsl -@fragment fn fs_main(@builtin(position) p: vec4) -> @location(0) vec4 { - let uv = p.xy / uniforms.resolution; - let col = vec3(0.5) + 0.5 * cos(uniforms.time + uv.xyx + vec3(0.0, 2.0, 4.0)); - return vec4(col, 1.0); +@fragment fn fs_main(in: VertexOutput) -> @location(0) vec4f { + let uv = in.uv; + let col = vec3f(0.5) + 0.5 * cos(uniforms.time + uv.xyx + vec3f(0.0, 2.0, 4.0)); + return vec4f(col, 1.0); } ``` -## Common Conversions +## Available Uniforms (`UniformsSequenceParams`, binding 2) -| ShaderToy | WGSL | -|-----------|------| -| `iResolution.xy` | `uniforms.resolution` | -| `iTime` | `uniforms.time` | -| `fragCoord` | `p.xy` | -| `float` | `f32` | -| `vec2` | `vec2` | -| `mod(x, y)` | `x % y` | -| `texture(iChannel0, uv)` | `textureSample(txt, smplr, uv)` | -| `fragColor = ...` | `return ...` | -| `vec2 p = ...` | `let p = vec2(...)` or `var p: vec2 = ...` | - -## Custom Parameters +| Field | Type | Description | +|-------|------|-------------| +| `resolution` | `vec2f` | Screen dimensions | +| `aspect_ratio` | `f32` | Width/height | +| `time` | `f32` | Physical time (seconds) | +| `beat_time` | `f32` | Musical beats (absolute) | +| `beat_phase` | `f32` | Fractional beat [0..1] | +| `audio_intensity` | `f32` | Audio peak | -For tunable values: +## Custom Parameters (optional, binding 3) -**C++ (`.h`):** +**C++** (must be 16-byte aligned): ```cpp -struct MyEffectParams { - float speed; - float scale; - float _pad[2]; -}; -static_assert(sizeof(MyEffectParams) == 16, "..."); +struct MyParams { float speed; float scale; float _pad[2]; }; +static_assert(sizeof(MyParams) == 16, "..."); +UniformBuffer params_; // add to .h ``` **WGSL:** ```wgsl -struct MyEffectParams { - speed: f32, - scale: f32, - _pad0: f32, - _pad1: f32, -} -@group(0) @binding(3) var params: MyEffectParams; +struct MyParams { speed: f32, scale: f32, _pad0: f32, _pad1: f32, } +@group(0) @binding(3) var params: MyParams; ``` -## Available Uniforms - -Always available in `uniforms: CommonUniforms`: -- `resolution: vec2` - 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/effects/` for examples +Also pass `params_.get()` instead of `{nullptr, 0}` in `pp_update_bind_group()`. -- cgit v1.2.3