Use matrices in render_strips.wgsl
diff --git a/sparse_strips/vello_sparse_shaders/shaders/render_strips.wgsl b/sparse_strips/vello_sparse_shaders/shaders/render_strips.wgsl index c0711e6..f19f9a9 100644 --- a/sparse_strips/vello_sparse_shaders/shaders/render_strips.wgsl +++ b/sparse_strips/vello_sparse_shaders/shaders/render_strips.wgsl
@@ -434,16 +434,9 @@ let paint_tex_idx = in.paint_and_rect_flag & PAINT_TEXTURE_INDEX_MASK; let linear_gradient = unpack_linear_gradient(paint_tex_idx); - // Calculate fragment position and apply transform + // Calculate fragment position and apply affine transform let fragment_pos = in.sample_xy; - let grad_pos = vec2<f32>( - linear_gradient.transform[0] * fragment_pos.x + - linear_gradient.transform[2] * fragment_pos.y + - linear_gradient.transform[4], - linear_gradient.transform[1] * fragment_pos.x + - linear_gradient.transform[3] * fragment_pos.y + - linear_gradient.transform[5] - ); + let grad_pos = linear_gradient.transform * fragment_pos + linear_gradient.translate; // For linear gradient, t-value is just the x coordinate in gradient space let t_value = grad_pos.x + 0.00001; @@ -459,16 +452,9 @@ let paint_tex_idx = in.paint_and_rect_flag & PAINT_TEXTURE_INDEX_MASK; let radial_gradient = unpack_radial_gradient(paint_tex_idx); - // Calculate fragment position and apply transform + // Calculate fragment position and apply affine transform let fragment_pos = in.sample_xy; - let grad_pos = vec2<f32>( - radial_gradient.transform[0] * fragment_pos.x + - radial_gradient.transform[2] * fragment_pos.y + - radial_gradient.transform[4], - radial_gradient.transform[1] * fragment_pos.x + - radial_gradient.transform[3] * fragment_pos.y + - radial_gradient.transform[5] - ); + let grad_pos = radial_gradient.transform * fragment_pos + radial_gradient.translate; // For radial gradient, calculate distance from center let gradient_result = calculate_radial_gradient(grad_pos, radial_gradient); @@ -484,16 +470,9 @@ let paint_tex_idx = in.paint_and_rect_flag & PAINT_TEXTURE_INDEX_MASK; let sweep_gradient = unpack_sweep_gradient(paint_tex_idx); - // Calculate fragment position and apply transform + // Calculate fragment position and apply affine transform let fragment_pos = in.sample_xy; - var grad_pos = vec2<f32>( - sweep_gradient.transform[0] * fragment_pos.x + - sweep_gradient.transform[2] * fragment_pos.y + - sweep_gradient.transform[4], - sweep_gradient.transform[1] * fragment_pos.x + - sweep_gradient.transform[3] * fragment_pos.y + - sweep_gradient.transform[5] - ); + var grad_pos = sweep_gradient.transform * fragment_pos + sweep_gradient.translate; // Before passing the position to the angle calculation, we bias // very small coordinates to 0. Otherwise the sweep gradient's seam @@ -1122,8 +1101,10 @@ gradient_start: u32, /// Width of the gradient texture. texture_width: u32, - /// Transform matrix [a, b, c, d, tx, ty]. - transform: array<f32, 6>, + /// 2×2 linear part of the affine transform (columns [a,b] and [c,d]). + transform: mat2x2<f32>, + /// Translation part of the affine transform [tx, ty]. + translate: vec2<f32>, } struct RadialGradient { @@ -1133,8 +1114,10 @@ gradient_start: u32, /// Width of the gradient texture. texture_width: u32, - /// Transform matrix [a, b, c, d, tx, ty]. - transform: array<f32, 6>, + /// 2×2 linear part of the affine transform (columns [a,b] and [c,d]). + transform: mat2x2<f32>, + /// Translation part of the affine transform [tx, ty]. + translate: vec2<f32>, /// Bias value for radial gradient calculation. bias: f32, /// Scale factor for radial gradient calculation. @@ -1162,8 +1145,10 @@ gradient_start: u32, /// Width of the gradient texture. texture_width: u32, - /// Transform matrix [a, b, c, d, tx, ty]. - transform: array<f32, 6>, + /// 2×2 linear part of the affine transform (columns [a,b] and [c,d]). + transform: mat2x2<f32>, + /// Translation part of the affine transform [tx, ty]. + translate: vec2<f32>, /// Starting angle for sweep gradient (in radians). start_angle: f32, /// Inverse of angle delta for sweep gradient. @@ -1180,13 +1165,14 @@ let extend_mode = texture_width_and_extend_mode.y; let gradient_start = texel0.y; - let transform = array<f32, 6>( - bitcast<f32>(texel0.z), bitcast<f32>(texel0.w), bitcast<f32>(texel1.x), - bitcast<f32>(texel1.y), bitcast<f32>(texel1.z), bitcast<f32>(texel1.w) + let transform = mat2x2<f32>( + vec2<f32>(bitcast<f32>(texel0.z), bitcast<f32>(texel0.w)), + vec2<f32>(bitcast<f32>(texel1.x), bitcast<f32>(texel1.y)) ); + let translate = vec2<f32>(bitcast<f32>(texel1.z), bitcast<f32>(texel1.w)); return LinearGradient( - extend_mode, gradient_start, texture_width, transform + extend_mode, gradient_start, texture_width, transform, translate ); } @@ -1296,10 +1282,11 @@ let texture_width = texture_width_and_extend_mode.x; let extend_mode = texture_width_and_extend_mode.y; let gradient_start = texel0.y; - let transform = array<f32, 6>( - bitcast<f32>(texel0.z), bitcast<f32>(texel0.w), bitcast<f32>(texel1.x), - bitcast<f32>(texel1.y), bitcast<f32>(texel1.z), bitcast<f32>(texel1.w) + let transform = mat2x2<f32>( + vec2<f32>(bitcast<f32>(texel0.z), bitcast<f32>(texel0.w)), + vec2<f32>(bitcast<f32>(texel1.x), bitcast<f32>(texel1.y)) ); + let translate = vec2<f32>(bitcast<f32>(texel1.z), bitcast<f32>(texel1.w)); let kind_and_swapped = unpack_radial_kind_and_swapped(texel2.x); let kind = kind_and_swapped.x; @@ -1314,7 +1301,7 @@ let scaled_r0_squared = bitcast<f32>(texel3.w); return RadialGradient( - extend_mode, gradient_start, texture_width, transform, + extend_mode, gradient_start, texture_width, transform, translate, bias, scale, fp0, fp1, fr1, f_focal_x, f_is_swapped, scaled_r0_squared, kind ); } @@ -1329,16 +1316,17 @@ let texture_width = texture_width_and_extend_mode.x; let extend_mode = texture_width_and_extend_mode.y; let gradient_start = texel0.y; - let transform = array<f32, 6>( - bitcast<f32>(texel0.z), bitcast<f32>(texel0.w), bitcast<f32>(texel1.x), - bitcast<f32>(texel1.y), bitcast<f32>(texel1.z), bitcast<f32>(texel1.w) + let transform = mat2x2<f32>( + vec2<f32>(bitcast<f32>(texel0.z), bitcast<f32>(texel0.w)), + vec2<f32>(bitcast<f32>(texel1.x), bitcast<f32>(texel1.y)) ); + let translate = vec2<f32>(bitcast<f32>(texel1.z), bitcast<f32>(texel1.w)); let start_angle = bitcast<f32>(texel2.x); let inv_angle_delta = bitcast<f32>(texel2.y); return SweepGradient( - extend_mode, gradient_start, texture_width, transform, start_angle, inv_angle_delta + extend_mode, gradient_start, texture_width, transform, translate, start_angle, inv_angle_delta ); }