Jump to content
  • Advertisement
Sign in to follow this  
abso

OpenGL Compositing shaders in a scenegraph

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

This came up at a discussion with some coworkers the other day. Basically, we have a virtual environment software sandbox (called VESS for anyone interested http://vess.ist.ucf.edu) that uses OSG for its graphics. One of the reasons for using a scenegraph is to accumulate and order state changes as you go down the graph. However, with shaders (the clear future of graphics given the push for a fully programmable pipeline with future versions of openGL and DX) this becomes a problem. For example, and I'm quoting from a coworker's email, "...say you have a nice, moderately complex lighting environment that you want to apply to the whole scene. Naturally, you'd want to attach this program near the root of the scene graph. However, there is an object farther down the tree that needs its own shading (say it's got a fancy procedural texturing shader with a nice bump map and glossmap for nifty specular reflections). You want to have your nice lighting shader work with it, but as soon as you apply the new program, your existing lighting environment goes out the window. So you're stuck implementing a dozen shaders for every scene to cover all the combinations of effects that you're looking for." In GLSL, you can implement shader modules as functions, but at some point you need to provide a fixed order to apply the shaders in (the shader entry point). You must always know the order of things in the scenegraph in order to manually set up this function. So, does anyone have any ideas as to how this will work? One of the ideas we were throwing around consisted of a meta-language to generate an entry function based on the order of shaders in the scenegraph. However, this has obvious drawbacks in that shader programmers need to know another language just to write shaders. Anyone have any ideas for how to go about this? It is possible that scenegraphs will just go out the window once the fixed-pipeline is dropped, but until then, what can be done to get composite shaders to run in a scenegraph? [Edited by - abso on March 29, 2006 3:15:07 PM]

Share this post


Link to post
Share on other sites
Advertisement
I think (anyone correct me if I'm wrong) that the Valve's Source engine handles this in a good way. Basically, they write one big shader that covers everything (e.g. lighting, multi-texturing etc.) But each section can be turned on / off depending on the material. Essentially, they put lots of "ifdef" statements in, and the material for each object specifies which sections of the shader to use. So you'd have, say, a material that requires one texture and all your dynamic lighting, and another that requires multi-texturing, dynamic lighting etc.

Then, when you load in your materials, you check if there's a shader matching the requirements you need, and if not, compile a new one, specifying the sections you want by setting the pre-processor defines depending on the material properties.

I think that makes sense :)

Share this post


Link to post
Share on other sites
One way to do it is to use a combiner system. For HoopWorld ( http://www.hoopworldgame.com/ ), one of our programmers wrote a system that basically took snippets of hlsl code that did a specific task ( lighting, texture coord transforms, etc ), then based on the needs of the material created in the material editor, it combines these shader fragments into a complete hlsl shader... in a nutshell.. It's useful in that your artists can easily create a lot of complex, unique materials, but as a downside you might be switching between a lot of unique shaders in your render loop, and it can be a pain in the arse to debug when things go wrong.
Sorry for my vague description, I'm a bit worn out at the moment. :)
Daniel

Share this post


Link to post
Share on other sites
I use a simple system which looks like the one described by abso for the Valve engine ; each material generates it's shader (using a cache) based on a shader feature mask.
This system has a some limitations ;
- each material must know how to implement each of node/environment settings you may have (atmospheric scattering, directional shadow map, cubic shadow map, trapezoidal shadow map, variance shadow map, directional light, point light, texture, normal map,...) which leads to a huge base shader (even if most of the shader will be discarded when compiled for a particular material).
- it makes developping new material very very difficult. For example, I have for the moment only the default appearance, and a toon appearance. Since everything is defined at the material level, any knew material needs to implement lots of features (I have not yet finished to implement everything for the toon appearance...).
The main advantage is that it is very easy and straight forward to develop and maintain.

I have put on my TODO list to redesign this using a mixed system ; the material will still be in charge of producing a dedicated shader but it will have "shader part factories" to perform this. I'm planning to use a mixed system since I still want to let a given material to provide its own implementation for a given feature.

Regarding the scenegraph question, my scenegraph is not targeted at accumulating and ordering state changes. It is only aimed at defining a structured universe that can be easily manipulated by the game engine.
The renderer traverses the scenegraph in order to built "renderer state" which are the context in which each node is to be interpreted (environment, transforms,...). The shader is generated according to this context.

Here is a simple example ;
A node interpreter is called to interpret a node with a renderer state stating one directional light with no shadow technique, one omni directional with cubic shadow map, a projection frustum and a transform. From this, the material build (or reuse) a dedicated shader.
For the moment the complete build is performed by the shader. In the future, the shader will ask the shadow technique for a shadowing GLSL function to use.

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!