openglglslwebglshader

Sending GL Uniforms: Multiple floats vs packing into vector


Say I have four floating point values I want to send to a shader, which of the following is the optimal way to send them.

Sending them as individual floats:

uniform float uniformValue1;
uniform float uniformValue2;
uniform float uniformValue3;
uniform float uniformValue4;

void main()
{
    //do shader stuff here
}

Packing them into a single vector:

uniform vec4 uniformValues;

void main()
{
    //do shader stuff here
}

I came across this document: https://www.khronos.org/webgl/public-mailing-list/archives/1003/pdf7z773meQcF.pdf

Which talks about this subject one thing I'm wondering: does OpenGL/OpenGLES/WebGL automatically pack uniforms or is it something I should take care of myself?


Solution

  • There are multiple ways to send uniform variables to the GPU. The less API calls you have the better, this will make fewer state changes in your application, and copying data will be less frequent for bigger blocks, rather than smaller ones more frequently. It's also easier to manage less number of uniform variables; so use a vector, it's a win-win situation.

    If you are using newer OpenGL versions 3.2+, there are also other ways to copy uniforms: to GPU, when you have larger number of uniforms.

    For example, use Uniform blocks, if you have a large block of uniform variables that will be used in multiple shaders, and you are not going to write on them. Uniform blocks will also reduce the number of copy operations if you are using multiple shaders, you can copy once and use them multiple times.

    On the other hand use shader storage block (available in OpenGL 4.3+) if your application is going write on them.