Does GLSL really do unnecessary calculations with uniform (rather than vertex) values?

For example, if I use a vertex shader as follows:

#version 400 core uniform mat4 projM; uniform mat4 viewM; uniform mat4 modelM; in vec4 in_Position; out vec4 pass_position_model; void main(void) { gl_Position = projM * viewM * modelM * in_Position; pass_position_model = modelM * in_Position; } 

Will matrix multiplication projM * viewM * modelM for each vertex, or is it smart enough to calculate if it is not recalculated once until uniform variables are changed? If this is not "reasonably reasonable", is there a way to optimize it, besides calculating all the equivalent values ​​on the processor and sending them as homogeneous variables to the GPU?

I'm also interested in solutions that can be ported to OpenGL ES 2.0 later without any problems.

+7
source share
4 answers

So, as I understand it, there is no answer. However, I did some tests on my hardware. I have 2 GPUs in my inventory, Intel HD Graphics 3000 and NVidia GeForce GT 555M . I tested my program (the program itself is written in java / scala) with matrix multiplication in the vertex shader, and then transferred the multiplication to the CPU program and checked again.

(ball N is a continuously rotating sphere with 2 * N ^ 2 quads drawn using glDrawElements (GL_QUADS, ...) with 1 texture and without any lighting effects / other effects)

matrix multiplication in the vertex shader:

 intel: sphere400: 57.17552887364208 fps sphere40: 128.1394156842645 fps nvidia: sphere400: 134.9527665317139 fps sphere40: 242.0135527589545 fps 

matrix multiplication by cpu:

 intel: sphere400: 57.37234652897303 fps sphere40: 128.2051282051282 fps nvidia: sphere400: 142.28799089356858 fps sphere40: 247.1576866040534 fps 

Tests show that multiplicative (uniform) matrices in the vertex shader are a bad idea, at least on this hardware. Therefore, you can’t generally rely on appropriate GLSL compiler optimizations.

+10
source

Will projM * viewM * modelM do matrix multiplication for each vertex, or is it smart enough to calculate, if not counted once, until uniform variables are changed?

Ask an OpenGL developer developer. The OpenGL specification has nothing to say about this, but the compilers and GLSL drivers may have implemented optimization for this.

If this is not "reasonably reasonable", is there any other way to optimize it than to calculate all the equivalent values ​​on the processor and send them as single variables to the GPU?

Not. You must do your work yourself.

+3
source

All OpenGL and GLSL optimizations are vendor specific. It is hard to say what is the final result of the glsl compiler.

You can see here information about a particular provider: http://renderingpipeline.com/graphics-literature/low-level-gpu-documentation/

For your code, you can always β€œpack” the matrices into a new uniform: matModelViewProjection , multiply it in the application and send it to the vertex shader.

+1
source

It is entirely up to the driver. OpenGL is a specification, if you pay them for the rights to create an implication, they will give you an example of use, but what is it.

In addition, you need to consider the restrictions on matrix multiplications, making projM * viewM * modelM * vertex not the same as doing vertex * projM * viewM * modelM . This is because matrices are multiplied from right to left, and order matters with that. Thus, the shader could not pre-compute projM * viewM * modelM to share between the vertices, because it would give you dummy results.

0
source

All Articles