summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/shaders/combined_postprocess.wgsl15
-rw-r--r--common/shaders/gaussian_blur.wgsl15
-rw-r--r--common/shaders/heptagon.wgsl15
-rw-r--r--common/shaders/passthrough.wgsl15
-rw-r--r--common/shaders/render/fullscreen_uv_vs.wgsl15
-rw-r--r--common/shaders/skybox.wgsl20
-rw-r--r--src/effects/shaders.cc2
-rw-r--r--src/gpu/shader_composer.cc42
-rw-r--r--workspaces/main/assets.txt1
-rw-r--r--workspaces/test/assets.txt1
10 files changed, 64 insertions, 77 deletions
diff --git a/common/shaders/combined_postprocess.wgsl b/common/shaders/combined_postprocess.wgsl
index d56386e..bf43d6e 100644
--- a/common/shaders/combined_postprocess.wgsl
+++ b/common/shaders/combined_postprocess.wgsl
@@ -3,25 +3,12 @@
#include "sequence_uniforms"
#include "postprocess_inline"
+#include "render/fullscreen_uv_vs" // <- VertexOutput + vs_main
@group(0) @binding(0) var input_sampler: sampler;
@group(0) @binding(1) var input_texture: texture_2d<f32>;
@group(0) @binding(2) var<uniform> uniforms: UniformsSequenceParams;
-struct VertexOutput {
- @builtin(position) position: vec4<f32>,
- @location(0) uv: vec2<f32>,
-};
-
-@vertex fn vs_main(@builtin(vertex_index) vid: u32) -> VertexOutput {
- var out: VertexOutput;
- let x = f32((vid & 1u) << 1u);
- let y = f32((vid & 2u));
- out.position = vec4<f32>(x * 2.0 - 1.0, 1.0 - y * 2.0, 0.0, 1.0);
- out.uv = vec2<f32>(x, y);
- return out;
-}
-
@fragment fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
// Sample base color
var color = textureSample(input_texture, input_sampler, in.uv);
diff --git a/common/shaders/gaussian_blur.wgsl b/common/shaders/gaussian_blur.wgsl
index 293977f..551d522 100644
--- a/common/shaders/gaussian_blur.wgsl
+++ b/common/shaders/gaussian_blur.wgsl
@@ -1,5 +1,6 @@
// Gaussian blur shader for Sequence v2
#include "sequence_uniforms"
+#include "render/fullscreen_uv_vs" // <- VertexOutput + vs_main
@group(0) @binding(0) var input_sampler: sampler;
@group(0) @binding(1) var input_texture: texture_2d<f32>;
@@ -12,20 +13,6 @@ struct GaussianBlurParams {
};
@group(0) @binding(3) var<uniform> params: GaussianBlurParams;
-struct VertexOutput {
- @builtin(position) position: vec4<f32>,
- @location(0) uv: vec2<f32>,
-};
-
-@vertex fn vs_main(@builtin(vertex_index) vid: u32) -> VertexOutput {
- var out: VertexOutput;
- let x = f32((vid & 1u) << 1u);
- let y = f32((vid & 2u));
- out.position = vec4<f32>(x * 2.0 - 1.0, 1.0 - y * 2.0, 0.0, 1.0);
- out.uv = vec2<f32>(x, y);
- return out;
-}
-
@fragment fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
let texel_size = 1.0 / uniforms.resolution;
let offset = params.direction * texel_size;
diff --git a/common/shaders/heptagon.wgsl b/common/shaders/heptagon.wgsl
index 078978a..519dce5 100644
--- a/common/shaders/heptagon.wgsl
+++ b/common/shaders/heptagon.wgsl
@@ -1,23 +1,10 @@
// Heptagon shader for Sequence v2
#include "sequence_uniforms"
+#include "render/fullscreen_uv_vs" // <- VertexOutput + vs_main
// Standard v2 post-process layout (bindings 0,1 unused for scene effects)
@group(0) @binding(2) var<uniform> uniforms: UniformsSequenceParams;
-struct VertexOutput {
- @builtin(position) position: vec4<f32>,
- @location(0) uv: vec2<f32>,
-};
-
-@vertex fn vs_main(@builtin(vertex_index) vid: u32) -> VertexOutput {
- var out: VertexOutput;
- let x = f32((vid & 1u) << 1u);
- let y = f32((vid & 2u));
- out.position = vec4<f32>(x * 2.0 - 1.0, 1.0 - y * 2.0, 0.0, 1.0);
- out.uv = vec2<f32>(x, y);
- return out;
-}
-
fn sdf_heptagon(p: vec2<f32>, r: f32) -> f32 {
let an = 3.141593 / 7.0; // PI/7 for heptagon
let acs = vec2<f32>(cos(an), sin(an));
diff --git a/common/shaders/passthrough.wgsl b/common/shaders/passthrough.wgsl
index 9fb0bdc..265082a 100644
--- a/common/shaders/passthrough.wgsl
+++ b/common/shaders/passthrough.wgsl
@@ -1,24 +1,11 @@
// Passthrough shader for Sequence v2
#include "sequence_uniforms"
+#include "render/fullscreen_uv_vs" // <- VertexOutput + vs_main
@group(0) @binding(0) var input_sampler: sampler;
@group(0) @binding(1) var input_texture: texture_2d<f32>;
@group(0) @binding(2) var<uniform> uniforms: UniformsSequenceParams;
-struct VertexOutput {
- @builtin(position) position: vec4<f32>,
- @location(0) uv: vec2<f32>,
-};
-
-@vertex fn vs_main(@builtin(vertex_index) vid: u32) -> VertexOutput {
- var out: VertexOutput;
- let x = f32((vid & 1u) << 1u);
- let y = f32((vid & 2u));
- out.position = vec4<f32>(x * 2.0 - 1.0, 1.0 - y * 2.0, 0.0, 1.0);
- out.uv = vec2<f32>(x, y);
- return out;
-}
-
@fragment fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
return textureSample(input_texture, input_sampler, in.uv);
}
diff --git a/common/shaders/render/fullscreen_uv_vs.wgsl b/common/shaders/render/fullscreen_uv_vs.wgsl
new file mode 100644
index 0000000..42d87c3
--- /dev/null
+++ b/common/shaders/render/fullscreen_uv_vs.wgsl
@@ -0,0 +1,15 @@
+// Common vertex shader for fullscreen post-processing effects.
+// Draws a single triangle that covers the entire screen, with uv
+// coordinates in [0..1]
+struct VertexOutput {
+ @builtin(position) position: vec4<f32>,
+ @location(0) uv: vec2<f32>,
+};
+
+@vertex fn vs_main(@builtin(vertex_index) i: u32) -> VertexOutput {
+ let pos = array<vec4f, 3>(vec4f(-1, -1, 0, 1.), vec4f(3, -1, 2., 1.), vec4f(-1, 3, 0, -1));
+ var out: VertexOutput;
+ out.position = vec4f(pos[i].xy, 0.0, 1.0);
+ out.uv = pos[i].zw;
+ return out;
+}
diff --git a/common/shaders/skybox.wgsl b/common/shaders/skybox.wgsl
index 31bea3b..d280390 100644
--- a/common/shaders/skybox.wgsl
+++ b/common/shaders/skybox.wgsl
@@ -1,29 +1,11 @@
#include "common_uniforms"
#include "math/common_utils"
+#include "render/fullscreen_uv_vs" // <- VertexOutput + vs_main
@group(0) @binding(0) var sky_tex: texture_2d<f32>;
@group(0) @binding(1) var sky_sampler: sampler;
@group(0) @binding(2) var<uniform> globals: GlobalUniforms;
-struct VertexOutput {
- @builtin(position) position: vec4<f32>,
- @location(0) uv: vec2<f32>,
-};
-
-@vertex
-fn vs_main(@builtin(vertex_index) vertex_index: u32) -> VertexOutput {
- var pos = array<vec2<f32>, 3>(
- vec2<f32>(-1.0, -1.0),
- vec2<f32>( 3.0, -1.0),
- vec2<f32>(-1.0, 3.0)
- );
-
- var out: VertexOutput;
- out.position = vec4<f32>(pos[vertex_index], 0.0, 1.0);
- out.uv = vec2<f32>(pos[vertex_index].x * 0.5 + 0.5, 1.0 - (pos[vertex_index].y * 0.5 + 0.5));
- return out;
-}
-
@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
// Convert UV to NDC
diff --git a/src/effects/shaders.cc b/src/effects/shaders.cc
index 3ba00bc..7e32aa6 100644
--- a/src/effects/shaders.cc
+++ b/src/effects/shaders.cc
@@ -53,6 +53,8 @@ void InitShaderComposer() {
register_if_exists("render/fullscreen_vs",
AssetId::ASSET_SHADER_RENDER_FULLSCREEN_VS);
+ register_if_exists("render/fullscreen_uv_vs",
+ AssetId::ASSET_SHADER_RENDER_FULLSCREEN_UV_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",
diff --git a/src/gpu/shader_composer.cc b/src/gpu/shader_composer.cc
index fce6de4..be311dd 100644
--- a/src/gpu/shader_composer.cc
+++ b/src/gpu/shader_composer.cc
@@ -2,6 +2,7 @@
// It implements the ShaderComposer class.
#include "gpu/shader_composer.h"
+#include <cassert>
#include <set>
#include <sstream>
@@ -44,6 +45,27 @@ void ShaderComposer::ResolveRecursive(const std::string& source,
ss << "// --- End Include: " << name << " ---\n";
} else {
ss << "// ERROR: Snippet not found: " << name << "\n";
+#if !defined(STRIP_ALL)
+ // Find suggestions: registered snippets whose basename matches.
+ std::string suggestion;
+ for (const auto& [sname, _] : snippets_) {
+ auto slash = sname.rfind('/');
+ std::string basename =
+ (slash == std::string::npos) ? sname : sname.substr(slash + 1);
+ if (basename == name) {
+ suggestion = sname;
+ break;
+ }
+ }
+ fprintf(stderr,
+ "FATAL: #include \"%s\" - snippet not registered.\n",
+ name.c_str());
+ if (!suggestion.empty()) {
+ fprintf(stderr, " Fix: use #include \"%s\"\n",
+ suggestion.c_str());
+ }
+ assert(false && "Unresolved shader #include");
+#endif
}
}
}
@@ -111,10 +133,26 @@ void ShaderComposer::VerifyIncludes() const {
}
}
if (!missing.empty()) {
- fprintf(stderr, "WARNING: Unregistered shader snippets:\n");
+ fprintf(stderr, "ERROR: Unregistered shader snippets referenced in #include:\n");
for (const auto& name : missing) {
- fprintf(stderr, " - %s\n", name.c_str());
+ std::string suggestion;
+ for (const auto& [sname, _] : snippets_) {
+ auto slash = sname.rfind('/');
+ std::string basename =
+ (slash == std::string::npos) ? sname : sname.substr(slash + 1);
+ if (basename == name) {
+ suggestion = sname;
+ break;
+ }
+ }
+ if (!suggestion.empty()) {
+ fprintf(stderr, " - \"%s\" (did you mean \"%s\"?)\n", name.c_str(),
+ suggestion.c_str());
+ } else {
+ fprintf(stderr, " - \"%s\"\n", name.c_str());
+ }
}
+ assert(false && "Unregistered shader snippets - fix #include paths");
}
#endif
}
diff --git a/workspaces/main/assets.txt b/workspaces/main/assets.txt
index 61d65d0..ba28b04 100644
--- a/workspaces/main/assets.txt
+++ b/workspaces/main/assets.txt
@@ -68,6 +68,7 @@ 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_RENDER_FULLSCREEN_UV_VS, NONE, ../../common/shaders/render/fullscreen_uv_vs.wgsl, "Fullscreen Vertex Shader + UV"
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"
diff --git a/workspaces/test/assets.txt b/workspaces/test/assets.txt
index a2d3002..7835cf8 100644
--- a/workspaces/test/assets.txt
+++ b/workspaces/test/assets.txt
@@ -55,6 +55,7 @@ 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_RENDER_FULLSCREEN_UV_VS, NONE, ../../common/shaders/render/fullscreen_uv_vs.wgsl, "Fullscreen Vertex Shader + UV"
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"