is this bad for performance? (GLSL)

Started by
8 comments, last by knighty 15 years ago
hey. in the beginning of my render loop i calculate the product of my projection matrix and view matrix(with my own math functions) and then i pass it to my shaders as a uniform named "projectionAndViewMatrix". Then for every node i render i send through the absolute transformation of that node as "node"(also calculated by my own math functions) so this would be the relevant part of my vertice shader

uniform mat4 node;
uniform mat4 projectionAndViewMatrix;

void main()
{
	gl_Position = projectionAndViewMatrix * node * gl_Vertex; 
}



this works fine for me, but i've read from a couple of sources that states that sending a lot of uniforms wil severly affect performance and im sending 1 uniform per node each frame... but thouse sources seemed pretty dated to me and i could not find anything newer on the subject. Will my way of doing this give me trouble in the long run? i just recently started with shaders and this is my first attempt at moving away from the fixed pipeline. Thnx in Advance! [Edited by - EternityZA on March 29, 2009 4:13:01 AM]
Advertisement
I'm not an expert in OpenGL but I think that two matrix-vector multiplication in the shader are more expensive than updating uniforms (I guess Matrix-vector multiplication is equivalent to 4 dot products) so it's better to pack node and viewprojection matrices.
Let's take some rough measurements of cycles-count:
- glUniform*() : 500-1000 cycles
- matrix multiplication: < 100 cycles

On the gpu, that extra multiplication will take 4 gpu cycles minimum. There's a pitfall that your code as it is will do the mat4*mat4 first, wasting ~16 gpu cycles. If you play safe, it'll be just 4 extra dots:
vec4 temp = node * gl_Vertex;gl_Position = projectionAndViewMatrix * temp; 


I think that the "mat4 node" approach could be faster if you render many small objects (under i.e 64 vertices each).
Thanks for the info :)

Anyway, I think one won't send uniforms as often, that is per vertex. In that case why not sending them as attributes?

In the code of EternityZA, he is sending the "projectionAndViewMatrix" (I gess once per frame) and "node" (many times per frame). Why not premutiply them before sending the result to the shader? he will save 4 slots and a matrix-vector multiplication.


I believe shader compilers do some optimizations so:
(edit: no! it's not optimization. it's just the way compiler is entended to behave)

gl_Position = projectionAndViewMatrix * node * gl_Vertex;

will be (edit: always) executed as:

temp = node * gl_Vertex;
gl_Position = projectionAndViewMatrix * temp;


[Edited by - knighty on March 30, 2009 6:26:10 AM]
thnx for the reply.

but seeing that the glUniform (500-1000 cycles) has such a high cost wouldnt it be better to just do everything on the cpu and then to send only the final matrix to the shaders? or is it still better to send both those matrixes through (of course making sure that the mat4*mat4 doesnt happen first like you suggested)
^^
:=)
ah. u just answered my question as i was typing :p

thnx il do that.

;O)
just one more question since im on the subject.

is a built in attibute faster than a uniform? meaning what if i where to take that final all inclusive matrix of mine and assighn it to a opengl built in atribute and then read that atribute from wihtin GLSL, wil that affect performance?

im guesing it wont (not positively at least) but i want to know for sure

EDIT:hmmm this question probely doesnt make any sense... ow wel im happy as it is
Honestly, I don't know. Perhaps you should do some experiments.

It (EDIT: I mean performance in general) also depend on the application: what you need and how you do it.

If you are rendering a static model you can send its geometry once. But if it is dynamic (it depends on how much it's dynamic) will you do the modification on cpu or can you do them on GPU ?...

It depends on so many things and that goes far beond my knowlege... :)

[Edited by - knighty on March 30, 2009 4:11:14 AM]

This topic is closed to new replies.

Advertisement