Skip to content

Add support for float colours on the GPU #970

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion sparse_strips/vello_api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ repository.workspace = true
publish = false

[dependencies]
peniko = { workspace = true }
peniko = { workspace = true, features = ["bytemuck"] }
png = { workspace = true, optional = true }

[features]
Expand Down
2 changes: 1 addition & 1 deletion sparse_strips/vello_dev_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// than 1. For example, if the target pixel is (233, 43, 64, 100), then permissible
// values are (232, 43, 65, 101) or (233, 42, 64, 100), but not (231, 43, 64, 100).
const DEFAULT_CPU_U8_TOLERANCE: u8 = 0;
const DEFAULT_HYBRID_TOLERANCE: u8 = 1;
const DEFAULT_HYBRID_TOLERANCE: u8 = 0;

use proc_macro::TokenStream;
use quote::quote;
Expand Down
19 changes: 3 additions & 16 deletions sparse_strips/vello_hybrid/shaders/sparse_strip_renderer.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct StripInstance {
// Alpha texture column index where this strip's alpha values begin
@location(2) col: u32,
// [r, g, b, a] packed as u8's
@location(3) rgba: u32,
@location(3) rgba: vec4<f32>,
}

struct VertexOutput {
Expand All @@ -39,7 +39,7 @@ struct VertexOutput {
// Ending x-position of the dense (alpha) region
@location(1) @interpolate(flat) dense_end: u32,
// RGBA color value
@location(2) @interpolate(flat) color: u32,
@location(2) @interpolate(flat) color: vec4<f32>,
// Normalized device coordinates (NDC) for the current vertex
@builtin(position) position: vec4<f32>,
};
Expand Down Expand Up @@ -119,7 +119,7 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
alpha = f32((alphas_u32 >> (y * 8u)) & 0xffu) * (1.0 / 255.0);
}
// Apply the alpha value to the unpacked RGBA color
return alpha * unpack4x8unorm(in.color);
return alpha * in.color;
}

fn unpack_alphas_from_channel(rgba: vec4<u32>, channel_index: u32) -> u32 {
Expand All @@ -132,16 +132,3 @@ fn unpack_alphas_from_channel(rgba: vec4<u32>, channel_index: u32) -> u32 {
default: { return rgba.x; }
}
}

// Polyfills `unpack4x8unorm`.
//
// Downlevel targets do not support native WGSL `unpack4x8unorm`.
fn unpack4x8unorm(rgba_packed: u32) -> vec4<f32> {
// Extract each byte and convert to float in range [0,1]
return vec4<f32>(
f32((rgba_packed >> 0u) & 0xFFu) / 255.0, // r
f32((rgba_packed >> 8u) & 0xFFu) / 255.0, // g
f32((rgba_packed >> 16u) & 0xFFu) / 255.0, // b
f32((rgba_packed >> 24u) & 0xFFu) / 255.0 // a
);
}
11 changes: 7 additions & 4 deletions sparse_strips/vello_hybrid/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ use alloc::vec::Vec;
use core::fmt::Debug;

use bytemuck::{Pod, Zeroable};
use vello_common::tile::Tile;
use vello_common::{
color::{PremulColor, Srgb},
tile::Tile,
};
use wgpu::{
BindGroup, BindGroupLayout, BlendState, Buffer, ColorTargetState, ColorWrites, Device,
PipelineCompilationOptions, Queue, RenderPass, RenderPipeline, Texture, util::DeviceExt,
Expand Down Expand Up @@ -114,8 +117,8 @@ pub struct GpuStrip {
///
/// There are [`Config::strip_height`] alpha values per column.
pub col: u32,
/// RGBA color value
pub rgba: u32,
/// RGBA color value.
pub rgba: PremulColor<Srgb>,
}

impl GpuStrip {
Expand All @@ -125,7 +128,7 @@ impl GpuStrip {
0 => Uint32,
1 => Uint32,
2 => Uint32,
3 => Uint32,
3 => Float32x4,
]
}
}
Expand Down
9 changes: 5 additions & 4 deletions sparse_strips/vello_hybrid/src/scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,9 @@ impl Scene {
let wide_tile = &self.wide.tiles[wide_tile_idx];
let wide_tile_x = wide_tile_col * WideTile::WIDTH;
let wide_tile_y = wide_tile_row * Tile::HEIGHT;
let bg = wide_tile.bg.as_premul_rgba8().to_u32();
if bg != 0 {
let bg = wide_tile.bg.as_premul_f32();
// TODO: Is this a precise enough check for transparency?
if bg.components[3] > 0. {
strips.push(GpuStrip {
x: wide_tile_x,
y: wide_tile_y,
Expand All @@ -226,7 +227,7 @@ impl Scene {
match cmd {
vello_common::coarse::Cmd::Fill(fill) => {
let rgba = match &fill.paint {
Paint::Solid(color) => color.as_premul_rgba8().to_u32(),
Paint::Solid(color) => color.as_premul_f32(),
Paint::Indexed(_) => unimplemented!(),
};
strips.push(GpuStrip {
Expand All @@ -240,7 +241,7 @@ impl Scene {
}
vello_common::coarse::Cmd::AlphaFill(cmd_strip) => {
let rgba = match &cmd_strip.paint {
Paint::Solid(color) => color.as_premul_rgba8().to_u32(),
Paint::Solid(color) => color.as_premul_f32(),
Paint::Indexed(_) => unimplemented!(),
};

Expand Down
Loading