<p>Let's review what the specification says about <code>std140</code> layout of arrays:</p>

<blockquote>
  <p>If the member is an array of scalars or vectors, the base alignment and array stride are set to match the base alignment of a single array element, according to rules (1), (2), and (3), and <strong>rounded up to the base alignment of a <code>vec4</code></strong>. The array may have padding at the end; the base offset of the member following the array is <strong>rounded up to the next multiple of the base alignment</strong>.</p>
</blockquote>

<p>Emphasis added.</p>

<p>So, if you have an array of <code>float</code>, the array stride shall be the same as the base alignment of a <code>vec4</code>. Also, each array will be padded at the end to the base alignment of a <code>vec4</code>. Yes, a <code>float[]</code> takes up the same room as a <code>vec4[]</code> of the same size.</p>

<p>Welcome to the wonderful world of <code>std140</code> layout.</p>

<p>If you want to have a real array of floats in a UBO... well, it's best to <em>avoid</em> wanting that. But if you have absolutely no other choice, then I suggest making it an array of <code>vec4</code>. Obviously, the size of this array will be the size you actually want, divided by 4 and rounded up:</p>

<pre><code>const int samples = 31;
const int arraySize = ((samples + 3) / 4);
</code></pre>

<p>To fetch a single float from this array, use math:</p>

<pre><code>arrayOfVec4[index / 4][index % 4]
</code></pre>

<p>Note that OpenGL ES 3.0 does allow non-constant array indexing of <code>vec</code> and <code>mat</code> types. It also allows the integer operations needed to pull this off.</p>

CC BY-SA 3.0
2017-01-02T23:58:42.610Z
Thank you @Nicol_Bolas. Now it's clear (and I will use a standard uniform to pass my data to the shader). I will delete my other post on stack overflow, but can you remove the down vote, please? Thank you again.
Fabrizio Duroni
CC BY-SA 3.0
2017-01-03T00:11:04.987Z
@FabrizioDuroni a number of people have viewed this post. We don't know who the downvoter was.
trichoplax is on Codidact now
CC BY-SA 3.0
2017-01-02T23:50:23.747Z
2017-01-02T23:59:41.573Z
2017-01-02T23:59:41.573Z
Nicol Bolas
<p>I'm trying to load an array of float to a fragment shader using a uniform buffer object, but it doesn't work.
In the fragment shader I declared the following uniform block:</p>

<pre><code>/// Spectrum samples.
const int samples = 31;

layout(std140) uniform SpectralDataBlock {

    float illuminant[samples];
    float object[samples];
};
</code></pre>

<p>Then on client side in my C++ code:</p>

<pre><code>float illuminant[31] = {
    82.754900,91.486000,93.431800,86.682300,104.865000,117.008000,117.812000,114.861000,115.923000,108.811000,109.354000,
    107.802000,104.790000,107.689000,104.405000,104.046000,100.000000,96.334200,95.788000,88.685600,90.006200,89.599100,
    87.698700,83.288600,83.699200,80.026800,80.214600,82.277800,78.284200,69.721300,71.609100
};

float object[31] = {
    0.051, 0.05, 0.049, 0.049, 0.049, 0.049, 0.048, 0.047, 0.045, 0.044,
    0.044, 0.044, 0.044, 0.044, 0.045, 0.047, 0.05, 0.057, 0.072, 0.109,
    0.192, 0.332, 0.486, 0.598, 0.654, 0.686, 0.7, 0.707, 0.718, 0.724,
    0.729
};

std::copy(illuminant, illuminant + 31, spectralData);
std::copy(object, object + 31, spectralData + 31);

blockId = glGetUniformBlockIndex(program, "SpectralDataBlock");
glUniformBlockBinding(program, blockId, bindingPoint);
glGetActiveUniformBlockiv(program, blockId, GL_UNIFORM_BLOCK_DATA_SIZE, &amp;blockSize);

glGenBuffers(1, &amp;bufferId);
glBindBuffer(GL_UNIFORM_BUFFER, bufferId);
glBufferData(GL_UNIFORM_BUFFER, blockSize, spectralData, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, bindingPoint, bufferId);
</code></pre>

<p>Unfortunately, the data doesn't get correctly loaded. </p>

<p>Are there any limitation in OpenGL ES the prevent to use float[] in an uniform buffer object? Are there any error in my code above?</p>

