Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does GLSL really do unnecessary computations with uniform (not per-vertex) values?

For example, if I use vertex shader like the following:

#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 it do projM * viewM * modelM matrix multiplication for each vertex, or it it smart enough to calculate if once and do not recalculate until uniform variables are changed? If it isn't "smart enough", then is there a way to optimize it other than computing all uniform-dependent values on CPU and send them as uniform variables to GPU?
Also I'm interested in solutions that can be ported to OpenGL ES 2.0 later without problems.

like image 341
Display Name Avatar asked Mar 17 '13 14:03

Display Name


People also ask

What does uniform mean in GLSL?

A uniform is a global Shader variable declared with the "uniform" storage qualifier. These act as parameters that the user of a shader program can pass to that program. Their values are stored in a program object.

What type of vertex shader variable has the same value for each vertex?

There are three types of variables in shaders: uniforms, attributes, and varyings: Uniforms are variables that have the same value for all vertices - lighting, fog, and shadow maps are examples of data that would be stored in uniforms. Uniforms can be accessed by both the vertex shader and the fragment shader.

What is gl_Position in GLSL?

gl_Position is a special variable that holds the position of the vertex in clip space. Since a vertex shader's main output is the position in clip space, it must always set gl_Position. This vertex shader just transforms each vertex position (by the VP matrix).

What is vec3 in GLSL?

vec3 is a floating point vector with three components. It can be initialized by: Providing a scalar value for each component. Providing one scalar value. This value is used for all components.


1 Answers

So there is no general answer, as I understand. I did some tests on my hardware, though. 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 vertex shader, and then moved multiplication to the CPU program and tested again.

(sphereN - it's a continuously rotating sphere with 2*N^2 quads, drawn with glDrawElements(GL_QUADS,...) with 1 texture and without any lighting/other effects)

matrix multiplication in vertex shader:

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

matrix multiplication on cpu:

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

Tests show that multiplicating (uniform) matrices in vertex shader is bad idea, at least on this hardware. So in general one may not rely on corresponding GLSL compiler optimization.

like image 123
Display Name Avatar answered Nov 01 '22 06:11

Display Name