diff options
| -rw-r--r-- | PROJECT_CONTEXT.md | 2 | ||||
| -rw-r--r-- | common/shaders/math/color.wgsl | 27 | ||||
| -rw-r--r-- | common/shaders/math/utils.wgsl | 14 | ||||
| -rw-r--r-- | common/shaders/render/fullscreen_vs.wgsl | 10 | ||||
| -rw-r--r-- | common/shaders/render/raymarching.wgsl | 59 | ||||
| -rw-r--r-- | common/shaders/sdf_primitives.wgsl | 5 | ||||
| -rw-r--r-- | src/gpu/post_process_helper.cc | 4 | ||||
| -rw-r--r-- | src/gpu/shaders.cc | 5 | ||||
| -rw-r--r-- | src/tests/gpu/test_shader_assets.cc | 9 | ||||
| -rw-r--r-- | workspaces/main/assets.txt | 4 | ||||
| -rw-r--r-- | workspaces/main/shaders/chroma_aberration.wgsl | 9 | ||||
| -rw-r--r-- | workspaces/main/shaders/distort.wgsl | 9 | ||||
| -rw-r--r-- | workspaces/main/shaders/scene1.wgsl | 116 | ||||
| -rw-r--r-- | workspaces/main/shaders/solarize.wgsl | 9 | ||||
| -rw-r--r-- | workspaces/main/shaders/vignette.wgsl | 10 | ||||
| -rw-r--r-- | workspaces/test/assets.txt | 4 | ||||
| -rw-r--r-- | workspaces/test/shaders/chroma_aberration.wgsl | 9 | ||||
| -rw-r--r-- | workspaces/test/shaders/distort.wgsl | 9 | ||||
| -rw-r--r-- | workspaces/test/shaders/solarize.wgsl | 9 | ||||
| -rw-r--r-- | workspaces/test/shaders/vignette.wgsl | 10 |
20 files changed, 154 insertions, 179 deletions
diff --git a/PROJECT_CONTEXT.md b/PROJECT_CONTEXT.md index 02c51e4..63e6f8a 100644 --- a/PROJECT_CONTEXT.md +++ b/PROJECT_CONTEXT.md @@ -34,7 +34,7 @@ - **Timing System:** **Beat-based timelines** for musical synchronization. Sequences defined in beats, converted to seconds at runtime. Effects receive both physical time (constant) and beat time (musical). Variable tempo affects audio only. See `doc/BEAT_TIMING.md`. - **Workspace system:** Multi-workspace support. Easy switching with `-DDEMO_WORKSPACE=<name>`. Organized structure: `music/`, `weights/`, `obj/`, `shaders/`. Shared common shaders in `common/shaders/`. See `doc/WORKSPACE_SYSTEM.md`. - **Audio:** Sample-accurate sync. Zero heap allocations per frame. Variable tempo. Comprehensive tests. -- **Shaders:** Parameterized effects (UniformHelper, .seq syntax). Beat-synchronized animation support (`beat_time`, `beat_phase`). Modular WGSL composition with ShaderComposer. 20 shared common shaders (math, render, compute). +- **Shaders:** Parameterized effects (UniformHelper, .seq syntax). Beat-synchronized animation support (`beat_time`, `beat_phase`). Modular WGSL composition with ShaderComposer. 24 shared common shaders (math, render, compute). - **3D:** Hybrid SDF/rasterization with BVH. Binary scene loader. Blender pipeline. - **Effects:** CNN post-processing: CNNEffect (v1) and CNNv2Effect operational. CNN v2: sigmoid activation, storage buffer weights (~3.2 KB), 7D static features, dynamic layers. Training stable, convergence validated. - **Tools:** CNN test tool operational. Texture readback utility functional. Timeline editor (web-based, beat-aligned, audio playback). diff --git a/common/shaders/math/color.wgsl b/common/shaders/math/color.wgsl new file mode 100644 index 0000000..b63c915 --- /dev/null +++ b/common/shaders/math/color.wgsl @@ -0,0 +1,27 @@ +// Common color space and tone mapping functions. + +// sRGB to Linear approximation +// Note: Assumes input is in sRGB color space. +fn sRGB(t: vec3<f32>) -> vec3<f32> { + return mix(1.055 * pow(t, vec3<f32>(1.0/2.4)) - 0.055, 12.92 * t, step(t, vec3<f32>(0.0031308))); +} + +// ACES Filmic Tone Mapping (Approximate) +// A common tone mapping algorithm used in games and film. +fn aces_approx(v_in: vec3<f32>) -> vec3<f32> { + var v = max(v_in, vec3<f32>(0.0)); + v *= 0.6; + let a = 2.51; + let b = 0.03; + let c = 2.43; + let d = 0.59; + let e = 0.14; + return clamp((v * (a * v + b)) / (v * (c * v + d) + e), vec3<f32>(0.0), vec3<f32>(1.0)); +} + +// HSV to RGB conversion +const hsv2rgb_K = vec4<f32>(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); +fn hsv2rgb(c: vec3<f32>) -> vec3<f32> { + let p = abs(fract(c.xxx + hsv2rgb_K.xyz) * 6.0 - hsv2rgb_K.www); + return c.z * mix(hsv2rgb_K.xxx, clamp(p - hsv2rgb_K.xxx, vec3<f32>(0.0), vec3<f32>(1.0)), c.y); +} diff --git a/common/shaders/math/utils.wgsl b/common/shaders/math/utils.wgsl new file mode 100644 index 0000000..85f0bdf --- /dev/null +++ b/common/shaders/math/utils.wgsl @@ -0,0 +1,14 @@ +// General-purpose math utility functions. + +// Returns a 2x2 rotation matrix. +fn rot(a: f32) -> mat2x2<f32> { + let c = cos(a); + let s = sin(a); + return mat2x2<f32>(c, s, -s, c); +} + +// Fast approximation of tanh. +fn tanh_approx(x: f32) -> f32 { + let x2 = x * x; + return clamp(x * (27.0 + x2) / (27.0 + 9.0 * x2), -1.0, 1.0); +} diff --git a/common/shaders/render/fullscreen_vs.wgsl b/common/shaders/render/fullscreen_vs.wgsl new file mode 100644 index 0000000..a68604b --- /dev/null +++ b/common/shaders/render/fullscreen_vs.wgsl @@ -0,0 +1,10 @@ +// Common vertex shader for fullscreen post-processing effects. +// Draws a single triangle that covers the entire screen. +@vertex fn vs_main(@builtin(vertex_index) i: u32) -> @builtin(position) vec4<f32> { + var pos = array<vec2<f32>, 3>( + vec2<f32>(-1, -1), + vec2<f32>(3, -1), + vec2<f32>(-1, 3) + ); + return vec4<f32>(pos[i], 0.0, 1.0); +} diff --git a/common/shaders/render/raymarching.wgsl b/common/shaders/render/raymarching.wgsl new file mode 100644 index 0000000..5a86840 --- /dev/null +++ b/common/shaders/render/raymarching.wgsl @@ -0,0 +1,59 @@ +// Common functions for Signed Distance Field (SDF) raymarching. +// These functions require the user to define a `df(vec3<f32>) -> f32` function +// which represents the scene's distance field. + +const TOLERANCE: f32 = 0.0005; +const MAX_RAY_LENGTH: f32 = 20.0; +const MAX_RAY_MARCHES: i32 = 80; +const NORM_OFF: f32 = 0.005; + +// Computes the surface normal of the distance field at a point `pos`. +fn normal(pos: vec3<f32>) -> vec3<f32> { + let eps = vec2<f32>(NORM_OFF, 0.0); + var nor: vec3<f32>; + nor.x = df(pos + eps.xyy) - df(pos - eps.xyy); + nor.y = df(pos + eps.yxy) - df(pos - eps.yxy); + nor.z = df(pos + eps.yyx) - df(pos - eps.yyx); + return normalize(nor); +} + +// Performs the raymarching operation. +// Returns the distance along the ray to the surface, or MAX_RAY_LENGTH if no surface is hit. +fn rayMarch(ro: vec3<f32>, rd: vec3<f32>, initt: f32) -> f32 { + var t = initt; + for (var i = 0; i < MAX_RAY_MARCHES; i++) { + if (t > MAX_RAY_LENGTH) { + t = MAX_RAY_LENGTH; + break; + } + let d = df(ro + rd * t); + if (d < TOLERANCE) { + break; + } + t += d; + } + return t; +} + +// Computes a soft shadow for a given point. +fn shadow(lp: vec3<f32>, ld: vec3<f32>, mint: f32, maxt: f32) -> f32 { + let ds = 1.0 - 0.4; + var t = mint; + var nd = 1e6; + let soff = 0.05; + let smul = 1.5; + let MAX_SHD_MARCHES = 20; + + for (var i = 0; i < MAX_SHD_MARCHES; i++) { + let p = lp + ld * t; + let d = df(p); + if (d < TOLERANCE || t >= maxt) { + let sd = 1.0 - exp(-smul * max(t / maxt - soff, 0.0)); + return select(mix(sd, 1.0, smoothstep(0.0, 0.025, nd)), sd, t >= maxt); + } + nd = min(nd, d); + t += ds * d; + } + let sd = 1.0 - exp(-smul * max(t / maxt - soff, 0.0)); + return sd; +} diff --git a/common/shaders/sdf_primitives.wgsl b/common/shaders/sdf_primitives.wgsl index 31bbe2d..407fb29 100644 --- a/common/shaders/sdf_primitives.wgsl +++ b/common/shaders/sdf_primitives.wgsl @@ -12,3 +12,8 @@ fn sdTorus(p: vec3<f32>, t: vec2<f32>) -> f32 { fn sdPlane(p: vec3<f32>, n: vec3<f32>, h: f32) -> f32 { return dot(p, n) + h; } + +fn sdBox2D(p: vec2<f32>, b: vec2<f32>) -> f32 { + let d = abs(p) - b; + return length(max(d, vec2<f32>(0.0))) + min(max(d.x, d.y), 0.0); +} diff --git a/src/gpu/post_process_helper.cc b/src/gpu/post_process_helper.cc index 4ffa9c1..c5bef27 100644 --- a/src/gpu/post_process_helper.cc +++ b/src/gpu/post_process_helper.cc @@ -21,8 +21,10 @@ WGPURenderPipeline create_post_process_pipeline(WGPUDevice device, .uniform(PP_BINDING_EFFECT_PARAMS, WGPUShaderStage_Fragment) .build(device); + const std::string composed_shader = ShaderComposer::Get().Compose({}, shader_code); + WGPURenderPipeline pipeline = RenderPipelineBuilder(device) - .shader(shader_code) + .shader(composed_shader.c_str()) .bind_group_layout(bgl) .format(format) .build(); diff --git a/src/gpu/shaders.cc b/src/gpu/shaders.cc index 903b96e..1b50e8e 100644 --- a/src/gpu/shaders.cc +++ b/src/gpu/shaders.cc @@ -52,6 +52,11 @@ void InitShaderComposer() { register_if_exists("ray_box", AssetId::ASSET_SHADER_RAY_BOX); register_if_exists("ray_triangle", AssetId::ASSET_SHADER_RAY_TRIANGLE); + register_if_exists("render/fullscreen_vs", AssetId::ASSET_SHADER_RENDER_FULLSCREEN_VS); + register_if_exists("math/color", AssetId::ASSET_SHADER_MATH_COLOR); + register_if_exists("math/utils", AssetId::ASSET_SHADER_MATH_UTILS); + register_if_exists("render/raymarching", AssetId::ASSET_SHADER_RENDER_RAYMARCHING); + register_if_exists("cnn_activation", AssetId::ASSET_SHADER_CNN_ACTIVATION); register_if_exists("cnn_conv1x1", AssetId::ASSET_SHADER_CNN_CONV1X1); register_if_exists("cnn_conv3x3", AssetId::ASSET_SHADER_CNN_CONV3X3); diff --git a/src/tests/gpu/test_shader_assets.cc b/src/tests/gpu/test_shader_assets.cc index f1562ea..5619a61 100644 --- a/src/tests/gpu/test_shader_assets.cc +++ b/src/tests/gpu/test_shader_assets.cc @@ -71,12 +71,15 @@ int main() { validate_shader(AssetId::ASSET_SHADER_GAUSSIAN_BLUR, "GAUSSIAN_BLUR", {"@vertex", "vs_main", "@fragment", "fs_main"}); all_passed &= validate_shader(AssetId::ASSET_SHADER_SOLARIZE, "SOLARIZE", - {"@vertex", "vs_main", "@fragment", "fs_main"}); + {"#include \"render/fullscreen_vs\"", "@fragment", "fs_main"}); all_passed &= validate_shader(AssetId::ASSET_SHADER_DISTORT, "DISTORT", - {"@vertex", "vs_main", "@fragment", "fs_main"}); + {"#include \"render/fullscreen_vs\"", "@fragment", "fs_main"}); all_passed &= validate_shader(AssetId::ASSET_SHADER_CHROMA_ABERRATION, "CHROMA_ABERRATION", - {"@vertex", "vs_main", "@fragment", "fs_main"}); + {"#include \"render/fullscreen_vs\"", "@fragment", "fs_main"}); + all_passed &= validate_shader(AssetId::ASSET_SHADER_VIGNETTE, + "VIGNETTE", + {"#include \"render/fullscreen_vs\"", "@fragment", "fs_main"}); all_passed &= validate_shader(AssetId::ASSET_SHADER_VISUAL_DEBUG, "VISUAL_DEBUG", {"@vertex", "vs_main", "@fragment", "fs_main"}); diff --git a/workspaces/main/assets.txt b/workspaces/main/assets.txt index 72a469b..ace1462 100644 --- a/workspaces/main/assets.txt +++ b/workspaces/main/assets.txt @@ -62,6 +62,10 @@ SHADER_RENDER_LIGHTING_UTILS, NONE, ../../common/shaders/render/lighting_utils.w SHADER_MESH, NONE, shaders/mesh_render.wgsl, "Mesh Rasterization Shader" MESH_CUBE, NONE, obj/test_mesh.obj, "A simple cube mesh" DODECAHEDRON, NONE, obj/dodecahedron.obj, "A dodecahedron mesh" +SHADER_RENDER_FULLSCREEN_VS, NONE, ../../common/shaders/render/fullscreen_vs.wgsl, "Fullscreen Vertex Shader" +SHADER_MATH_COLOR, NONE, ../../common/shaders/math/color.wgsl, "Color Functions" +SHADER_MATH_UTILS, NONE, ../../common/shaders/math/utils.wgsl, "Math Utilities" +SHADER_RENDER_RAYMARCHING, NONE, ../../common/shaders/render/raymarching.wgsl, "Raymarching Functions" SHADER_VIGNETTE, NONE, shaders/vignette.wgsl, "Vignette Shader" SHADER_COMPUTE_GEN_NOISE, NONE, ../../common/shaders/compute/gen_noise.wgsl, "GPU Noise Compute Shader" SHADER_COMPUTE_GEN_PERLIN, NONE, ../../common/shaders/compute/gen_perlin.wgsl, "GPU Perlin Noise Compute Shader" diff --git a/workspaces/main/shaders/chroma_aberration.wgsl b/workspaces/main/shaders/chroma_aberration.wgsl index 6c942b7..ee730b1 100644 --- a/workspaces/main/shaders/chroma_aberration.wgsl +++ b/workspaces/main/shaders/chroma_aberration.wgsl @@ -10,14 +10,7 @@ struct ChromaAberrationParams { @group(0) @binding(2) var<uniform> uniforms: CommonUniforms; @group(0) @binding(3) var<uniform> params: ChromaAberrationParams; -@vertex fn vs_main(@builtin(vertex_index) i: u32) -> @builtin(position) vec4<f32> { - var pos = array<vec2<f32>, 3>( - vec2<f32>(-1, -1), - vec2<f32>(3, -1), - vec2<f32>(-1, 3) - ); - return vec4<f32>(pos[i], 0.0, 1.0); -} +#include "render/fullscreen_vs" @fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { let uv = p.xy / uniforms.resolution; diff --git a/workspaces/main/shaders/distort.wgsl b/workspaces/main/shaders/distort.wgsl index 5d35129..607ac60 100644 --- a/workspaces/main/shaders/distort.wgsl +++ b/workspaces/main/shaders/distort.wgsl @@ -11,14 +11,7 @@ struct DistortParams { @group(0) @binding(2) var<uniform> uniforms: CommonUniforms; @group(0) @binding(3) var<uniform> params: DistortParams; -@vertex fn vs_main(@builtin(vertex_index) i: u32) -> @builtin(position) vec4<f32> { - var pos = array<vec2<f32>, 3>( - vec2<f32>(-1, -1), - vec2<f32>(3, -1), - vec2<f32>(-1, 3) - ); - return vec4<f32>(pos[i], 0.0, 1.0); -} +#include "render/fullscreen_vs" @fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { let uv = p.xy / uniforms.resolution; diff --git a/workspaces/main/shaders/scene1.wgsl b/workspaces/main/shaders/scene1.wgsl index 7af3811..2a811f7 100644 --- a/workspaces/main/shaders/scene1.wgsl +++ b/workspaces/main/shaders/scene1.wgsl @@ -2,29 +2,15 @@ // Source: Saturday cubism experiment by skal #include "common_uniforms" +#include "math/color" +#include "math/utils" +#include "sdf_primitives" +#include "render/raymarching" @group(0) @binding(0) var<uniform> uniforms: CommonUniforms; const PI: f32 = 3.141592654; const TAU: f32 = 6.283185307; -const TOLERANCE: f32 = 0.0005; -const MAX_RAY_LENGTH: f32 = 20.0; -const MAX_RAY_MARCHES: i32 = 80; -const MAX_SHD_MARCHES: i32 = 20; -const NORM_OFF: f32 = 0.005; - -fn rot(a: f32) -> mat2x2<f32> { - let c = cos(a); - let s = sin(a); - return mat2x2<f32>(c, s, -s, c); -} - -// HSV to RGB conversion -const hsv2rgb_K = vec4<f32>(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); -fn hsv2rgb(c: vec3<f32>) -> vec3<f32> { - let p = abs(fract(c.xxx + hsv2rgb_K.xyz) * 6.0 - hsv2rgb_K.www); - return c.z * mix(hsv2rgb_K.xxx, clamp(p - hsv2rgb_K.xxx, vec3<f32>(0.0), vec3<f32>(1.0)), c.y); -} // Colors (precomputed HSV conversions) const skyCol = vec3<f32>(0.176, 0.235, 0.25); // HSV(0.57, 0.90, 0.25) @@ -38,44 +24,10 @@ const sunDir1 = vec3<f32>(0.0, 0.04997, -0.99875); // normalize(0, 0.05, -1) const lightPos1 = vec3<f32>(10.0, 10.0, 10.0); const lightPos2 = vec3<f32>(-10.0, 10.0, -10.0); -fn sRGB(t: vec3<f32>) -> vec3<f32> { - return mix(1.055 * pow(t, vec3<f32>(1.0/2.4)) - 0.055, 12.92 * t, step(t, vec3<f32>(0.0031308))); -} - -fn aces_approx(v_in: vec3<f32>) -> vec3<f32> { - var v = max(v_in, vec3<f32>(0.0)); - v *= 0.6; - let a = 2.51; - let b = 0.03; - let c = 2.43; - let d = 0.59; - let e = 0.14; - return clamp((v * (a * v + b)) / (v * (c * v + d) + e), vec3<f32>(0.0), vec3<f32>(1.0)); -} - -fn tanh_approx(x: f32) -> f32 { - let x2 = x * x; - return clamp(x * (27.0 + x2) / (27.0 + 9.0 * x2), -1.0, 1.0); -} - fn rayPlane(ro: vec3<f32>, rd: vec3<f32>, plane: vec4<f32>) -> f32 { return -(dot(ro, plane.xyz) + plane.w) / dot(rd, plane.xyz); } -fn box2d(p: vec2<f32>, b: vec2<f32>) -> f32 { - let d = abs(p) - b; - return length(max(d, vec2<f32>(0.0))) + min(max(d.x, d.y), 0.0); -} - -fn box3d(p: vec3<f32>, b: vec3<f32>) -> f32 { - let q = abs(p) - b; - return length(max(q, vec3<f32>(0.0))) + min(max(q.x, max(q.y, q.z)), 0.0); -} - -fn sphere(p: vec3<f32>, r: f32) -> f32 { - return length(p) - r; -} - var<private> g_rot0: mat2x2<f32>; fn render0(ro: vec3<f32>, rd: vec3<f32>) -> vec3<f32> { @@ -90,7 +42,7 @@ fn render0(ro: vec3<f32>, rd: vec3<f32>) -> vec3<f32> { if (tp1 > 0.0) { let pos = ro + tp1 * rd; let pp = pos.xz; - let db = box2d(pp, vec2<f32>(5.0, 9.0)) - 3.0; + let db = sdBox2D(pp, vec2<f32>(5.0, 9.0)) - 3.0; col += vec3<f32>(4.0) * skyCol * rd.y * rd.y * smoothstep(0.25, 0.0, db); col += vec3<f32>(0.8) * skyCol * exp(-0.5 * max(db, 0.0)); } @@ -106,12 +58,12 @@ fn df(p_in: vec3<f32>) -> f32 { // Cube var pc = p; pc -= vec3<f32>(-1.9, 0.0, 0.0); - let dCube = box3d(pc, vec3<f32>(1.6)); + let dCube = sdBox(pc, vec3<f32>(1.6)); // Sphere var ps = p; ps -= vec3<f32>(1.3, 0.0, 0.0); - let dSphere = sphere(ps, 1.2); + let dSphere = sdSphere(ps, 1.2); // Ground plane let dPlane = p.y + 1.0; @@ -123,51 +75,6 @@ fn df(p_in: vec3<f32>) -> f32 { return d; } -fn normal(pos: vec3<f32>) -> vec3<f32> { - let eps = vec2<f32>(NORM_OFF, 0.0); - var nor: vec3<f32>; - nor.x = df(pos + eps.xyy) - df(pos - eps.xyy); - nor.y = df(pos + eps.yxy) - df(pos - eps.yxy); - nor.z = df(pos + eps.yyx) - df(pos - eps.yyx); - return normalize(nor); -} - -fn rayMarch(ro: vec3<f32>, rd: vec3<f32>, initt: f32) -> f32 { - var t = initt; - for (var i = 0; i < MAX_RAY_MARCHES; i++) { - if (t > MAX_RAY_LENGTH) { - t = MAX_RAY_LENGTH; - break; - } - let d = df(ro + rd * t); - if (d < TOLERANCE) { - break; - } - t += d; - } - return t; -} - -fn shadow(lp: vec3<f32>, ld: vec3<f32>, mint: f32, maxt: f32) -> f32 { - let ds = 1.0 - 0.4; - var t = mint; - var nd = 1e6; - let soff = 0.05; - let smul = 1.5; - for (var i = 0; i < MAX_SHD_MARCHES; i++) { - let p = lp + ld * t; - let d = df(p); - if (d < TOLERANCE || t >= maxt) { - let sd = 1.0 - exp(-smul * max(t / maxt - soff, 0.0)); - return select(mix(sd, 1.0, smoothstep(0.0, 0.025, nd)), sd, t >= maxt); - } - nd = min(nd, d); - t += ds * d; - } - let sd = 1.0 - exp(-smul * max(t / maxt - soff, 0.0)); - return sd; -} - fn boxCol(col: vec3<f32>, nsp: vec3<f32>, rd: vec3<f32>, nnor: vec3<f32>, nrcol: vec3<f32>, nshd1: f32, nshd2: f32) -> vec3<f32> { var nfre = 1.0 + dot(rd, nnor); nfre *= nfre; @@ -236,14 +143,7 @@ fn effect(p: vec2<f32>) -> vec3<f32> { return render1(ro, rd); } -@vertex fn vs_main(@builtin(vertex_index) i: u32) -> @builtin(position) vec4<f32> { - var pos = array<vec2<f32>, 3>( - vec2<f32>(-1.0, -1.0), - vec2<f32>(3.0, -1.0), - vec2<f32>(-1.0, 3.0) - ); - return vec4<f32>(pos[i], 0.0, 1.0); -} +#include "render/fullscreen_vs" @fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { // Flip Y to match ShaderToy convention (origin at bottom-left) diff --git a/workspaces/main/shaders/solarize.wgsl b/workspaces/main/shaders/solarize.wgsl index de15dfc..0a69b83 100644 --- a/workspaces/main/shaders/solarize.wgsl +++ b/workspaces/main/shaders/solarize.wgsl @@ -5,14 +5,7 @@ @group(0) @binding(2) var<uniform> uniforms: CommonUniforms; -@vertex fn vs_main(@builtin(vertex_index) i: u32) -> @builtin(position) vec4<f32> { - var pos = array<vec2<f32>, 3>( - vec2<f32>(-1, -1), - vec2<f32>(3, -1), - vec2<f32>(-1, 3) - ); - return vec4<f32>(pos[i], 0.0, 1.0); -} +#include "render/fullscreen_vs" @fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { let uv = p.xy / uniforms.resolution; diff --git a/workspaces/main/shaders/vignette.wgsl b/workspaces/main/shaders/vignette.wgsl index b129883..c4d0389 100644 --- a/workspaces/main/shaders/vignette.wgsl +++ b/workspaces/main/shaders/vignette.wgsl @@ -10,15 +10,7 @@ struct VignetteParams { @group(0) @binding(2) var<uniform> common_uniforms: CommonUniforms; @group(0) @binding(3) var<uniform> params: VignetteParams; -@vertex -fn vs_main(@builtin(vertex_index) vertex_idx: u32) -> @builtin(position) vec4<f32> { - var pos = array<vec2<f32>, 3>( - vec2<f32>(-1.0, -1.0), - vec2<f32>(3.0, -1.0), - vec2<f32>(-1.0, 3.0) - ); - return vec4<f32>(pos[vertex_idx], 0.0, 1.0); -} +#include "render/fullscreen_vs" @fragment fn fs_main(@builtin(position) pos: vec4<f32>) -> @location(0) vec4<f32> { diff --git a/workspaces/test/assets.txt b/workspaces/test/assets.txt index ed81885..b717e15 100644 --- a/workspaces/test/assets.txt +++ b/workspaces/test/assets.txt @@ -54,6 +54,10 @@ SHADER_RENDER_LIGHTING_UTILS, NONE, ../../common/shaders/render/lighting_utils.w SHADER_MESH, NONE, shaders/mesh_render.wgsl, "Mesh Rasterization Shader" MESH_CUBE, NONE, obj/test_mesh.obj, "A simple cube mesh" DODECAHEDRON, NONE, obj/dodecahedron.obj, "A dodecahedron mesh" +SHADER_RENDER_FULLSCREEN_VS, NONE, ../../common/shaders/render/fullscreen_vs.wgsl, "Fullscreen Vertex Shader" +SHADER_MATH_COLOR, NONE, ../../common/shaders/math/color.wgsl, "Color Functions" +SHADER_MATH_UTILS, NONE, ../../common/shaders/math/utils.wgsl, "Math Utilities" +SHADER_RENDER_RAYMARCHING, NONE, ../../common/shaders/render/raymarching.wgsl, "Raymarching Functions" SHADER_VIGNETTE, NONE, shaders/vignette.wgsl, "Vignette Shader" SHADER_COMPUTE_GEN_NOISE, NONE, ../../common/shaders/compute/gen_noise.wgsl, "GPU Noise Compute Shader" SHADER_COMPUTE_GEN_PERLIN, NONE, ../../common/shaders/compute/gen_perlin.wgsl, "GPU Perlin Noise Compute Shader" diff --git a/workspaces/test/shaders/chroma_aberration.wgsl b/workspaces/test/shaders/chroma_aberration.wgsl index 6c942b7..ee730b1 100644 --- a/workspaces/test/shaders/chroma_aberration.wgsl +++ b/workspaces/test/shaders/chroma_aberration.wgsl @@ -10,14 +10,7 @@ struct ChromaAberrationParams { @group(0) @binding(2) var<uniform> uniforms: CommonUniforms; @group(0) @binding(3) var<uniform> params: ChromaAberrationParams; -@vertex fn vs_main(@builtin(vertex_index) i: u32) -> @builtin(position) vec4<f32> { - var pos = array<vec2<f32>, 3>( - vec2<f32>(-1, -1), - vec2<f32>(3, -1), - vec2<f32>(-1, 3) - ); - return vec4<f32>(pos[i], 0.0, 1.0); -} +#include "render/fullscreen_vs" @fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { let uv = p.xy / uniforms.resolution; diff --git a/workspaces/test/shaders/distort.wgsl b/workspaces/test/shaders/distort.wgsl index 5d35129..607ac60 100644 --- a/workspaces/test/shaders/distort.wgsl +++ b/workspaces/test/shaders/distort.wgsl @@ -11,14 +11,7 @@ struct DistortParams { @group(0) @binding(2) var<uniform> uniforms: CommonUniforms; @group(0) @binding(3) var<uniform> params: DistortParams; -@vertex fn vs_main(@builtin(vertex_index) i: u32) -> @builtin(position) vec4<f32> { - var pos = array<vec2<f32>, 3>( - vec2<f32>(-1, -1), - vec2<f32>(3, -1), - vec2<f32>(-1, 3) - ); - return vec4<f32>(pos[i], 0.0, 1.0); -} +#include "render/fullscreen_vs" @fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { let uv = p.xy / uniforms.resolution; diff --git a/workspaces/test/shaders/solarize.wgsl b/workspaces/test/shaders/solarize.wgsl index de15dfc..0a69b83 100644 --- a/workspaces/test/shaders/solarize.wgsl +++ b/workspaces/test/shaders/solarize.wgsl @@ -5,14 +5,7 @@ @group(0) @binding(2) var<uniform> uniforms: CommonUniforms; -@vertex fn vs_main(@builtin(vertex_index) i: u32) -> @builtin(position) vec4<f32> { - var pos = array<vec2<f32>, 3>( - vec2<f32>(-1, -1), - vec2<f32>(3, -1), - vec2<f32>(-1, 3) - ); - return vec4<f32>(pos[i], 0.0, 1.0); -} +#include "render/fullscreen_vs" @fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { let uv = p.xy / uniforms.resolution; diff --git a/workspaces/test/shaders/vignette.wgsl b/workspaces/test/shaders/vignette.wgsl index b129883..c4d0389 100644 --- a/workspaces/test/shaders/vignette.wgsl +++ b/workspaces/test/shaders/vignette.wgsl @@ -10,15 +10,7 @@ struct VignetteParams { @group(0) @binding(2) var<uniform> common_uniforms: CommonUniforms; @group(0) @binding(3) var<uniform> params: VignetteParams; -@vertex -fn vs_main(@builtin(vertex_index) vertex_idx: u32) -> @builtin(position) vec4<f32> { - var pos = array<vec2<f32>, 3>( - vec2<f32>(-1.0, -1.0), - vec2<f32>(3.0, -1.0), - vec2<f32>(-1.0, 3.0) - ); - return vec4<f32>(pos[vertex_idx], 0.0, 1.0); -} +#include "render/fullscreen_vs" @fragment fn fs_main(@builtin(position) pos: vec4<f32>) -> @location(0) vec4<f32> { |
