pouët.net

uniform vs. attribute variables in shaders

category: code [glöplog]
 
Hi,
I recently rediscovered - after 10 years of nothing - a certain interest in pc and demo programming. Things sure changed a lot by the time, and I suddenly feel old and antiquated...
However, following the advice "just start coding and make something appear on the screen", I begun messing with WebGL and I wrote a standard minimal framework for shaders, just to teach me how to pass variables to shaders and stuff like this.
That's a simple Monjori intro port running on WebGL, but I don't understand how I should pass the "time" variable to the fragment shader in order to write something slightly optimized: the Orange GLSL book states that a variable qualified as unifrom should be used when its value changes "relatively infrequently"... but how much is relatively unfrequently? That's the approach I chose for passing the time value to the shader, but it changes at least once per frame.
The alternative - correct? - way would be to pass the time as an attribute qualified variable to the vertex shader that then is passed to the fragment shader, but this approach seems very convolute!
Sorry for the noob question!
I'm not an expert also, but the general idea is this: pass everything that is constant over bunch of data (vertices/fragments/whatever) as uniform. Time is a very good example for that.
Everything else that changes between elements in the same draw call (normals, tex coords, whatever other custom stuff you come up with) should be passed as an attribute.
added on the 2012-06-13 12:38:55 by provod provod
Just use uniforms for all constants that come from outside the shader and do not change during the execution.
added on the 2012-06-13 13:10:46 by Preacher Preacher
Basically what w23 said. Attributes are just that: "vertex" attributes like (per-vertex-)normal, (per-vertex-)color, etc.
Uniforms are what you pass to a shader to set up global values that doen't change during one rendering call. You can create sets uniforms ("Uniform Buffer Object"s) to share them between program, quickly switch them etc.
added on the 2012-06-13 13:11:00 by raer raer
Passing time as a uniform should be fine. I do it all the time.
added on the 2012-06-13 14:19:06 by raizor raizor
That's pretty much how everyone's doing it. :)
added on the 2012-06-13 14:36:16 by tomaes tomaes
I thought "everyone" is passing time as z coordinate of the one fullscreen quad nowadays :)

(don't listen to me. Uniform is the way to go. :)
added on the 2012-06-13 14:59:41 by kb_ kb_
uniforms can't be changed during a draw call, so everything that's specific to parts of a mesh (like a single vector) you are sending to the gpu has to be modelled as vertex attribute (as w23 said: normals, tex coords). time changes "relatively infrequently", that is once per frame, i.e. once per shader program usage. more often would be something like material ids for different object you are rendering using the same shader, i don't know if that's what the orange book still mentions as "relatively infrequently". but i'm not really an expert either.

kb_: or as a color along with some envelopes or other data :)
added on the 2012-06-13 18:14:19 by skomp skomp
kb_: i usually pass time as scale by using glRectf(-t, -t, t, t) (where t=ticks_in_ms/1000.f+1.f) on the code side, and restore it as p.w=length(gl_Vertex.xy) in vertex shader.
added on the 2012-06-13 19:27:20 by provod provod
zerothehero: if something changes only once per frame (like time!) and it represents a small amount of data (say, few floats, like time!), then that's a candidate for being a uniform. instead, if something changes per vertex (or every few vertices) in your mesh/redner call, make it an attribute/varying. there are more mechanism (buffers, textures...), but for i'd say that for now you are good with that rule of thumb.
added on the 2012-06-13 20:41:07 by iq iq
THANKS!
This doubt I had, came from the only example I met in the Orange Book so far, that is a trivial vertex+fragment shader which evaluates the color of a surface depending on its tempearature; the uniform variables that are passed are the temperature range and the the coolest temp, which are obviously prone to not be changed frequently - more constant values than real variables.
That why I thought that the time variable would be a candidate for being a "frequently value changing" variable.
Now it's clear, thanks again!
While there's a definite consensus that time should be a uniform (and it's the way I've always done it), this thread got me thinking that a different time value per vertex could be fun.
added on the 2012-06-14 11:30:19 by psonice psonice
psonice: congrats, you just discovered how to do raymarched jello cubes basically for free ;)
added on the 2012-06-14 11:36:24 by kb_ kb_
woohoo! I can make that twister at last!
added on the 2012-06-14 12:21:01 by psonice psonice

login