• Advertisement
Sign in to follow this  

Multiple shaders in a scene

This topic is 3581 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

Hello There's something I do not understand perfectly about the usage of shaders in complex scenes. Let's say that a room is shaded using a simple shader which takes into account three lights, one texture and simulates fog. Now let's say you introduce an object in this room that needs to be bump-mapped, as the room shader does not implement bump mapping, a new shader must be written. In order for this shader to be "visually compatible" with the room, this new shader must not only implement bump mapping, but texturing, the support for 3 lights and fog. That means that the new shader will be pretty much copy-pasted from the other one, only to add bump mapping support. As the size of the scene grows, objects might need different shaders. How is this handled? Is there a single shader which implements everything, but which can disable additionnal features when they aren't used (like bump mapping for the room), or is a shader created for every possible combination of visual effects like : - A lit, fogged & textured shader - A lit, fogged, textured & bump mapped shader - A lit, fogged, multitextured shader - A lit, fogged, multitextured & bump-mapped shader ... etc I'm somewhat worrying about code duplication in this situation. How is this handled, in order to preserve visual coherence, by games in which many objects are shaded differently?

Share this post


Link to post
Share on other sites
Advertisement
Well it really depends on the person coding the shaders. Some people will just copy and paste the shader so you have a bunch of shaders which are slightly different. You could move a lot of the code into seperate functions for each stage and make one big uber shader. Or you could move those functions into seperate header files and include them in your shader.

Share this post


Link to post
Share on other sites
It's usually solved by exactly the two ways you mentioned:

1) "Über-shaders": a single, potentially very long, shader handles all situations and uses dynamic branching to skip unused parts.

2) Shader permutations. Those are created automatically, often by pasting standard shader parts together.

There is also a very popular intermediate approach. The idea is to write your shader as a single, all encompassing one, just as in approach 1. But instead of using dynamic branching to skip unused parts, you use compile time conditional directives (ie. ifdef and friends). An automatic system then compiles all needed permutations from the generic meta-shader by inserting defines as needed before compilation.

The method to choose depends on your engine design and your target hardware.

Share this post


Link to post
Share on other sites
Just as I thought then!

I'll be diving into shaders pretty soon so I guess I'll be able to see what suits me best. Shaders are cool, but they seem to be quite more trouble than fixed function pipeline... ah well. Thanks a lot for the information!

Share this post


Link to post
Share on other sites
Quote:
Original post by Trillian
As the size of the scene grows, objects might need different shaders. How is this handled?

Shaders do suffer from combinatorial explosion as you've realised.

Quote:
Is there a single shader which implements everything, but which can disable additionnal features when they aren't used (like bump mapping for the room)

This is one partial solution, the pseudo-technical name for such a shader is an uber-shader.
Obviously you usually can't write a shader that does everything, but depending on your scene complexity it can aleviate things somewhat.

Quote:
or is a shader created for every possible combination of visual effects

Yeah this is that pesky combinatorial explosion of shader effects.

Quote:
I'm somewhat worrying about code duplication in this situation. How is this handled, in order to preserve visual coherence, by games in which many objects are shaded differently?

In practice the two most commonly used solutions are to use uber-shaders where appropriate and other than that just suffer the large number of shader variations - using a sensible naming convention can help you select the suitable shader for the job.

A third solution is JIT compiled shaders. That is to combine and compile shaders on the fly from fragments of shader source code, this can become a bit impractical speed-wise, though typically you'd cache the compiled shader and only recompile it if a fragment of code was edited (in a real-time editing environment for example).

Real-time JIT shaders are the future solution to the combinatorial explosion problem. They'll be used in the form of shader meta-languages, where you write a surface meta-shader once; it then gets automagically linked and compiled, with its passes, constants and parameters all extracted in the compilation process and not explicitly coded by you.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement