support two point radial with r0 > 0.0

This commit is contained in:
Chad Brokaw 2023-05-06 03:27:53 -04:00
parent 2db555145e
commit ced6309a3b
4 changed files with 28 additions and 12 deletions

View file

@ -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) {

View file

@ -153,13 +153,17 @@ fn main(
let r1 = bitcast<f32>(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<u32>(inv_mat.x);
info[di + 2u] = bitcast<u32>(inv_mat.y);
info[di + 3u] = bitcast<u32>(inv_mat.z);
@ -169,7 +173,7 @@ fn main(
info[di + 7u] = bitcast<u32>(c1.x);
info[di + 8u] = bitcast<u32>(c1.y);
info[di + 9u] = bitcast<u32>(ra);
info[di + 10u] = bitcast<u32>(roff);
info[di + 10u] = bitcast<u32>(rr);
}
// DRAWTAG_FILL_IMAGE
case 0x248u: {

View file

@ -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;

View file

@ -57,7 +57,7 @@ struct CmdRadGrad {
xlat: vec2<f32>,
c1: vec2<f32>,
ra: f32,
roff: f32,
rr: f32,
}
struct CmdImage {