mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-22 09:26:33 +11:00
Address review feedback
* replace one_minus_focal_x and abs_one_minus_focal_x variables with the actual expressions * replace division by r^2-1 with multiplication by reciprocal * revert chain selects to branchy code for clarity. Branching is dynamically uniform so shouldn't affect performance * add suggested comment describing gradient kind/flags constants
This commit is contained in:
parent
5e1188f968
commit
58c7df469d
3 changed files with 42 additions and 94 deletions
|
@ -184,9 +184,7 @@ fn main(
|
||||||
r1 = tmp_r;
|
r1 = tmp_r;
|
||||||
}
|
}
|
||||||
focal_x = r0 / (r0 - r1);
|
focal_x = r0 / (r0 - r1);
|
||||||
let one_minus_focal_x = 1.0 - focal_x;
|
let cf = (1.0 - focal_x) * p0 + focal_x * p1;
|
||||||
let cf = one_minus_focal_x * p0 + focal_x * p1;
|
|
||||||
let abs_one_minus_focal_x = abs(one_minus_focal_x);
|
|
||||||
radius = r1 / (distance(cf, p1));
|
radius = r1 / (distance(cf, p1));
|
||||||
let user_to_unit_line = transform_mul(
|
let user_to_unit_line = transform_mul(
|
||||||
two_point_to_unit_line(cf, p1),
|
two_point_to_unit_line(cf, p1),
|
||||||
|
@ -196,15 +194,16 @@ fn main(
|
||||||
// When r == 1.0, focal point is on circle
|
// When r == 1.0, focal point is on circle
|
||||||
if abs(radius - 1.0) <= GRADIENT_EPSILON {
|
if abs(radius - 1.0) <= GRADIENT_EPSILON {
|
||||||
kind = RAD_GRAD_KIND_FOCAL_ON_CIRCLE;
|
kind = RAD_GRAD_KIND_FOCAL_ON_CIRCLE;
|
||||||
let scale = 0.5 * abs_one_minus_focal_x;
|
let scale = 0.5 * abs(1.0 - focal_x);
|
||||||
user_to_scaled = transform_mul(
|
user_to_scaled = transform_mul(
|
||||||
Transform(vec4(scale, 0.0, 0.0, scale), vec2(0.0)),
|
Transform(vec4(scale, 0.0, 0.0, scale), vec2(0.0)),
|
||||||
user_to_unit_line
|
user_to_unit_line
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let a = radius * radius - 1.0;
|
let a = radius * radius - 1.0;
|
||||||
let scale_x = radius / a * abs_one_minus_focal_x;
|
let a_recip = 1.0 / a;
|
||||||
let scale_y = sqrt(abs(a)) / a * abs_one_minus_focal_x;
|
let scale_x = radius * a_recip * abs(1.0 - focal_x);
|
||||||
|
let scale_y = sqrt(abs(a)) * a_recip * abs(1.0 - focal_x);
|
||||||
user_to_scaled = transform_mul(
|
user_to_scaled = transform_mul(
|
||||||
Transform(vec4(scale_x, 0.0, 0.0, scale_y), vec2(0.0)),
|
Transform(vec4(scale_x, 0.0, 0.0, scale_y), vec2(0.0)),
|
||||||
user_to_unit_line
|
user_to_unit_line
|
||||||
|
|
121
shader/fine.wgsl
121
shader/fine.wgsl
|
@ -118,30 +118,20 @@ fn extend_mode(t: f32, mode: u32) -> f32 {
|
||||||
let EXTEND_PAD = 0u;
|
let EXTEND_PAD = 0u;
|
||||||
let EXTEND_REPEAT = 1u;
|
let EXTEND_REPEAT = 1u;
|
||||||
let EXTEND_REFLECT = 2u;
|
let EXTEND_REFLECT = 2u;
|
||||||
// Branching version of the code below:
|
switch mode {
|
||||||
//
|
// EXTEND_PAD
|
||||||
// switch mode {
|
case 0u: {
|
||||||
// // EXTEND_PAD
|
return clamp(t, 0.0, 1.0);
|
||||||
// case 0u: {
|
}
|
||||||
// return clamp(t, 0.0, 1.0);
|
// EXTEND_REPEAT
|
||||||
// }
|
case 1u: {
|
||||||
// // EXTEND_REPEAT
|
return fract(t);
|
||||||
// case 1u: {
|
}
|
||||||
// return fract(t);
|
// EXTEND_REFLECT
|
||||||
// }
|
default: {
|
||||||
// // EXTEND_REFLECT
|
return abs(t - 2.0 * round(0.5 * t));
|
||||||
// default: {
|
}
|
||||||
// return abs(t - 2.0 * round(0.5 * t));
|
}
|
||||||
// }
|
|
||||||
// }
|
|
||||||
let pad = clamp(t, 0.0, 1.0);
|
|
||||||
let repeat = fract(t);
|
|
||||||
let reflect = abs(t - 2.0 * round(0.5 * t));
|
|
||||||
return select(
|
|
||||||
select(pad, repeat, mode == EXTEND_REPEAT),
|
|
||||||
reflect,
|
|
||||||
mode == EXTEND_REFLECT
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -309,16 +299,14 @@ fn main(
|
||||||
case 7u: {
|
case 7u: {
|
||||||
let rad = read_rad_grad(cmd_ix);
|
let rad = read_rad_grad(cmd_ix);
|
||||||
let focal_x = rad.focal_x;
|
let focal_x = rad.focal_x;
|
||||||
let one_minus_focal_x = 1.0 - focal_x;
|
|
||||||
let radius = rad.radius;
|
let radius = rad.radius;
|
||||||
let is_strip = rad.kind == RAD_GRAD_KIND_STRIP;
|
let is_strip = rad.kind == RAD_GRAD_KIND_STRIP;
|
||||||
let is_circular = rad.kind == RAD_GRAD_KIND_CIRCULAR;
|
let is_circular = rad.kind == RAD_GRAD_KIND_CIRCULAR;
|
||||||
let is_focal_on_circle = rad.kind == RAD_GRAD_KIND_FOCAL_ON_CIRCLE;
|
let is_focal_on_circle = rad.kind == RAD_GRAD_KIND_FOCAL_ON_CIRCLE;
|
||||||
let is_swapped = (rad.flags & RAD_GRAD_SWAPPED) != 0u;
|
let is_swapped = (rad.flags & RAD_GRAD_SWAPPED) != 0u;
|
||||||
let is_greater = radius > 1.0;
|
let r1_recip = select(1.0 / radius, 0.0, is_circular);
|
||||||
let inv_r1 = select(1.0 / radius, 0.0, is_circular);
|
let less_scale = select(1.0, -1.0, is_swapped || (1.0 - focal_x) < 0.0);
|
||||||
let less_scale = select(1.0, -1.0, is_swapped || one_minus_focal_x < 0.0);
|
let t_sign = sign(1.0 - focal_x);
|
||||||
let t_sign = sign(one_minus_focal_x);
|
|
||||||
for (var i = 0u; i < PIXELS_PER_THREAD; i += 1u) {
|
for (var i = 0u; i < PIXELS_PER_THREAD; i += 1u) {
|
||||||
let my_xy = vec2(xy.x + f32(i), xy.y);
|
let my_xy = vec2(xy.x + f32(i), xy.y);
|
||||||
let local_xy = rad.matrx.xy * my_xy.x + rad.matrx.zw * my_xy.y + rad.xlat;
|
let local_xy = rad.matrx.xy * my_xy.x + rad.matrx.zw * my_xy.y + rad.xlat;
|
||||||
|
@ -326,65 +314,22 @@ fn main(
|
||||||
let y = local_xy.y;
|
let y = local_xy.y;
|
||||||
let xx = x * x;
|
let xx = x * x;
|
||||||
let yy = y * y;
|
let yy = y * y;
|
||||||
let x_inv_r1 = x * inv_r1;
|
var t = 0.0;
|
||||||
// This is the branching version of the code implemented
|
var is_valid = true;
|
||||||
// by the chained selects below:
|
if is_strip {
|
||||||
//
|
let a = radius - yy;
|
||||||
// var t = 0.0;
|
t = sqrt(a) + x;
|
||||||
// var is_valid = true;
|
is_valid = a >= 0.0;
|
||||||
// if is_strip {
|
} else if is_focal_on_circle {
|
||||||
// let a = radius - yy;
|
t = (xx + yy) / x;
|
||||||
// t = sqrt(a) + x;
|
is_valid = t >= 0.0 && x != 0.0;
|
||||||
// is_valid = a >= 0.0;
|
} else if radius > 1.0 {
|
||||||
// } else if is_focal_on_circle {
|
t = sqrt(xx + yy) - x * r1_recip;
|
||||||
// t = (xx + yy) / x;
|
} else { // radius < 1.0
|
||||||
// is_valid = t >= 0.0;
|
let a = xx - yy;
|
||||||
// } else if radius > 1.0 {
|
t = less_scale * sqrt(a) - x * r1_recip;
|
||||||
// t = sqrt(xx + yy) - x_inv_r1;
|
is_valid = a >= 0.0 && t >= 0.0;
|
||||||
// } else {
|
}
|
||||||
// let a = xx - yy;
|
|
||||||
// t = root_f * sqrt(a) - x_inv_r1;
|
|
||||||
// is_valid = a >= 0.0 && t >= 0.0;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// The pattern is that these can all be computed with
|
|
||||||
// the expression: a * sqrt(b) + c
|
|
||||||
//
|
|
||||||
// The parameters to the expression are computed up front
|
|
||||||
// and chosen with chained selects based on their
|
|
||||||
// respective conditions. The same process is done
|
|
||||||
// for determining the validity of the resulting value.
|
|
||||||
var strip_params = vec3(1.0, radius - yy, x);
|
|
||||||
var foc_params = vec3(1.0, 0.0, (xx + yy) / x);
|
|
||||||
var greater_params = vec3(1.0, xx + yy, -x_inv_r1);
|
|
||||||
var less_params = vec3(less_scale, xx - yy, -x_inv_r1);
|
|
||||||
var params = select(
|
|
||||||
select(
|
|
||||||
select(
|
|
||||||
less_params,
|
|
||||||
greater_params,
|
|
||||||
is_greater,
|
|
||||||
),
|
|
||||||
foc_params,
|
|
||||||
is_focal_on_circle,
|
|
||||||
),
|
|
||||||
strip_params,
|
|
||||||
is_strip,
|
|
||||||
);
|
|
||||||
var t = params.x * sqrt(params.y) + params.z;
|
|
||||||
let is_valid = select(
|
|
||||||
select(
|
|
||||||
select(
|
|
||||||
params.y >= 0.0 && t >= 0.0,
|
|
||||||
true,
|
|
||||||
is_greater
|
|
||||||
),
|
|
||||||
t >= 0.0 && x != 0.0,
|
|
||||||
is_focal_on_circle,
|
|
||||||
),
|
|
||||||
params.y >= 0.0,
|
|
||||||
is_strip,
|
|
||||||
);
|
|
||||||
if is_valid {
|
if is_valid {
|
||||||
t = extend_mode(focal_x + t_sign * t, rad.extend_mode);
|
t = extend_mode(focal_x + t_sign * t, rad.extend_mode);
|
||||||
t = select(t, 1.0 - t, is_swapped);
|
t = select(t, 1.0 - t, is_swapped);
|
||||||
|
|
|
@ -50,6 +50,10 @@ let N_TILE = 256u;
|
||||||
|
|
||||||
let BLEND_STACK_SPLIT = 4u;
|
let BLEND_STACK_SPLIT = 4u;
|
||||||
|
|
||||||
|
// The following are computed in draw_leaf from the generic gradient parameters
|
||||||
|
// encoded in the scene, and stored in the gradient's info struct, for
|
||||||
|
// consumption during fine rasterization.
|
||||||
|
|
||||||
// Radial gradient kinds
|
// Radial gradient kinds
|
||||||
let RAD_GRAD_KIND_CIRCULAR = 1u;
|
let RAD_GRAD_KIND_CIRCULAR = 1u;
|
||||||
let RAD_GRAD_KIND_STRIP = 2u;
|
let RAD_GRAD_KIND_STRIP = 2u;
|
||||||
|
|
Loading…
Add table
Reference in a new issue