Discussion:
Shader Uniform Performance Question(s)
paul1492-/
2008-11-19 14:58:25 UTC
Permalink
Maybe somebody on this list can save me from reinventing the wheel...

I'm looking to get a better understanding of performance issues related to uniforms.

How much overhead is there in having a uniform?  If there only a performance hit if the uniform changes values or every frame. What if I change the Uniform in OSG to exactly the same value it already has, would there be a performance hit?

I have uniforms that might not change values very often. Some are simply boolean flags. Can I have different shaders and somehow switch between them?  Can I "recompile" the shader on-the-fly (i.e. defining these boolean using #define/#if-#endif)? 

In some cases, I have variables which can change within the shader, but I know these values when I create the scene graph so I currently use #define instead of passing them as uniforms (which will ever only have one value). Does this gain me much in performance? 

Also, is there a difference in performance in using four "float" uniforms versus setting a Vec4?

Paul P. 
Ümit Uzun
2008-11-19 15:25:08 UTC
Permalink
Hi Paul,
Post by paul1492-/
Maybe somebody on this list can save me from reinventing the wheel...
I'm looking to get a better understanding of performance issues related to uniforms.
How much overhead is there in having a uniform? If there only a
performance hit if the uniform changes values or every frame. What if I
change the Uniform in OSG to exactly the same value it already has, would
there be a performance hit?
Firstly, uniform variables are intented to using in rarely changing values,
and attributes is used while needing frequently changing values. So using
uniform qualified saves your performance if your value not changing in every
frame. But at that point if you update uniform variable by the
initialized callback or visitor, your variables updating operation will be
needless and I think will reduce your performance. So update your changed
uniform variables by triggered function or operation.
Post by paul1492-/
I have uniforms that might not change values very often. Some are simply
boolean flags. Can I have different shaders and somehow switch between
them? Can I "recompile" the shader on-the-fly (i.e. defining these boolean
using #define/#if-#endif)?
You can recompile or switch but I don't advice these operation. Only update
your changed values by triggered functions.
Post by paul1492-/
In some cases, I have variables which can change within the shader, but I
know these values when I create the scene graph so I currently use #define
instead of passing them as uniforms (which will ever only have one
value). Does this gain me much in performance?
It's good choice. Every variable which you send by unifrom variables will
reduce the usable memory by GPU so this is most practical way for me.
Post by paul1492-/
Also, is there a difference in performance in using four "float" uniforms
versus setting a Vec4?
Actually the preceded answer about memory usage is same situation too. Every
memory usage reduce the performance I think.

P.S : I am not guru' I only use GLSL about 2 months.
Post by paul1492-/
Paul P.
_______________________________________________
osg-users mailing list
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Regards.
--
Ümit Uzun
David Spilling
2008-11-19 15:45:37 UTC
Permalink
Umit,

Sorry to be picky, but:

Firstly, uniform variables are intented to using in rarely changing values,
Post by Ümit Uzun
and attributes is used while needing frequently changing values.
Not quite. Lots of the "fixed-function" uniforms - which are deprecated
under GL3 - potentially change every frame ( gl_ModelViewMatrix etc. ).

Attributes are per-vertex data, like position, normals, texcoords and so on.
Uniforms are the same across a set of vertices.

David
Ümit Uzun
2008-11-19 15:56:04 UTC
Permalink
Hi David,

You are right there is much uniform variables can be changed in every frame
but these all Built-in variables. I think this difference can change the
state of your tenet.

I have read OrangeBook and Randi Rost ( GLSL GURU :) ) advices using uniform
variables if you rarely update and in converse situation for attributes.

I don't know why but if they advices, this must be true :)

Regards.
Post by Ümit Uzun
Umit,
Firstly, uniform variables are intented to using in rarely changing
values, and attributes is used while needing frequently changing values.
Not quite. Lots of the "fixed-function" uniforms - which are deprecated
under GL3 - potentially change every frame ( gl_ModelViewMatrix etc. ).
Attributes are per-vertex data, like position, normals, texcoords and so
on. Uniforms are the same across a set of vertices.
David
_______________________________________________
osg-users mailing list
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
--
Ümit Uzun
David Spilling
2008-11-19 15:37:56 UTC
Permalink
Paul,
How much overhead is there in having a uniform?


GLSL? Not much.
Post by paul1492-/
If there only a performance hit if the uniform changes values or every
frame. What if I change the Uniform in OSG to exactly the same value it
already has, would there be a performance hit?
I regularly use uniforms that change every frame, and I can't say I've
noticed any performance penalty (in the context of an app that is doing
"real work").
Post by paul1492-/
I have uniforms that might not change values very often. Some are simply
boolean flags. Can I have different shaders and somehow switch between them?
Yes. Some people use uniforms and in-shader dynamic branching to control the
operation of shaders. (Some people obviously have too much GPU power for
their own good ;). Me, I'm often stuck with older cards that can't support
dynamic branching very sensibly, and so this kind of shader kills me. ).

