PDA

View Full Version : uniform shader



Zamfiry
08-07-2017, 10:38 AM
Hi,

I'm very new to OpenGL and I've only tried some very basic shader programs (like calculating dynamic lighting and basic shadows).
However, I'm very ambitious about the GLSL language and the functionality it offers.

I recently started wondering about something I see also people on other forums are asking and if you can excuse me if I'm raising an old discussion that's been already talked about million times but I couldn't find any proper answer, so here it goes:

Whenever there's an uniform calculation in a GLSL shader it seems like a waste of GPU cycles to make the same calculation over and over again when the result will be the same.
For example:

//vertex shader
uniform mat4 ModelMat;
uniform mat4 ViewMat;
uniform mat4 ProjectionMat;

in vec4 v_Position;

void main()
{
gl_Position = ProjectionMat * ViewMat * ModelMat * v_Position;
}


The result of ProjectionMat * ViewMat * ModelMat is an uniform since it doesn't change per vertex (as long as the other uniforms stay unchanged).

I know that the compiler may be able to optimize this operation so it happens once for all vertex shader executions.
But as far as I know the OpenGL standard doesn't state any such optimization, so it's up to the compiler developers to make it work.

Also, a dynamically-uniform operation can be more subtle, in a way that it's hard for the compiler to determine if the result will be uniform or not.

Some may simply suggest that if the user is aware that a result of an operation is uniform, then just do the calculation outside of the shader and pass it as an uniform value for the shader to use.
But this means that a purely shader-related code must be exposed to the outside world simply for optimization purposes.
Not to mention that maybe the GPU can do the calculations faster than the CPU.

So, my suggestion/question is:
Why not have a "uniform shader" program where only uniform operations are handled?
Operations of the following kind: uniform = function(other_uniforms); //example: u1 = u2+u3;
This uniform shader will be executed only once per glDraw*() operation before the other shaders.
It's like a preparation phase before the actual vertex and fragment processing.
Also, the shader can be optimized not to be executed at all if the uniforms inside it didn't change from last time it was called.

This way the uniform operations optimization will be done explicitly by the user and not relaying on the compiler to do it.

It is probably a stupid suggestion with thousands of reasons not to implement it but I'm really trying to understand the whole philosophy behind OpenGL and if such thing is possible and will it make a difference.