code: function (name, data, opt) {
      var attribIdx = indexOfName(this.attributes, name)
      var attrib = attribIdx === -1 ? null : this.attributes[attribIdx]
      if (typeof data === 'undefined') { // getter
        return attrib
      }
  
      var gl = this.gl
      opt = opt || {}
  
      var array = unroll(data, fromGLType(opt.type) || 'float32')
      var size = opt.size || guessSize(data, 3)
      var buffer
      if (!attrib) { // create new attribute
        buffer = createBuffer(gl, array, gl.ARRAY_BUFFER, opt.usage)
        attrib = assign({
          name: name,
          size: size,
          usage: gl.STATIC_DRAW
        }, opt, { buffer: buffer })
        this.attributes.push(attrib)
      } else { // update existing
        buffer = attrib.buffer
        // mutate existing attribute info like stride/etc
        assign(attrib, opt, { buffer: buffer })
        buffer.usage = defined(opt.usage, buffer.usage)
        buffer.update(array)
      }
  
      this._dirty = true
      return this
    }
docs: replaces attribute