run method
Returns linear RGBA for attachment zero. Null discards the fragment.
Implementation
@override
Vector4? run(Float32List v, ShaderBindings b, FragmentContext c) {
// `texture()` picks its level from the screen derivatives, so the sprite
// is read through its chain here too, from the footprint of varyings four
// and five the way `ParticleTexturedShader` reads it for colour.
final sprite = b.textures['sprite_texture'];
final ddx = c.ddx;
final ddy = c.ddy;
final (du, dv) = ddx != null && ddy != null
? (
math.max(ddx[4].abs(), ddy[4].abs()),
math.max(ddx[5].abs(), ddy[5].abs()),
)
: (0.0, 0.0);
final spriteAlpha = sprite?.sample(v[4], v[5], du: du, dv: dv).w ?? 1.0;
final cx = v[4] * 2.0 - 1.0;
final cy = v[5] * 2.0 - 1.0;
final falloff = 1.0 - smoothstep(0.0, 1.0, math.sqrt(cx * cx + cy * cy));
final disc = falloff * falloff;
final power = -0.5 * (v[4] * v[4] + v[5] * v[5]);
final gaussian = power < -4.5 ? 0.0 : math.exp(power);
final params = b.vec4(_block, 'params', Vector4.zero());
final shape = params.y;
final coverage =
v[3] *
(shape < 0.5
? disc
: shape < 1.5
? gaussian
: spriteAlpha);
final eye = b.vec4(_block, 'eye', Vector4.zero());
final forward = b.vec4(_block, 'forward', Vector4.zero());
final depth =
(v[6] - eye.x) * forward.x +
(v[7] - eye.y) * forward.y +
(v[8] - eye.z) * forward.z;
final reactive = params.x * coverage;
if (_hidden(b, c, depth) || reactive <= 0.0) return null;
return Vector4(0.0, 0.0, reactive, 0.0);
}