anchor.diff:      _lastTimeMs = timeMs;
       orbit.azimuth += 0.001;
   
  -    if (programSprites.enabled && elapsed > 0.0) {
  -      int n = 0;
  -      for (Ion ion in ions) {
  -        ion.Update(srcPoles, dstPoles, rng, elapsed / 1000.0);
  -        vertices[n + 0] = ion.Pos().x;
  -        vertices[n + 1] = ion.Pos().y;
  -        vertices[n + 2] = ion.Pos().z;
  -        n += 3;
  -      }
  -      md.ChangeVertices(vertices);
  +    if (programJS.enabled && elapsed > 0.0) {
  +      RecomputeParticlePos(elapsed / 1000.0);
  +      md.ChangeVertices(particlePos);
       }
       orbit.animate(elapsed);
   
  
positive.code: const float kMinDistance = ${kMinDistance};
    
  const float dt = 0.1666;
  const float speed = 2.0;  
    
  const vec3 srcs[] = vec3[](vec3(6.0, 0.0, 6.0),
                             vec3(3.0, 0.0, 6.0),
  
negative.code:     Ion ion = new Ion(2.0, outOfBounds);
      ions.add(ion);
    }
  
    Float32List particlePos = new Float32List(3 * kIons);
    void RecomputeParticlePos(double t) {
      int n = 0;
      for (Ion ion in ions) {
        ion.Update(srcPoles, dstPoles, rng, t);
        particlePos[n + 0] = ion.Pos().x;
        particlePos[n + 1] = ion.Pos().y;
        particlePos[n + 2] = ion.Pos().z;
        n += 3;
      }
    }
  
    Material mat = new Material.Transparent("stars", BlendEquationMix)
      ..SetUniform(uTexture, Utils.createParticleTexture(chronosGL))
      ..SetUniform(uPointSize, 200.0);
    GeometryBuilder gb = new GeometryBuilder(true);
    for (var i = 0; i < kIons; i++) {
      gb.AddVertex(RandomVector(rng, kMaxDistance * 100.0));
    }
    MeshData md = GeometryBuilderToMeshData("", chronosGL, gb);
    RenderProgram programJS = phase.createProgram(createPointSpritesShader());
    programJS.add(new Node("ions1", md, mat));
  
    RenderProgram programGPU = phase.createProgram(createFireWorksShader());
    MeshData md2 = GeometryBuilderToMeshData("", chronosGL, gb);
    MeshData md1 = GeometryBuilderToMeshData("", chronosGL, gb);
  
    var transform = chronosGL.createTransformFeedback();
    chronosGL.bindTransformFeedback(transform);
    chronosGL.bindBufferBase(
        GL_TRANSFORM_FEEDBACK_BUFFER, 0, md2.GetBuffer(aVertexPosition));
    programGPU.add(new Node("ions2", md1, mat));
  
    chronosGL.bindTransformFeedback(transform);
    programJS.enabled = false;
    programGPU.enabled = true;
  
    double _lastTimeMs = 0.0;
    void animate(timeMs) {
  