piet-wgpu 0.3.4

A hardware-accelerated 2D graphics backend for piet using wgpu
Documentation
// SPDX-License-Identifier: LGPL-3.0-or-later OR MPL-2.0
// This file is a part of `piet-hardware`.
//
// `piet-hardware` is free software: you can redistribute it and/or modify it under the
// terms of either:
//
// * GNU Lesser General Public License as published by the Free Software Foundation, either
//   version 3 of the License, or (at your option) any later version.
// * Mozilla Public License as published by the Mozilla Foundation, version 2.
//
// `piet-hardware` is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU Lesser General Public License or the Mozilla Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General Public License and the Mozilla
// Public License along with `piet-hardware`. If not, see <https://www.gnu.org/licenses/>.

struct Uniforms {
    // Viewport size.
    viewport_size: vec2<f32>,

    // 64-byte padding.
    padding: vec2<u32>,

    // 3x3 matrix for transforming vertices.
    transform: mat3x3<f32>,
};

struct VertexShaderOutput {
    @location(0) tex_coords: vec2<f32>,
    @location(1) mask_coords: vec2<f32>,
    @location(2) color: vec4<f32>,
    @builtin(position) position: vec4<f32>,
}

@group(0) @binding(0) var<uniform> uniforms: Uniforms;
@group(1) @binding(0) var texColor: texture_2d<f32>;
@group(1) @binding(1) var texSampler: sampler;
@group(2) @binding(0) var maskColor: texture_2d<f32>;
@group(2) @binding(1) var maskSampler: sampler;

fn unpack_color(color: u32) -> vec4<f32> {
    return vec4<f32>(
        f32((color >> 0u) & 255u),
        f32((color >> 8u) & 255u),
        f32((color >> 16u) & 255u),
        f32((color >> 24u) & 255u),
    ) / 255.0;
}

fn unpack_position(posn: vec2<f32>) -> vec4<f32> {
    return vec4<f32>(
        (2.0 * posn.x / uniforms.viewport_size.x) - 1.0,
        1.0 - (2.0 * posn.y / uniforms.viewport_size.y),
        0.0,
        1.0,
    );
}

struct InVertex {
    @location(0) position: vec2<f32>,
    @location(1) tex_coords: vec2<f32>,
    @location(2) color: u32,
}

@vertex
fn vertex_main(vert: InVertex) -> VertexShaderOutput {
    var out: VertexShaderOutput;

    // Transform the vertex position.
    var pos: vec3<f32> = uniforms.transform * vec3<f32>(vert.position, 1.0);
    pos = pos / pos.z;

    out.position = unpack_position(pos.xy);
    out.tex_coords = vert.tex_coords;
    out.mask_coords = vec2<f32>(
        pos.x / uniforms.viewport_size.x,
        pos.y / uniforms.viewport_size.y,
    );
    out.color = unpack_color(vert.color);

    return out;
}

@fragment
fn fragment_main(in: VertexShaderOutput) -> @location(0) vec4<f32> {
    let tex_color = textureSample(texColor, texSampler, in.tex_coords);
    let mask_color = textureSample(maskColor, maskSampler, in.mask_coords);

    let main_color = in.color * tex_color;
    return main_color * mask_color;
}