run method
Returns linear RGBA for attachment zero. Null discards the fragment.
Implementation
@override
Vector4? run(Float32List v, ShaderBindings b, FragmentContext c) {
final length = math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
final scale = length > 0.0 ? 1.0 / length : 0.0;
final dx = v[0] * scale;
final dy = v[1] * scale;
final dz = v[2] * scale;
// The preset, off the varyings rather than out of a uniform block — see
// [SkyVertexShader].
final zenith = Vector4(v[3], v[4], v[5], v[6]);
final horizon = Vector4(v[7], v[8], v[9], v[10]);
final nadir = Vector4(v[11], v[12], v[13], v[14]);
final sun = Vector4(v[15], v[16], v[17], v[18]);
final glow = Vector4(v[19], v[20], v[21], v[22]);
final disc = Vector4(v[23], v[24], v[25], v[26]);
final height = dy.clamp(-1.0, 1.0);
final far = height >= 0.0 ? zenith : nadir;
final magnitude = height.abs();
final t = magnitude * magnitude * (3.0 - 2.0 * magnitude);
var r = horizon.x + (far.x - horizon.x) * t;
var g = horizon.y + (far.y - horizon.y) * t;
var bl = horizon.z + (far.z - horizon.z) * t;
final towards = dx * sun.x + dy * sun.y + dz * sun.z;
if (towards > 0.0) {
final lobe = glow.w * math.pow(towards, sun.w).toDouble();
r += glow.x * lobe;
g += glow.y * lobe;
bl += glow.z * lobe;
}
// `disc.y` is the width of the soft edge, not the outer cosine: see the
// renderer, which writes it that way because a varying cannot carry two
// cosines this close together.
// A soft edge of nothing is a hard edge, not an absent sun — see the same
// branch in `sky.frag`, which had the same hole.
final edge =
(disc.y > 0.0
? smoothstep(disc.x - disc.y, disc.x, towards)
: (towards >= disc.x ? 1.0 : 0.0)) *
disc.z;
r += glow.x * edge;
g += glow.y * edge;
bl += glow.z * edge;
// **The surface is left alone, and that is a transcription of a fix.** The
// GLSL this mirrors used to declare a second output and write zero into it;
// on Impeller, in the usual single-attachment pass, that killed the
// process. Nothing is lost either way — the attachment is cleared to zero,
// which is the value this was writing — and the two backends have to say
// the same thing or the transcription stops being one.
return Vector4(r, g, bl, 1.0);
}