0

How do you implement per instance textures, vertex shaders, and pixel shaders, in the same Vertex Buffer and/or DeviceContext?

I am just trying to find the most efficient way to have different pixel shaders used by the same type of mesh, but colored differently. For example, I would like square and triangle models in the vertex buffer, and for the vertex/pixel/etc shaders to act differently based on instance data.... (If the instance data includes "dead" somehow, the shaders used to draw opaque shapes with solid colors rather than gradients are used.

Given: 1. Different model templates in Vertex Buffer, Square & Triangl, (more eventually).

  1. Instance Buffer with [n] instances of type Square and/or Triangle, etc.

Guesses: Things I am trying to Research to do this:

A: Can 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?

B. Can 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?

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

D. 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);
e.s. kohen
  • 213
  • 1
  • 4
  • 21

1 Answers1

0

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?

You can't assign a Pixel Shader ID to a buffer, that's not how the pipeline works.

A / You can bind only one Vertex/Pixel Shader in a Device context at a time, which defines your pipeline, draw your geometry using this shader, then switch to another Vertex/Pixel shader as needed, draw next geometry...

B/ you can use different shaders using the same model, but that's done on cpu using VSSetShader, PSSetShader....

C/No, for same reason as in B (shaders are set on the CPU)

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

if you don't specify a vertex shader, the pipeline will consider that you draw "null" geometry, which is actually possible (and very fun), but bit out of context, if you provide geometry you need to send the vertex shader data so the runtime can match your geometry layout to the vertex input layout. You can of course create several input layouts by calling the function several times (once per vertex shader/geometry in worst case, but if two models/vertex shaders have the same layout you can omit it).

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?

You bind everything you need (Vertex/Pixel shaders, Vertex/IndexBuffer,Input layout) and call draw (or drawinstanced).

mrvux
  • 8,523
  • 1
  • 27
  • 61
  • I am trying to wrap my head around CPU vs GPU shaders. You say that I can set CPU shaders using VSSetShader, but in the code above, the syntax is DeviceContext->VSSetShader ... You said that I can use different shaders on the same model, are you implying that I would have to reset the InputLayout, but reuse the same model buffer? I edited the question description a little, to hopefully clarify. Thank you for your thoroughness. – e.s. kohen Jan 30 '13 at 01:38
  • shaders are all executed on the gpu, when you call VSSetShader and send the shader bytecode you instruct your graphics card that for the next draw call your should use this specific vertex shader. And indeed it's of course possible to reuse same model with different shader, Input layout tells the input assembler (before vertex shader is called) how to organize data to be read from the model and sent to the vertex shader, so in some cases you can reuse same layout, some cases you can't. – mrvux Jan 30 '13 at 13:26
  • Are you implying that most people do this in phases like: Initialize Phase: Create Buffer, SetVertices, SetShaders, SetLayout, DrawInstance; then cycle through all: [UpdateVertices, [Update Shaders, [Set Layout, [DrawInstanced] * repeat Draw Instanced ] * repeat Set Layout] * repeat Update Shaders ] * Repeat Update Vertices] ? Can you set all the different shader types at once to the GPU so you don't have to copy from CPU to GPU all the time, and just update your input layout when you want to switch shaders? Or is that the constraint you mentioned with 1 vertex shader per Context. – e.s. kohen Jan 30 '13 at 17:58
  • Initialize is: Create buffers/Create layouts/Create shaders Then on update/draw : assign shader/layout/geometry, update geometry position if needed and call draw. You don't have to copy shaders all the time, once you have created them they sit on your gpu (same for buffers and layouts), so VSSetshader just tells gpu to use this one, but it doesn't upload it (it's already there, you just provide reference to it). – mrvux Jan 30 '13 at 19:15
  • VSSetShader doesn't recopy, but just points the a specific shader from the Device toe the layout? Is there a "buffer" of shaders somewhere? What are the associations? 1 Device: 1 Context; 1 Device : [n] Shaders; Context : [n] Input Layout; Input Layout : [n] Buffers ... ? Sorry, I know these are really basic questions, but I can't find this diagram anywhere. I found this on Texture Buffers, but I am trying to figure out how to map this to Input Layout: http://msdn.microsoft.com/en-us/library/windows/desktop/bb509581(v=vs.85).aspx – e.s. kohen Feb 01 '13 at 05:45