run method

  1. @override
Vector4? run(
  1. Float32List v,
  2. ShaderBindings b,
  3. FragmentContext c
)
override

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);
}