title: Float32Array not updating ArrayBuffer to reflect assigned values when interacting with WebGL (Chrome)
body: <p>In order to manually pack and bind an RGBA float component texture to the GPU using WebGL in chrome using the <b>OES_texture_float</b> extension, pixel component data must be stored in a Float32Array.</p>
  
  <p>For example, for a simple 3 pixel texture, with 4 float components each, a plain JS array would first be declared:</p>
  
  <pre><code>var pixels = [1.01, 1.02, 1.03, 1.04, 2.01, 2.02, 2.03, 2.04, 3.01, 3.02, 3.03];
  </code></pre>
  
  <p>Then to convert the plain JS array to a strongly typed array of floats which can be fed to the GPU, we simply use the Float32Array constructor which can take a plain JS array of numbers as input:</p>
  
  <pre><code>pixels = new Float32Array(pixels);
  </code></pre>
  
  <p>Now that we have our texture represented as a strongly typed array of floats, we can feed it to the GPU using an already established WebGL context (which is working and beyond the scope of this question), using texImage2D:</p>
  
  <pre><code>gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 3, 1, 0, gl.RGBA, gl.FLOAT, pixels);
  </code></pre>
  
  <p>Making the appropriate render calls shows that these floats are being passed into, and back out of (by encoding an output float into the fragment color) the GPU without error (albeit a slight loss of precision due to conversions).</p>
  
  <p><b>The Problem</b></p>
  
  <p>Converting from a plain JS array to a Float32Array is actually a pretty expensive operation, and it's far quicker to manipulate already converted floats in the Float32Array - an operation that seems to be supported according to most JS specs floating around: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Float32Array" rel="nofollow">https://developer.mozilla.org/en-US/docs/Web/API/Float32Array</a></p>
  
  <blockquote>
    <p>Once established, you can reference elements in the array using the object's methods, or using standard array index syntax (that is, using bracket notation).</p>
  </blockquote>
  
  <p>The problem occurs when:</p>
  
  <p>a Float32Array is created with a plain JS array of preset values</p>
  
  <p>we change one or many values in the Float32Array using [] notation, ie:</p>
  
  <pre><code>pixels[0] = 420.4;
  pixels[1] = 420.4;
  </code></pre>
  
  <p>we pass the Float32Array to the GPU using texImage2D, and using the same method mentioned above shows that the inititally set values to the Float32Array somehow made it to the GPU without the two values changed to 420.4</p>
  
  <p><b>WTF?</b></p>
  
  <p>My best guess is that because strongly typed arrays are (usually) internally represented as a buffer and a view, that I'm updating the view, and the buffer is not reflecting the changes.  Logging the Float32Array to the browser console shows that the two changed numbers in this case appear to indeed be changed.  However because the contents of an ArrayBuffer can't be read through the console in Chrome, it's a debugging dead end as far as my skillset goes.</p>
  
  <p>Trying the same create, convert, update and check methodology (without the GPU involved) using a NodeJS REPL, reveals that the buffer values are updated during the evaluation of <code>pixels[0] = 420.4;</code> and are not updated in a 'lazy' fashion when the buffer is read.</p>
  
  <p>It may be possible that Chrome is lazy updating underlying buffers, but copying that data to the GPU does not trigger the getter but rather copies it raw from memory.</p>
  
  <p><b>Temporary Solution</b></p>
  
  <p>Until the underlying problem is found and remedied (if even applicable), it would seem that Float32Arrays are essentially immutable (cannot be changed) once created in the context of WebGL textures.  There also appears to be a <code>.set()</code> method attached to typed arrays, but this:</p>
  
  <pre><code> pixels.set(new Float32Array([420.4]), index);
  </code></pre>
  
  <p>Seems like a lot of external boxing/conversion to get around a lazy buffer, especially one that claims to allow [] access.</p>