Sign in to follow this  
LargeJ

How to incorporate shaders in a rendering engine

Recommended Posts

I am working on my own simple rendering engine and I have a problem concerning shaders.

1. Right now I have two objects: a teapot (which consists of multiple submeshes) and a plane. The plane uses a shader that is almost identical to the teapot, but differs in the fact that it needs a "grass"-texture. Is this common in shader programming that you duplicate a lot of shader code (I guess not)? Do I have to split these shaders up in multiple shaders and apply multi-pass rendering, thereby causing overhead?

2. In my engine a mesh only knows about its geometrical data and not about the naming of uniform variables. I put a wrapper class around the mesh and set the uniform variables from there. So for the teapot, I loop over the submeshes and set the uniform variables for each of the meshes. The problem is that every wrapper class (say a wall, stone, car etc) needs to specify the uniform variable values. If one uniform variable name changes I have to edit a lot of code in different places. What is the best way to solve this? Right now I made a utility class that has a member "setMaterialVars( Material* )" that sets the material properties based on a material struct. Is this the way to go (every shader has it's own utility class) or are there better solutions?

Thanks in advance.

Share this post


Link to post
Share on other sites
I can't suggest any great advice, as it's entirely dependant on your own decisions of how you prefer to order things.
Here's my personal preference:
[list][*]Each shader has texture slots and variable slots[*]A material can then set the textures and variables to their slots[*]A renderable instance then matches a submesh with a material[/list]
Which means when rendering, I can:[list][*]Iterate through each shader and set the shader states:[*]iterate through each material and update the textures and variables and match them to the slots[*]iterate through each submesh using the material, and set the index/vertex buffers for rendering[*]Update the world matrix and render instances using the above combination of submesh and material[/list]
It seems to work quite nicely. Though, there's issues when it comes to dynamic lighting - and updating the light data when forward shading is used.

So:
[list=1][*]Use the same shader - but let the render engine change the texture for different materials. (it's best to use a generic texture name in the shader, i.e "Texture2D diffuseTx" )[*]Having a material class that deals with inputting each material's data into a shader seems like a good idea[/list]
Hope this helps

Share this post


Link to post
Share on other sites
Thanks for the quick reply.
So what I understand is that you create a material structure that matches the available variable slots in the shader so that the renderer can set these slots when needed (or make it virtual in the IRenderable interface to vary different material structures for different shaders)? Right now I have a teapot which does not use a texture, but just diffuse/ambient/specular colors. So does this mean I have to set a boolean to true to indicate whether I use the specified diffuse color or the texture?

Share this post


Link to post
Share on other sites
[quote name='LargeJ' timestamp='1313751277' post='4851149']
Thanks for the quick reply.
So what I understand is that you create a material structure that matches the available variable slots in the shader so that the renderer can set these slots when needed (or make it virtual in the IRenderable interface to vary different material structures for different shaders)?
[/quote]

Yeah, pretty much. In my implementation I'm using the Effects11 framework, and querying the variables of a constant buffer labelled "material" (defined in the shader) - and then creating and updating the constant buffer when need be.

[quote name='LargeJ' timestamp='1313751277' post='4851149']
Right now I have a teapot which does not use a texture, but just diffuse/ambient/specular colors. So does this mean I have to set a boolean to true to indicate whether I use the specified diffuse color or the texture?

[/quote]

In that case I'd have 2 shaders, one for colour only, and one for textured - but only because dynamic branching can be inefficient in pixel shaders.
Having to pass in a bool to specify which "material properties" to use in a shader can be inefficient - an alternative to my method, is storing a database of shaders which are automatically associated with materials.
i.e "I want a shader that can deal with diffuse and specular mapping, with [x] light types" etc... this could then be generated - or selected from the database.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this