An alternative is to have a switch node, whose children all have different
shaders on them, and who are all the parent of your object. There's a
separate thread on this topic going on at this exact time with very similar
issues to this approach, bearing in mind that shaders form part of the
stateset.

Can I "recompile" the shader on-the-fly (i.e. defining these boolean using
Post by paul1492-/
#define/#if-#endif)?
Bad idea in general, for performance reasons.
Post by paul1492-/
In some cases, I have variables which can change within the shader, but I
know these values when I create the scene graph so I currently use #define
instead of passing them as uniforms (which will ever only have one
value). Does this gain me much in performance?
In general, yes - it's certainly better for performance (the extent is GPU
dependent, obviously) and this solution is better for older hardware that
doesn't support dynamic branching.
Post by paul1492-/
Also, is there a difference in performance in using four "float" uniforms
versus setting a Vec4?
Off the top of my head, I'm not sure - this is probably driver dependent
(good GLSL compilers might pack this up automatically). You might try the
OpenGL / GLSL forums for this.

Hope that helps,

David
Middleton, Colin (GE EntSol, Intelligent Platforms)
2008-11-19 16:11:39 UTC
Permalink
Hi Paul,
Post by paul1492-/
Maybe somebody on this list can save me from reinventing the wheel...
I'm looking to get a better understanding of performance
issues related to uniforms.
How much overhead is there in having a uniform?  If there
only a performance hit if the uniform changes values or every
frame. What if I change the Uniform in OSG to exactly the
same value it already has, would there be a performance hit?
At an OpenGL level a uniform change will result in a state change, in the same way as changing the diffuse color or a texture parameter would. This can mean that the graphics hardware may need to wait whilst some currently executing commands are flushed.

If you only change it once a frame and you have any objects with different state in your scene, it will not make any difference. The main cost of uniforms is when you have many objects with slightly difference uniform values in the same frame as this introduces state changes.

Uniforms are part of the osg::StateSet, so you need to be careful about making too many different ones as too many can cause performance problems.
Post by paul1492-/
I have uniforms that might not change values very often. Some
are simply boolean flags. Can I have different shaders and
somehow switch between them?  Can I "recompile" the shader
on-the-fly (i.e. defining these boolean using #define/#if-#endif)? 
Compiling the shader on the fly is certainly possible, how long it takes I'm not sure. I expect it is an expensive state change ( like a texture download ), rather than a cheapish sort ( such as a uniform ), so probably not good if you are doing it a lot.
Post by paul1492-/
In some cases, I have variables which can change within the
shader, but I know these values when I create the scene graph
so I currently use #define instead of passing them as
uniforms (which will ever only have one value). Does this
gain me much in performance? 
I assume that the #define values are in the shader. The only way I've found to use #defines is with a different shader program ( character array or string ). As such it will mean using a different osg::Shader object and therefore more gfx memory and a different shader handle.
I expect the cost of switching shaders is the same or more than switching the value of Uniforms.
Post by paul1492-/
Also, is there a difference in performance in using four
"float" uniforms versus setting a Vec4?
From my understanding a Vec4 will be cheaper than a four float uniforms in terms of state changing. Each uniform needs to be checked with the uniforms in the shader by the OpenGL driver. This is some sort of string compare. Also increasing the number of uniforms increases the length of the list in osg::StateSet and therefore how long it takes to walk.
It is also feasible that the hardware is faster at dealing with shaders with less uniforms, so that your shaders may run faster with a Vec4 rather than 4 floats. However this is entirely dependant on the hardware optimisations. I've not tested this.

Colin.

Continue reading on narkive:
Loading...