4
\$\begingroup\$

So I have the following situation: I'm sharing a blinn shader accross many meshes. Some meshes have specular & normal maps, others do not.

I'd like to, without making the shader code too complicated, be able to specify a constant color instead of a texture, for the normal or specular maps. This is for example if a given mesh doesn't need one of those maps.

The way I imagine it, I would just pass a flat "grey" as the specular map, for instance, and the shader could just act as if a texture was passed in. Is this possible?

Ideally, I don't want to have an extra uniform for each mesh specifying whether or not the texture should be used.

Another alternative would be to actually create a grey texture on the fly, if this is the better way, please advise on the simplest way to do this.

\$\endgroup\$
4
\$\begingroup\$

I've had the same problem several times and haven't found a way to specify a default color that would be used when a texture is not used.

I've ended up creating 1x1 pixel fully white, black and transparent textures that are globally available. This does the job pretty well and is easy to use, although I don't like the unnecessary texture accesses in the shader.

\$\endgroup\$
  • \$\begingroup\$ The texture accesses should be cached and therefore be very fast - almost certainly faster than any branching or state-change based approach. \$\endgroup\$ – Maximus Minimus Jan 6 at 12:21
1
\$\begingroup\$

Here is where it comes the shader/material distinction.

The shader is a GPU program that produces some lighting/shading effect. In your case you need to build a material system (albeit a simple one) where multiple materials can use the same shader, but pass different values for each material, that's one reason we have uniforms.

Another point is, if some material doesn't need a specific property of a shader (e.g. especially normal map) then it shouldn't have it. Just create an appropriate shader for it (or use uber shaders), you also want to do this for performance reasons.

If you want a diffuse shader to be to have a solid color, just create a "non-texture" or blank-texture and pass it by default, probably white and it doesn't need to be big 1x1px is fine (though I didn't try it), and pass the diffuse color, this way you can modulate while still having only the diffuse color.

\$\endgroup\$
  • \$\begingroup\$ Won't this make shader creation much more complicated? Everything is the same between the two materials, except one has a spec map and the other doesn't, for instance.. \$\endgroup\$ – cloudhead Mar 20 '14 at 23:35
  • \$\begingroup\$ @cloudhead with your current approach it is only going to be fine for very small demos, once you have alot of shaders and objects on the screen you will notice you need a material system so it's simpler on the long run. And regarding your current problem, I already mentioned that you can create a 1x1 px texture, though be warned this is only fine for simple diffuse textures once you have normal maps etc don't do this. \$\endgroup\$ – concept3d Mar 21 '14 at 14:21
0
\$\begingroup\$

I have implemented a simple solution that seems to be working for myself. I solved it by ensuring that my shader takes in both colour and texture coordinate data. The other requirement is that you set the colour of all textured vertices to black. My fragment shader is then set up as follows:

    #version 330 core
    out vec4 gl_FragColor;

    in vec2 TexCoords;
    in vec4 vsColour;

    uniform sampler2D texture_diffuse1;

    void main()
    {    
        gl_FragColor = vsColour;
        gl_FragColor += texture(texture_diffuse1, TexCoords);    
    }

If there is texture data it will overwrite the black value.

\$\endgroup\$
  • \$\begingroup\$ This will only work for black though. Any other colour will alter the texture colour because of the += adding it to the fragment colour. \$\endgroup\$ – Soapy Jan 7 at 11:23
  • \$\begingroup\$ I had it working and the default colour of an object that normally should be textured was set to black. If the texture fails it will add 0 to all colour channels and leave the default colour unchanged. \$\endgroup\$ – Will Jan 7 at 11:33

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.