run method
Returns linear RGBA for attachment zero. Null discards the fragment.
Implementation
@override
Vector4? run(Float32List v, ShaderBindings b, FragmentContext c) {
final power = -0.5 * (v[4] * v[4] + v[5] * v[5]);
// Cut off at three standard deviations, where the falloff is under a
// hundredth: a Gaussian never reaches zero, so without this the quad's own
// square edge shows and the cloud reads as a field of faint rectangles.
if (power < -4.5) return null;
final alpha = v[3] * math.exp(power);
if (alpha < 1.0 / 255.0) return null;
var r = v[0];
var g = v[1];
var bl = v[2];
final fog = b.vec4('FogInfo', 'fog', Vector4.zero());
if (fog.w > 0.0) {
final d = fogDistance(b, v[6], v[7], v[8]);
final visibility = math.exp(-fog.w * d).clamp(0.0, 1.0);
// A mix rather than an attenuation, which is the opposite of the particle
// stage and for the opposite reason: this is blended, so a splat that
// faded toward black would put black into the wall behind it.
r = fog.x + (r - fog.x) * visibility;
g = fog.y + (g - fog.y) * visibility;
bl = fog.z + (bl - fog.z) * visibility;
}
// Premultiplied, for the blend state this draws under.
return Vector4(r * alpha, g * alpha, bl * alpha, alpha);
}