locked
More than one vertex/pixel shaders in one project

    Question

  • I'm new to D3D11 and trying to port our OpenGL desktop application to Windows RT. In our project, we are inclined to write more than one vertex/pixel shaders. For now we have written two vertex shaders, one for solid color objects and the other for texture-mapped objects. And at runtime we switch vertex shaders for each type of objects using VSSetShader() method. The vertex shader for colored object is defined as:

    cbuffer cbPerObject : register(b0)
    {
        matrix model; 
        matrix view; 
        matrix projection; 
        float4 penColor;
    };
    
    struct VertexShaderInput
    {
        float3 pos : POSITION;
        float4 color : COLOR;
    };
    
    struct PixelShaderInput
    {
        float4 pos : SV_POSITION;
        float4 color : COLOR;
    };
    
    // Vertex shader for textureless object
    PixelShaderInput ColorVertexShader(VertexShaderInput input)
    {
       PixelShaderInput output;
    
       float4 pos = float4(input.pos, 1.0f);
       pos = mul(pos, model);
       pos = mul(pos, view);
       pos = mul(pos, projection);
       output.pos = pos;
       output.color = penColor;
    
       return output;
    }
    

    The vertex shader for textured object is

    cbuffer cbPerObject : register(b0)
    {
        matrix model; 
        matrix view; 
        matrix projection; 
        float4 penColor;
    };
    
    struct VertexShaderInput
    {
        float3 pos : POSITION;
        float2 tex : TEXCOORD;
    };
    
    struct PixelShaderInput
    {
        float4 pos : SV_POSITION;
        float2 tex : TEXCOORD;
    };
    
    // Vertex shader for textureless object
    PixelShaderInput TextureVertexShader(VertexShaderInput input)
    {
       PixelShaderInput output;
    
       float4 pos = float4(input.pos, 1.0f);
       pos = mul(pos, model);
       pos = mul(pos, view);
       pos = mul(pos, projection);
       output.pos = pos;
       output.tex = input.tex;
    
       return output;
    }
    

    Although the build is successful, I am not sure whether it's the best way to solve our problem to draw graphics objects of different types. Would the redefinition of cbPerObject, VertexShaderInput, and PixelShaderInput cause potential issues? After all, most of the Windows 8 D3D code samples include one vertex shader in the project.

    Sunday, July 29, 2012 1:49 PM

Answers

  • What you've done here is fine.  Each compiled shader acts like a separate program that will run on the GPU.  So that means that all constants and global resources your shader needs must have definitions at compile time.  You could consider moving the duplicate code to a shader header file and just #include that.  Even the model transform code could be moved to a separate function that both shaders call.  Moving this code won't incur any additional runtime const since the code will get inlined by the compiler.

    The D3D code samples are just samples and not indicative of a normal applications which would likely have a larger number of shaders.


    Monday, July 30, 2012 6:10 PM

All replies

  • What you've done here is fine.  Each compiled shader acts like a separate program that will run on the GPU.  So that means that all constants and global resources your shader needs must have definitions at compile time.  You could consider moving the duplicate code to a shader header file and just #include that.  Even the model transform code could be moved to a separate function that both shaders call.  Moving this code won't incur any additional runtime const since the code will get inlined by the compiler.

    The D3D code samples are just samples and not indicative of a normal applications which would likely have a larger number of shaders.


    Monday, July 30, 2012 6:10 PM
  • Thanks Dieter.
    Tuesday, July 31, 2012 9:06 AM