1
\$\begingroup\$

I have a renderer where you can define passes where you pick the shader, and a signal, each object can register a listener to that signal in order to draw himself, the problem comes when some objects are normal meshes, others are sprites, some have skeletal animations, some don't. I was wondering if I could pack within the same vertex shader many different optional main functions, and pick the correct one for each object.

If there is no way, I would have to compile a different shader for each of the types and bind it from zero for all objects, even though all fragment shaders are the same.

\$\endgroup\$
0
\$\begingroup\$

No, I don't believe there's any way to have different main() functions in one shader. But you do have a few options. You could pass in a uniform that the main() function uses to decide which other function to call. Something like this:

uniform int shaderType;
const int kShaderType_X = 1;
const int kShaderType_Y = 2;
const int kShaderType_Z = 3;

vec4 doShaderTypeX()
{
    // ... do whatever you need for the first shader type
}

vec4 doShaderTypeY()
{
    // ... do whatever you need for the second shader type
}

vec4 do ShaderTypeZ()
{
    // ... etc.
}

void main()
{
    vec4 result;
    if (shaderType == kShaderType_X)
    {
        result = doShaderTypeX();
    }
    else if (shaderType == kShaderType_Y)
    {
        result = doShaderTypeY();
    }
    else if (shaderType == kShaderType_Z)
    {
        result = doShaderTypeZ();
    }
}

Your other solution of making several different programs that share a fragment shader but have different vertex shaders will also work. If you make them all at start up, you only need to make them once. Or you could do it lazily and make each one the first time it's required, and keep it around for later use.

\$\endgroup\$
  • \$\begingroup\$ The first option seems more bloated than it should be, as for the second option, do I have to recompile the fragment shader in order to attach it to other shaders? Also, will they share uniform locations or do I have to get them for each variation? Also, will they share uniform memory or do I have to bind all the variables for each shader combination? \$\endgroup\$ – evilpudding Mar 7 '18 at 4:23
  • 1
    \$\begingroup\$ According to the docs: "a single shader object may be attached to more than one program object." I do not know whether they will share uniform locations or uniform memory, but I would suspect so. That would make a good question here on game dev! \$\endgroup\$ – user1118321 Mar 7 '18 at 5:15
  • 1
    \$\begingroup\$ If not you can look into uniform buffers. \$\endgroup\$ – Sidar Mar 7 '18 at 10:35
  • \$\begingroup\$ Thanks for the info, I'll mark it as solved and look into it. \$\endgroup\$ – evilpudding Mar 7 '18 at 19:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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