Sign in to follow this  

GLSL Uniform Variable Initialization/Management/Wrangling

This topic is 2565 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Perhaps my skill in Google is not what I believe it to be, but I haven't found much information on how people manage the binding of uniform variables in their shaders?

By this, I mean, you write a shader and declare some uniforms. Now you have to set them up on the client side with glGetUniformLocation() and glUniform(). Can you "automagically" set some of these uniforms? I don't want to have to rewrite code in two different places because I changed a variable name in one place. Is this simply the reality of writing shaders?

Share this post


Link to post
Share on other sites
Do you mean a default value?

From opengl.org
Quote:

Uniforms are intended to be set by the user. However, you can initialize them to a default value using standard GLSL initalizer syntax:

uniform vec3 initialUniform = vec3(1.0, 0.0, 0.0);

This will cause the uniform to have this vector as its value until the user changes it.


Other than this, you're pretty much on your own, you can encapsulate your shaders in any kind of class that you want, but essentially at some point you have to tell OpenGL what you want to do with the uniforms you declare.

I guess the best thing you could do would just be to use consistent naming across all of your shaders, i.e. make the name of the projection matrix uniform the same across all of your shaders.

You also can get a list of the uniforms in your shader with glGetActiveUniform, which may help you somehow.

Share this post


Link to post
Share on other sites
I want to be able to make changes to shader code and have it be as independent as possible from the rest of the client code. Basically, if I have a uniform and I change the name of it, I don't want to have to go find the setup code and change everything to match.

But it seems like the way the binding works, it is fundamentally not possible to make such bindings automatic (you need to know which client side variable maps to which shader variable, but only the programmer can know what this mapping is). Is my observation accurate?

Share this post


Link to post
Share on other sites
Yes I think you have the right understanding. If you change the name of the uniform, you have to change the corresponding code in the client. Otherwise how would you know which uniform to send the data to?

Share this post


Link to post
Share on other sites
Precisely. So I guess my next question then is: how do professional developers deal with this? Do they simply develop some sort of uniform naming convention (as you mentioned) and add any other uniforms as they need it? Or do they simply try to avoid using "non-standard" uniforms and try to hack some functionality in by way of textures?

Share this post


Link to post
Share on other sites
well, I'm not a professional but academic developer. The best way to me is to write something like this in glsl:
#AutoBind( typename, globalVariable )
This implies parsing the shader code once yourself.
which is really, *really* suggested. You can also solve includes that way and do other funny stuff...
On the cpu-side, I have a variable manager which is basically a manager for hashmaps of different type (int, bool, vec2, vec3, etc.)

Share this post


Link to post
Share on other sites
Quote:
Original post by snowmanZOMG
Perhaps my skill in Google is not what I believe it to be, but I haven't found much information on how people manage the binding of uniform variables in their shaders?

By this, I mean, you write a shader and declare some uniforms. Now you have to set them up on the client side with glGetUniformLocation() and glUniform(). Can you "automagically" set some of these uniforms? I don't want to have to rewrite code in two different places because I changed a variable name in one place. Is this simply the reality of writing shaders?


Sounds like you don't want uniform.
The purpose of a uniform is so that you can set it from your C++ (or whatever) code.

You want to have a constant.
Just declare this in your GLSL
const vec4 myvalue=vec4(0.0, 1.0, 2.0, 2.5);

Yup, you haven't been Googling enough or perhaps the Wiki over at opengl.org/wiki sucks.

Share this post


Link to post
Share on other sites
Quote:
Original post by snowmanZOMG
Precisely. So I guess my next question then is: how do professional developers deal with this? Do they simply develop some sort of uniform naming convention (as you mentioned) and add any other uniforms as they need it? Or do they simply try to avoid using "non-standard" uniforms and try to hack some functionality in by way of textures?


I think they try to avoid using opengl (oh snap!).

Seriously though in DirectX you have the ability to bind uniforms directly to constant registers without having to know the shader's name for the variable. The same way you can bind vertex attributes by semantic rather than by name as you have to in opengl. I've found this to be quite a problem when working with opengl. Especially if you use lots of different shaders, you waste a lot of performance calling glGetUniformLocation and glGetAttribLocation all the time. If there's a better solution to this I'd love to hear it as well.

Share this post


Link to post
Share on other sites
Quote:
Original post by doesnotcompute
Quote:
Original post by snowmanZOMG
Precisely. So I guess my next question then is: how do professional developers deal with this? Do they simply develop some sort of uniform naming convention (as you mentioned) and add any other uniforms as they need it? Or do they simply try to avoid using "non-standard" uniforms and try to hack some functionality in by way of textures?


I think they try to avoid using opengl (oh snap!).

Seriously though in DirectX you have the ability to bind uniforms directly to constant registers without having to know the shader's name for the variable. The same way you can bind vertex attributes by semantic rather than by name as you have to in opengl. I've found this to be quite a problem when working with opengl. Especially if you use lots of different shaders, you waste a lot of performance calling glGetUniformLocation and glGetAttribLocation all the time. If there's a better solution to this I'd love to hear it as well.


1) Explicit_Attrib_Location (don't remember if it's ARB or EXT) is an extension which allows you to bind attribs to numbers (or semantics if you do the #define POSITION 0 stuff).

2) glBindAttribLocation is a no-cost way to bind attributes after the shader linkage is complete

Share this post


Link to post
Share on other sites
ARB_explicit_attrib_location looks interesting. I wish it wasn't part of the 3.x specification but it's definitely the right idea. Here's the link if anybody wants to read about it.

Regarding glBindAttribLocation, I'm not sure how useful that is really since it still requires the application to have knowledge of the shader attribute names.

Anyway, I didn't know about either of these though so thanks for pointing them out.

@snowmanZOMG sorry for hijacking your thread, this seems like the type of information you were looking for as well though right?

Share this post


Link to post
Share on other sites
Any variable that you re-name in any language has to be changed anywhere you use it, so I don't see what the problem is.

1.) You probably aren't going to rename variables in your shader much. Light, normal, eyeVec, sampler2D Diffuse, sampler2D NormalMap....these variables never need to be renamed.

If you have a ton of objects with different materials/uniforms you can simply call a helper function like

string realUniformName(string name)
{
return map[name];
}

//somwhere global you have a map or hash:
map["Diffuse"] = "YourShaderVariableName"

realUniformName("Diffuse");

if you change the variable name in the shader, it can still be diffuse in c++, just go to your: map["Diffuse"] = "YourShaderNEWVariableName", this way you only change the name at one point in c++ code.

Share this post


Link to post
Share on other sites

This topic is 2565 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this