CC BY-SA 3.0
2017-01-02T23:30:19.500Z
Could you let us know what you mean by "doesn't get correctly loaded"? What specifically goes wrong that indicates this?
trichoplax is on Codidact now
CC BY-SA 3.0
2017-01-02T23:33:45.547Z
Hi @trichoplax, the problem is that the array doesn't contain any data. I'm sure of this because the data I'm trying to load is used to calculate the colours of objects using tristimulus values, but the object is always black. In fact, if I tested now that if I try to pass an array of 4 values and the block in the shader contains for example a single variable of type vec4, the code above works. Thanks.
Fabrizio Duroni
<opengl-es><uniform-buffer-object>
OpenGL ES 3 - Uniform buffer object with float array
Fabrizio Duroni
# OpenGL ES 3 - Uniform buffer object with float array

(Asked by: username_0 on 2017-01-02)

I'm trying to load an array of float to a fragment shader using a uniform buffer object, but it doesn't work.
In the fragment shader I declared the following uniform block:

```
/// Spectrum samples.
const int samples = 31;

layout(std140) uniform SpectralDataBlock {

    float illuminant[samples];
    float object[samples];
};

```

Then on client side in my C++ code:

```
float illuminant[31] = {
    82.754900,91.486000,93.431800,86.682300,104.865000,117.008000,117.812000,114.861000,115.923000,108.811000,109.354000,
    107.802000,104.790000,107.689000,104.405000,104.046000,100.000000,96.334200,95.788000,88.685600,90.006200,89.599100,
    87.698700,83.288600,83.699200,80.026800,80.214600,82.277800,78.284200,69.721300,71.609100
};

float object[31] = {
    0.051, 0.05, 0.049, 0.049, 0.049, 0.049, 0.048, 0.047, 0.045, 0.044,
    0.044, 0.044, 0.044, 0.044, 0.045, 0.047, 0.05, 0.057, 0.072, 0.109,
    0.192, 0.332, 0.486, 0.598, 0.654, 0.686, 0.7, 0.707, 0.718, 0.724,
    0.729
};

std::copy(illuminant, illuminant + 31, spectralData);
std::copy(object, object + 31, spectralData + 31);

blockId = glGetUniformBlockIndex(program, "SpectralDataBlock");
glUniformBlockBinding(program, blockId, bindingPoint);
glGetActiveUniformBlockiv(program, blockId, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize);

glGenBuffers(1, &bufferId);
glBindBuffer(GL_UNIFORM_BUFFER, bufferId);
glBufferData(GL_UNIFORM_BUFFER, blockSize, spectralData, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, bindingPoint, bufferId);

```

Unfortunately, the data doesn't get correctly loaded.

Are there any limitation in OpenGL ES the prevent to use float[] in an uniform buffer object? Are there any error in my code above?

**Tags:** opengl-es, uniform-buffer-object

> **Comments:**
> **username_1**: Could you let us know what you mean by "doesn't get correctly loaded"? What specifically goes wrong that indicates this?  
> **username_0**: Hi @username_1, the problem is that the array doesn't contain any data. I'm sure of this because the data I'm trying to load is used to calculate the colours of objects using tristimulus values, but the object is always black. In fact, if I tested now that if I try to pass an array of 4 values and the block in the shader contains for example a single variable of type vec4, the code above works. Thanks.  

---

## 1 answers

### Answer by username_2 on 2017-01-02. Score: 5 | Accepted answer

Let's review what the specification says about `std140` layout of arrays:

> If the member is an array of scalars or vectors, the base alignment and array stride are set to match the base alignment of a single array element, according to rules (1), (2), and (3), and **rounded up to the base alignment of a `vec4`**. The array may have padding at the end; the base offset of the member following the array is **rounded up to the next multiple of the base alignment**.

Emphasis added.

So, if you have an array of `float`, the array stride shall be the same as the base alignment of a `vec4`. Also, each array will be padded at the end to the base alignment of a `vec4`. Yes, a `float[]` takes up the same room as a `vec4[]` of the same size.

Welcome to the wonderful world of `std140` layout.

If you want to have a real array of floats in a UBO... well, it's best to *avoid* wanting that. But if you have absolutely no other choice, then I suggest making it an array of `vec4`. Obviously, the size of this array will be the size you actually want, divided by 4 and rounded up:

```
const int samples = 31;
const int arraySize = ((samples + 3) / 4);

```

To fetch a single float from this array, use math:

```
arrayOfVec4[index / 4][index % 4]

```

Note that OpenGL ES 3.0 does allow non-constant array indexing of `vec` and `mat` types. It also allows the integer operations needed to pull this off.

> **Comments:**
> **username_0**: Thank you @username_2. Now it's clear (and I will use a standard uniform to pass my data to the shader). I will delete my other post on stack overflow, but can you remove the down vote, please? Thank you again.  
> **username_1**: @username_0 a number of people have viewed this post. We don't know who the downvoter was.  

---

