Search code examples
xnahardware

Hardware Instancing for Primitives


I have read about hardware instancing. I wanted to apply it to primitives instead of models. But my question is: I want to draw a circle build by vertices(in total 6300 Vertices for all circles)

Do I have to set a transform matrix for every vertex?

Thank you in advance


Solution

  • This is what MSDN has to say on GraphicsDevice.DrawInstancedPrimitives

    This method provides a mechanism for gathering vertex shader input data from different streams at different frequencies (typically by interpreting one data stream as a per-instance world transform); this approach requires a custom shader to interpret the input data. For more information, see DrawInstancedPrimitives in XNA Game Studio 4.0. Tell me more

    Returning to your question:

    Do I have to set a transform matrix for every vertex?

    No you don't. The instance (not each vertex) will have a transform that you bind to your shader prior to rendering. A model/instance will have a transform describing it's position in the world. Each vertex is essentially a relative coordinate describing an offset from the model's origin.

    e.g. courtesy of Shawn Hargreaves Blog

    float4x4 WorldViewProj;
    
    void InstancingVertexShader(inout float4 position : POSITION0,
                                in float4x4 world : TEXCOORD0)
    {
        position = mul(mul(position, transpose(world)), WorldViewProj);
    }
    

    ...your XNA code: again courtesy of Shawn Hargreaves Blog

    instanceVertexBuffer.SetData(instanceTransformMatrices, 0, numInstances, SetDataOptions.Discard);
    
    graphicsDevice.SetVertexBuffers(modelVertexBuffer, new VertexBufferBinding(instanceVertexBuffer, 0, 1));
    graphicsDevice.Indices = indexBuffer;
    instancingEffect.CurrentTechnique.Passes[0].Apply();
    
    graphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0,
                                           modelVertexBuffer.VertexCount, 0,
                                           indexBuffer.IndexCount / 3,
                                           numInstances);