From ced6309a3b40798f8ed69c2aa23d2debff8a40ff Mon Sep 17 00:00:00 2001 From: Chad Brokaw Date: Sat, 6 May 2023 03:27:53 -0400 Subject: [PATCH] support two point radial with r0 > 0.0 --- examples/scenes/src/test_scenes.rs | 13 +++++++++++++ shader/draw_leaf.wgsl | 14 +++++++++----- shader/fine.wgsl | 11 +++++------ shader/shared/ptcl.wgsl | 2 +- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/examples/scenes/src/test_scenes.rs b/examples/scenes/src/test_scenes.rs index 4da8959..9c95b3c 100644 --- a/examples/scenes/src/test_scenes.rs +++ b/examples/scenes/src/test_scenes.rs @@ -294,6 +294,19 @@ fn gradient_extend(sb: &mut SceneBuilder, params: &mut SceneParams) { label, ); } + let t = (params.time * 0.5).sin() * 0.5 + 0.5; + let x_delta: f64 = t * 2000.0 - 1000.0; + let gradient = + Gradient::new_two_point_radial((400.0, 500.0), 100.0, (101.0 + x_delta, 500.0), 200.0) + .with_extend(Extend::Reflect) + .with_stops([Color::GREEN, Color::WHITE, Color::RED]); + sb.fill( + Fill::NonZero, + Affine::translate((400.0, 800.0)) * Affine::scale(0.2), + &gradient, + None, + &Rect::new(0.0, 0.0, 2000.0, 2000.0), + ); } fn blend_grid(sb: &mut SceneBuilder, _: &mut SceneParams) { diff --git a/shader/draw_leaf.wgsl b/shader/draw_leaf.wgsl index b149d27..beced9c 100644 --- a/shader/draw_leaf.wgsl +++ b/shader/draw_leaf.wgsl @@ -153,13 +153,17 @@ fn main( let r1 = bitcast(scene[dd + 6u]); let inv_det = 1.0 / (matrx.x * matrx.w - matrx.y * matrx.z); let inv_mat = inv_det * vec4(matrx.w, -matrx.y, -matrx.z, matrx.x); + let rr = r1 / (r1 - r0); + var rr1 = rr; + if r0 > 0.0 { + p0 = p0 + (p0 - p1) * rr * 0.5; + rr1 = 1.0; + } let inv_tr = mat2x2(inv_mat.xy, inv_mat.zw) * -translate - p0; let center1 = p1 - p0; - let rr = r1 / (r1 - r0); - let ra_inv = rr / (r1 * r1 - dot(center1, center1)); + let ra_inv = rr1 / (r1 * r1 - dot(center1, center1)); let c1 = center1 * ra_inv; - let ra = rr * ra_inv; - let roff = rr - 1.0; + let ra = rr1 * ra_inv; info[di + 1u] = bitcast(inv_mat.x); info[di + 2u] = bitcast(inv_mat.y); info[di + 3u] = bitcast(inv_mat.z); @@ -169,7 +173,7 @@ fn main( info[di + 7u] = bitcast(c1.x); info[di + 8u] = bitcast(c1.y); info[di + 9u] = bitcast(ra); - info[di + 10u] = bitcast(roff); + info[di + 10u] = bitcast(rr); } // DRAWTAG_FILL_IMAGE case 0x248u: { diff --git a/shader/fine.wgsl b/shader/fine.wgsl index 42970e5..85ed7a4 100644 --- a/shader/fine.wgsl +++ b/shader/fine.wgsl @@ -295,18 +295,17 @@ fn main( // CMD_RAD_GRAD case 7u: { let rad = read_rad_grad(cmd_ix); + let rr = rad.rr; + let roff = rr - 1.0; for (var i = 0u; i < PIXELS_PER_THREAD; i += 1u) { let my_xy = vec2(xy.x + f32(i), xy.y); // TODO: can hoist y, but for now stick to the GLSL version let xy_xformed = rad.matrx.xy * my_xy.x + rad.matrx.zw * my_xy.y + rad.xlat; let ba = dot(xy_xformed, rad.c1); let ca = rad.ra * dot(xy_xformed, xy_xformed); - let t0 = sqrt(ba * ba + ca) - ba; - // For radial gradients that generate a cone, reject pixels outside - // the region. - if t0 >= 0.0 { - let t = t0 - rad.roff; - let x = i32(round(extend_mode(t, rad.extend_mode) * f32(GRADIENT_WIDTH - 1))); + let t = sqrt(ba * ba + ca) - ba; + if t >= 0.0 { + let x = i32(round(extend_mode(t * rr - roff, rad.extend_mode) * f32(GRADIENT_WIDTH - 1))); let fg_rgba = textureLoad(gradients, vec2(x, i32(rad.index)), 0); let fg_i = fg_rgba * area[i]; rgba[i] = rgba[i] * (1.0 - fg_i.a) + fg_i; diff --git a/shader/shared/ptcl.wgsl b/shader/shared/ptcl.wgsl index 8137f32..8e80524 100644 --- a/shader/shared/ptcl.wgsl +++ b/shader/shared/ptcl.wgsl @@ -57,7 +57,7 @@ struct CmdRadGrad { xlat: vec2, c1: vec2, ra: f32, - roff: f32, + rr: f32, } struct CmdImage {