Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm not familiar with SDKs like Unity or UDK that much, so i can't check this offhand. Do general purpose engines allow users to create custom uniform variables? The way i see it, and the way i have implemented it in an engine i'm writing to learn 3D, is that there is a "set" of uniforms provided by the engine and if you want to write a custom shader then you utilize uniforms you need to create a wanted effect.

Now, the thing is, first of all i'm not an artist, second of all, i didn't have a chance to create complex scenes yet. So my question is, is it common practice to define variables that the engine provides and only allow the user to work with what they're given?

Allowing users to add custom programs and use them where they want is not hard, but i have issues imagining how you'd go about doing the same for uniforms.

share|improve this question

1 Answer 1

up vote 1 down vote accepted

Yes, they do allow custom uniforms, but they will also fill out a few standard ones. For example, I'm using Horde3D for a project, and one of the shaders contains the following:

[[VS_GENERAL]]

#include "shaders/shaderSettings.shader"

#include "shaders/utilityLib/vertCommon.glsl"

#ifdef _F01_Skinning
    #include "shaders/utilityLib/vertSkinning.glsl"
#endif

uniform mat4        viewProjMat;
uniform vec3        viewerPos;
attribute vec3      vertPos;
attribute vec2      texCoords0;
attribute vec3      normal;

#ifdef _F02_NormalMapping
    attribute vec4  tangent;
#endif

varying vec4        pos, vsPos;
varying vec2        texCoords;

#ifdef _F02_NormalMapping
    varying mat3    tsbMat;
#else
    varying vec3    tsbNormal;
#endif

varying vec4        projCoords;

// texture matrix
uniform vec4        textureMatrixRow0;
uniform vec4        textureMatrixRow1;
uniform vec4        textureMatrixRow2;
uniform vec4        textureMatrixRow3;

And the material:

<Material>
    <Shader source="shaders/water.shader" />

    <ShaderFlag name="_F01_Skinning" />
    <ShaderFlag name="_F02_NormalMapping" />
    <ShaderFlag name="_F02_Character" />

    <Sampler name="albedoMap" map="/textures/dolphin/dolphin_diffuse_V02.dds" />
    <Sampler name="causticMap" map="/textures/caustics/001.dds" />
    <Sampler name="normalMap" map="/textures/dolphin/dolphin_normal_V02.dds" />

    <Uniform name="textureMatrixRow0" a="0.0" b="0.0" c="0.0" d="0.0" />
    <Uniform name="textureMatrixRow1" a="0.0" b="0.0" c="0.0" d="0.0" />
    <Uniform name="textureMatrixRow2" a="0.0" b="0.0" c="0.0" d="0.0" />
    <Uniform name="textureMatrixRow3" a="0.0" b="0.0" c="0.0" d="0.0" />
    <Uniform name="fogColor" a="0.0" b="0.0" c="0.0" d="0.0" />
    <Uniform name="texScale" a="1.0" b="0.0" c="0.0" d="0.0" />
</Material>

Here, the viewProjMat and viewerPos uniforms are filled by the engine, while the others are defined by the user. It seems like a pretty good solution to me.

Note that you can check which GLSL uniform variables are actually used in a shader program:

// uniforms

GLint max_name_length;
GLint active_count;
GLchar* name;
GLsizei length = 100;
GLenum type;
GLint size;

glGetProgramiv(m_Program, GL_ACTIVE_UNIFORMS, &active_count);
glGetProgramiv(m_Program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length);

name = new GLchar[max_name_length];
for (GLint u = 0; u < active_count; u++)
{
    glGetActiveUniform(m_Program, u, max_name_length, &length, &size, &type, name);
    GLint handle = glGetUniformLocation(m_Program, name);

    LOG_INFO("Uniform - %s (%i)", name, handle);

    if (!strncmp(name, "gl_", 3))
    {
        LOG_TRACE("Using deprecated GLSL: %s", name);
    }
    else
    {
        // do something with standard uniforms
    }
}
delete [] name;

EDIT:

As a user, you see the following:

// set the fog color uniform
h3dSetResParamF(res, H3DMatRes::UniformElem, 4, H3DMatRes::UnifValueF4, 0, m_FogColor.x);
h3dSetResParamF(res, H3DMatRes::UniformElem, 4, H3DMatRes::UnifValueF4, 1, m_FogColor.y);
h3dSetResParamF(res, H3DMatRes::UniformElem, 4, H3DMatRes::UnifValueF4, 2, m_FogColor.z);

Can't say I agree with the C-style interface, but it works.

share|improve this answer
    
Thanks, this gives me a few ideas. Could you tell how are the uniforms managed on the code level? Like, you as the user, how do you see these uniforms in your own code. –  dreta Jul 11 '12 at 9:51
    
I've expanded my answer a bit. P.S. The best way to say thanks is to upvote the answer. ;) –  knight666 Jul 11 '12 at 9:55

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.