summaryrefslogtreecommitdiff
path: root/rust/crates/compositor/src/shaders/layer.wgsl
diff options
context:
space:
mode:
Diffstat (limited to 'rust/crates/compositor/src/shaders/layer.wgsl')
-rw-r--r--rust/crates/compositor/src/shaders/layer.wgsl49
1 files changed, 49 insertions, 0 deletions
diff --git a/rust/crates/compositor/src/shaders/layer.wgsl b/rust/crates/compositor/src/shaders/layer.wgsl
new file mode 100644
index 00000000..9e335687
--- /dev/null
+++ b/rust/crates/compositor/src/shaders/layer.wgsl
@@ -0,0 +1,49 @@
+struct VertexOutput {
+ @builtin(position) position: vec4f,
+ @location(0) tex_coord: vec2f,
+}
+
+struct LayerUniforms {
+ resolution: vec2f,
+ center: vec2f,
+ size: vec2f,
+ rotation_radians: f32,
+ opacity: f32,
+ flip_x: f32,
+ flip_y: f32,
+}
+
+@group(0) @binding(0) var source_texture: texture_2d<f32>;
+@group(0) @binding(1) var source_sampler: sampler;
+@group(1) @binding(0) var<uniform> uniforms: LayerUniforms;
+
+fn rotate_inverse(point: vec2f, angle: f32) -> vec2f {
+ let c = cos(angle);
+ let s = sin(angle);
+ return vec2f(
+ point.x * c + point.y * s,
+ -point.x * s + point.y * c,
+ );
+}
+
+@fragment
+fn fragment_main(input: VertexOutput) -> @location(0) vec4f {
+ let pixel = input.tex_coord * uniforms.resolution;
+ let local = rotate_inverse(pixel - uniforms.center, uniforms.rotation_radians);
+
+ let uv = vec2f(
+ local.x / uniforms.size.x + 0.5,
+ local.y / uniforms.size.y + 0.5,
+ );
+
+ if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {
+ return vec4f(0.0, 0.0, 0.0, 0.0);
+ }
+
+ let sample_uv = vec2f(
+ select(uv.x, 1.0 - uv.x, uniforms.flip_x > 0.5),
+ select(uv.y, 1.0 - uv.y, uniforms.flip_y > 0.5),
+ );
+ let color = textureSampleLevel(source_texture, source_sampler, sample_uv, 0.0);
+ return vec4f(color.rgb, color.a * uniforms.opacity);
+}