3
\$\begingroup\$

How do you implement per instance textures, vertex shaders, and pixel shaders?

Given:
1. Two different model templates in Vertex Buffer, Square & Triangle 2. Instance Buffer with [n] instances of type Square or Triangle.

How do I add a Texture, VertexShader or PixelShader ID to the buffer data so that HLSL or the InputAssembly can determine which Shader to use at draw time?

A. How do I "Set" multiple Pixel and Vertex Shaders into the DeviceContext, and how do I tell DirectX to "switch" the Vertex Shader that is loaded at render time?

B. How many Shaders of each type, (Vertex, Pixel, Hull, etc), can I associate with model templates in the default Vertex Buffer?

C. Can I use some sort of Shader Selector in HLSL?

Related C++ Code

When I create an input layout, can I do this without specifying an actual Vertex Shader, or somehow specify more than one?

NS::ThrowIfFailed(
result = NS::DeviceManager::Device->CreateInputLayout(
NS::ModelRenderer::InitialElementDescription,
2,
vertexShaderFile->Data,
vertexShaderFile->Length,
& NS::ModelRenderer::StaticInputLayout
)
);

When I set the VertexShader and PixelShader, how do I associate them with a particular model in my VertexBuffer? Is it possible to set more than one of each?

DeviceManager::DeviceContext->IASetInputLayout(ModelRenderer::StaticInputLayout.Get());

DeviceManager::DeviceContext->VSSetShader(ModelRenderer::StaticVertexShader.Get(), nullptr, 0);
DeviceManager::DeviceContext->PSSetShader(ModelRenderer::StaticPixelShader.Get(), nullptr, 0);
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

You can't draw with multiple vertex or pixel shaders at the same time. GPUs don't work that way. To render objects with different shaders, you sequentially set one shader, draw the objects for it, set another shader, draw its objects, etc.

for each (vertex, pixel) shader pair:
    set vertex shader in the device context
    set pixel shader in the device context
    set textures
    set constant buffers
    draw geometry for objects that use these shaders

That being said, it's possible to fold multiple shaders into one by using branches. For example, you could have a flag in your vertex format that says whether to use vertex shader A or B, where the code for A and B are actually both in one vertex shader and it uses an if-statement to decide which one to run. This may or may not be faster than having separate shaders and separate draw calls, depending on circumstances. Similarly, one can fold multiple textures into one by using a texture atlas or a texture array.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks Nathan! How would I change the VertexShader's output dynamically so a different pixel shader could be called? If I had set 2 pixel shaders already, (perhaps with different input signatures), how could I output a different type from the VertexShader so a specific Pixel Shader would be called? I have been trying to bury myself in documentation about class linkages, interfaces, etc, but no luck. I was wondering if there is a way to specify input parameters for pixel shaders that are interfaces, but have vertex and geometry shaders dynamically output different interface types. \$\endgroup\$ Jan 28, 2013 at 18:47
  • \$\begingroup\$ @WindAndFlame There is no way to do that. That's what I was trying to explain; at any given time there can be at most ONE vertex shader and ONE pixel shader active in the pipeline. To use multiple shaders, you use them sequentially, not simultaneously - you set one shader, draw some stuff, then set another shader and draw some more stuff. If two pixel shaders require different inputs, then they should have accompanying vertex shaders that generate those inputs. \$\endgroup\$ Jan 28, 2013 at 19:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .