// Invert Effect Shader // Inverts color values struct Uniforms { // params packed as vec4s for proper 16-byte alignment // params[0-3] in params0, params[4-7] in params1, etc. params0: vec4, params1: vec4, params2: vec4, params3: vec4, texture_width: f32, texture_height: f32, time: f32, mix: f32, } struct VertexOutput { @builtin(position) position: vec4, @location(0) uv: vec2, } @group(0) @binding(0) var source_tex: texture_2d; @group(0) @binding(1) var source_sampler: sampler; @group(0) @binding(2) var uniforms: Uniforms; @vertex fn vs_main(@builtin(vertex_index) vertex_index: u32) -> VertexOutput { var out: VertexOutput; let x = f32((vertex_index & 1u) << 1u); let y = f32(vertex_index & 2u); out.position = vec4(x * 2.0 - 1.0, 1.0 - y * 2.0, 0.0, 1.0); out.uv = vec2(x, y); return out; } // The HDR pipeline feeds these shaders LINEAR light, but "invert" is a // perceptual operation defined in gamma/display space (Photoshop, GIMP, etc.). // Convert to sRGB, invert there, then convert back to linear. The sRGB helpers // (linear_to_srgb / srgb_to_linear) come from the prepended COLOR_WGSL prelude. @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4 { let src = textureSample(source_tex, source_sampler, in.uv); let amount = uniforms.params0.x; // params[0] let src_srgb = linear_to_srgb(src.rgb); let inverted = vec3(1.0) - src_srgb; let result_srgb = mix(src_srgb, inverted, amount * uniforms.mix); return vec4(srgb_to_linear(result_srgb), src.a); }