Jump to content
  • Advertisement
Sign in to follow this  
John Mott

when do you load new shaders?

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

I'm a hobbyist learning DirectX. I'm using C# with SharpDX. I'm a strong developer, pretty good with the graphics and math but still wrapping my brain around how to use the shaders and the order of things.

 

I'm not clear on when you are supposed to load a new shader.

 

lets say I have two boxes, each with different texture (from a bitmap for example)

 

I see that I can load the texture into the card and I see how its referenced in the shader.

 

I also see how you can load multiple textures into the card and refer to them in the shaders.

 

However, what's the flow for having the shader pick one texture vs. another?

 

A related question is that I see how rich the shader coding world is. Does a typical design use different shader code for different objects? If I have one shiny object, one thing that is water, and something else that has a matte finish these would seem to be different shaders.  Is the rendering flow to 'load shader for object/draw object'?

 

thanks,

 

john

Share this post


Link to post
Share on other sites
Advertisement
However, what's the flow for having the shader pick one texture vs. another?

 

A shader does not directly use a given texture. A shader has a slot or binding point, to which you can assign any texture you want, in your application code. Note that you don't actually bind the textures to the shader, but rather to the device (so if you change shaders, the texture still stay bound).

Texture2D BoundByApplication;


float4 pixel = BoundByApplication.Sample(Sampler, vTexCoords); 

As to how this is done, each shader stage (vertex, pixel, ...) has its own binding points, and you can assign a "shader resource view" generated from the texture-object to that. For SharpDX, have a look at this code:

 

https://gist.github.com/axefrog/b51b4e149c329608eae6

 

Line 145, SetShaderResource(slot, resource). This should give you the right idea.

Edited by Juliean

Share this post


Link to post
Share on other sites
Thank you, that helps.

How do you deal with shaders that might have different hlsl code? If cube 1 is shiny and cube 2 is flat that would require different shaders, correct? Can you load multiple shader code, or do you do that? Its really a workflow question, how do you manage it when there are a lot of shaders? Do you load each one before calling draw?

Share this post


Link to post
Share on other sites
How do you deal with shaders that might have different hlsl code? If cube 1 is shiny and cube 2 is flat that would require different shaders, correct? Can you load multiple shader code, or do you do that? Its really a workflow question, how do you manage it when there are a lot of shaders? Do you load each one before calling draw?

 

 

Okay, so for your question: Yes, you can load as many shaders as you want. You usually do this at load-up time, doing it before drawing would be ungodly aweful for performance.

Shaders are just like textures, they are resources being bound to the device. So you load & compile the shader once, and for each object that needs a certain shader, you bind this shader before drawing.

Share this post


Link to post
Share on other sites

Ok, I got that and immediately my head started swimming again. I see how shaders can select textures and how the shaders are loaded into a slot. How do you bind to a particular shader when you draw?  Is it the call to SetVertexBuffers?

 

thanks,

 

john

Share this post


Link to post
Share on other sites
Ok, I got that and immediately my head started swimming again. I see how shaders can select textures and how the shaders are loaded into a slot. How do you bind to a particular shader when you draw?  Is it the call to SetVertexBuffers?

 

What do you mean by "how do you bind to a particular shader"? As I explained, you don't. You bind all types of resources (shader, textures, vertexbuffer), ... to the device, which acts like a state-machine. And then when you draw, the GPU executes the shader with all the other resources that are currently bound as input :)

Edited by Juliean

Share this post


Link to post
Share on other sites

Thank you for your patience. I don't have a clear picture in my head of the relationship between the slots, the shader code and which shader code will be called for a given call to Draw(). I've been looking through the sample code to try to connect the dots. I see these calls on the device context. Are these calls where the current shaders are set?

 

 

  DeviceContext.VertexShader.Set(VertexShader);
  DeviceContext.PixelShader.Set(PixelShader);
 

If this is how the shader code is set, would I use VertexShader_ONE and VertexShader_TWO like this?

 

// Set the first shader

  DeviceContext.VertexShader.Set(VertexShader_ONE);

 

 // Draw the first shape

 DeviceContext.Draw(Shape1Triangle)

 

 // Set the second shader

  DeviceContext.VertexShader.Set(VertexShader_TWO);

 

 // Draw the second shape

 DeviceContext.Draw(Shape2Triangle)

 

 

John

Share this post


Link to post
Share on other sites

Yep thats basically it.

 

The cost of switching shaders like this is generally non-free so be wary of doing thousands of shader switches per frame. It's best to batch them, for example.

Edited by Dave

Share this post


Link to post
Share on other sites

Thank you! This suggests that a render loop should be based on the shaders first. Although a shader is a property of a mesh you should think about it in terms of meshes being a list associated with the shader, like this:

 

foreach (shader s in ListOfShaders) {

  

     s.SetAsCurrentShader();

 

     foreach (Mesh m in s.ListOfMeshes) {

             m.Draw();

     }

 

}

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!