summaryrefslogtreecommitdiff
path: root/src/shaders/render
diff options
context:
space:
mode:
Diffstat (limited to 'src/shaders/render')
-rw-r--r--src/shaders/render/fullscreen_uv_vs.wgsl24
1 files changed, 19 insertions, 5 deletions
diff --git a/src/shaders/render/fullscreen_uv_vs.wgsl b/src/shaders/render/fullscreen_uv_vs.wgsl
index f9ae427..5f76160 100644
--- a/src/shaders/render/fullscreen_uv_vs.wgsl
+++ b/src/shaders/render/fullscreen_uv_vs.wgsl
@@ -1,15 +1,29 @@
// Common vertex shader for fullscreen post-processing effects.
-// Draws a single triangle that covers the entire screen, with uv
-// coordinates in [0..1]
+// Draws a single triangle that covers the entire screen.
+//
+// Screen-space convention: Y-UP, origin at BOTTOM-LEFT
+// uv in [0,1]: (0,0) = bottom-left, (1,1) = top-right
+// st in [-1,1]: NDC directly, y-up
+//
+// WebGPU textures are Y-DOWN ((0,0) at top-left).
+// Use textureSampleYUp() instead of textureSample() when sampling with uv.
struct VertexOutput {
- @builtin(position) position: vec4f,
- @location(0) uv: vec2f,
+ @builtin(position) position: vec4f, // in pixel screen units
+ @location(0) uv: vec2f, // in [0, 1]
+ @location(1) st: vec2f, // in [-1, 1]
};
@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));
+ let pos = array<vec4f, 3>(vec4f(-1, -1, 0, 0.), vec4f(3, -1, 2., 0.), vec4f(-1, 3, 0, 2.));
var out: VertexOutput;
out.position = vec4f(pos[i].xy, 0.0, 1.0);
out.uv = pos[i].zw;
+ out.st = pos[i].xy;
return out;
}
+
+// Sample a texture using y-up UV coordinates (uv.y=0 at bottom).
+// Flips Y to match WebGPU texture convention (texel (0,0) at top-left).
+fn textureSampleYUp(tex: texture_2d<f32>, s: sampler, uv: vec2f) -> vec4f {
+ return textureSample(tex, s, vec2f(uv.x, 1.0 - uv.y));
+}