Files
OpenCut/rust/crates/compositor/src/shaders/layer.wgsl
T
2026-04-13 05:01:51 +02:00

50 lines
1.3 KiB
WebGPU Shading Language

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);
}