Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There are currently 4 ways to do this: standard 1D textures, buffer textures, uniform buffers, and shader storage buffers.</p> <h2>1D Textures</h2> <p>With this method, you use <code>glTex(Sub)Image1D</code> to fill a 1D texture with your data. Since your data is just an array of floats, your <a href="http://www.opengl.org/wiki/Image_Format">image format</a> should be <code>GL_R32F</code>. You then access it in the shader with a simple <code>texelFetch</code> call. <code>texelFetch</code> takes texel coordinates (hence the name), and it shuts off all filtering. So you get exactly one texel.</p> <p>Note: <code>texelFetch</code> is 3.0+. If you want to use prior GL versions, you will need to pass the size to the shader and normalize the texture coordinate manually.</p> <p>The main advantages here are compatibility and compactness. This will work on GL 2.1 hardware (using the notation). And you don't <em>have</em> to use <code>GL_R32F</code> formats; you could use <code>GL_R16F</code> half-floats. Or <code>GL_R8</code> if your data is reasonable for a normalized byte. Size can mean a lot for overall performance.</p> <p>The main disadvantage is the size limitation. You are limited to having a 1D texture of the max texture size. On GL 3.x-class hardware, this will be around 8,192, but is guaranteed to be no less than 4,096.</p> <h2>Uniform Buffer Objects</h2> <p>The way this works is that you declare a uniform block in your shader:</p> <pre><code>layout(std140) uniform MyBlock { float myDataArray[size]; }; </code></pre> <p>You then access that data in the shader just like an array.</p> <p>Back in C/C++/etc code, you create a buffer object and fill it with floating-point data. Then, you can associate that buffer object with the <code>MyBlock</code> uniform block. <a href="http://www.opengl.org/wiki/Uniform_Buffer_Object">More details can be found here.</a></p> <p>The principle advantages of this technique are speed and semantics. Speed is due to how implementations treat uniform buffers compared to textures. Texture fetches are global memory accesses. Uniform buffer accesses are generally not; the uniform buffer data is usually loaded into the shader when the shader is initialized upon its use in rendering. From there, it is a local access, which is much faster.</p> <p>Semantically, this is better because it isn't just a flat array. For your specific needs, if all you need is a <code>float[]</code>, that doesn't matter. But if you have a more complex data structure, the semantics can be important. For example, consider an array of lights. Lights have a position and a color. If you use a texture, your code to get the position and color for a particular light looks like this:</p> <pre><code>vec4 position = texelFetch(myDataArray, 2*index); vec4 color = texelFetch(myDataArray, 2*index + 1); </code></pre> <p>With uniform buffers, it looks just like any other uniform access. You have named members that can be called <code>position</code> and <code>color</code>. So all the semantic information is there; it's easier to understand what's going on.</p> <p>There are size limitations for this as well. OpenGL requires that implementations provide at least 16,384 bytes for the maximum size of uniform blocks. Which means, for float arrays, you get only 4,096 elements. Note again that this is the <em>minimum</em> required from implementations; some hardware can offer much larger buffers. AMD provides 65,536 on their DX10-class hardware, for example.</p> <h2>Buffer Textures</h2> <p>These are kind of a "super 1D texture". They effectively allow you to <a href="http://www.opengl.org/wiki/Buffer_Texture">access a buffer object from a texture unit</a>. Though they are one-dimensional, they are not 1D textures.</p> <p>You can only use them from GL 3.0 or above. And you can only access them via the <code>texelFetch</code> function.</p> <p>The main advantage here is size. Buffer textures can generally be pretty gigantic. While the spec is generally conservative, mandating at least 65,536 bytes for buffer textures, most GL implementations allow them to range in the <b>mega</b>bytes in size. Indeed, usually the maximum size is limited by the GPU memory available, not hardware limits.</p> <p>Also, buffer textures are stored in buffer objects, not the more opaque texture objects like 1D textures. This means you can use some <a href="http://www.opengl.org/wiki/Buffer_Object_Streaming">buffer object streaming techniques</a> to update them.</p> <p>The main disadvantage here is performance, just like with 1D textures. Buffer textures probably won't be any slower than 1D textures, but they won't be as fast as UBOs either. If you're just pulling one float from them, it shouldn't be a concern. But if you're pulling lots of data from them, consider using a UBO instead.</p> <h2>Shader Storage Buffer Objects</h2> <p>OpenGL 4.3 provides another way to handle this: <a href="http://www.opengl.org/wiki/GLSL_Interface_Block#Buffer_backed">shader storage buffers</a>. They're a lot like uniform buffers; you specify them using syntax almost identical to that of uniform blocks. The principle difference is that you can write to them. Obviously that's not useful for your needs, but there are other differences.</p> <p>Shader storage buffers are, conceptually speaking, an alternate form of buffer texture. Thus, the size limits for shader storage buffers are a <em>lot</em> larger than for uniform buffers. The OpenGL minimum for the max UBO size is 16KB. The OpenGL minimum for the max SSBO size is <strong>16MB</strong>. So if you have the hardware, they're an interesting alternative to UBOs.</p> <p>Just be sure to declare them as <code>readonly</code>, since you're not writing to them.</p> <p>The potential disadvantage here is performance again, relative to UBOs. SSBOs work like an <a href="http://www.opengl.org/wiki/Image_Load_Store">image load/store operation</a> through buffer textures. Basically, it's (very nice) syntactic sugar around an <code>imageBuffer</code> image type. As such, reads from these will likely perform at the speed of reads from a <code>readonly imageBuffer</code>.</p> <p>Whether reading via image load/store through buffer images is faster or slower than buffer textures is unclear at this point.</p> <p>Another potential issue is that you must abide by the rules for <a href="http://www.opengl.org/wiki/Memory_Model#Incoherent_memory_access">non-synchronous memory access</a>. These are complex and can very easily trip you up.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload