How do I put a 32 bit integer in a VertexDeclaration?

Hey everyone,

Let’s say I want to send a 32 bit integer to my vertex shader in HLSL:

struct VertexShaderInput { ... int Index : TEXCOORD2; };

How would I put the integer into my custom VertexDeclaration? There doesn’t seem to be a VertexElementFormat for ‘Int32’ or anything similar.

Thanks!

honest advice pass in a float and trunc it if need be.

dunno if this will work i would think single and blend indices would work but i actually use floats for my models blend indices which the shader is fine with.
new VertexElement(0, VertexElementFormat.Single, VertexElementUsage.BlendIndices, 0),

I would guess, there is none, because the GPU used to work with floats. If you can live with a smaller rang, there is Short2 and Short4.

Personally I tend to use any unused component of any existing semantics in the declaration … because - I believe - in the hardware it gets expanded to float4 anyway. For the UVs in my Voxel Engine I currently use Vec3 and use the z as the index in the texture array

Ya the gpu has some unexpected indexing magical abilitys as well.
(i say magical cause i don’t know the specifics of how it index’s with floats)

Take for instance the following code.
Specifically the Bones[input.BlendIndices.x]

You might think logically you need to have integers in the shader for indexing ?.

But

//_______________________________________________________________
// techniques 
// Skinned draw.
//_______________________________________________________________
VsOutputSkinnedQuad VertexShaderSkinnedDraw(VsInputSkinnedQuad input)
{
    VsOutputSkinnedQuad output;
    float4 pos = mul(input.Position, World);

    float weightA = input.BlendWeights.x;
    float weightB = input.BlendWeights.y;
    float weightC = input.BlendWeights.z;
    float weightD = input.BlendWeights.w;
    float sum = weightA + weightB + weightC + weightD;
    weightA = weightA / sum;
    weightB = weightB / sum;
    weightC = weightC / sum;
    weightD = weightD / sum;

    pos =
    mul(pos, Bones[input.BlendIndices.x]) * weightA +
    mul(pos, Bones[input.BlendIndices.y]) * weightB +
    mul(pos, Bones[input.BlendIndices.z]) * weightC +
    mul(pos, Bones[input.BlendIndices.w]) * weightD;

    float4 col =
    float4(0.10f, 0.99f, 0.99f, 1.0f) * weightA +
    float4(0.99f, 0.99f, 0.10f, 1.0f) * weightB +
    float4(0.99f, 0.10f, 0.99f, 1.0f) * weightC +
    float4(0.50f, 0.70f, 0.59f, 1.0f) * weightD;
    col = saturate(col);

    // Visualization alter the color depending on the bone number.      //float4 bonecol = colArray[((input.BlendIndices.x +1.0f) % colArrayCount)];
    float4 bonecol = colArray[fmod((input.BlendIndices.x + 1.0f), (colArrayCount)) * (colArrayCount - 1.0f)];

    output.Color =
    (
    col * 3 +   // 5
    bonecol * 2 +  // 3
    (col * bonecol) * 5  //2
    )
    * 0.10f;

    
    float4x4 vp = mul(View, Projection);
    output.Position = mul(pos, vp);
    output.TexureCoordinateA = input.TexureCoordinateA;
    return output;
}

Those really are floats.

namespace GLAssimpModelLoader
{
    /// <summary>
    /// basically a full spectrum vertice structure.
    /// </summary>
    public struct VertexPositionTextureNormalTangentWeights : IVertexType
    {
        public Vector3 Position;
        public Vector3 Normal;
        public Vector2 TextureCoordinate;
        public Vector3 Tangent;
        public Vector4 BlendIndices;
        public Vector4 BlendWeights;

        public static VertexDeclaration VertexDeclaration = new VertexDeclaration
        (
              new VertexElement(VertexElementByteOffset.PositionStartOffset(), VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
              new VertexElement(VertexElementByteOffset.OffsetVector3(), VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),
              new VertexElement(VertexElementByteOffset.OffsetVector2(), VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0),
              new VertexElement(VertexElementByteOffset.OffsetVector3(), VertexElementFormat.Vector3, VertexElementUsage.Normal, 1),
              new VertexElement(VertexElementByteOffset.OffsetVector4(), VertexElementFormat.Vector4, VertexElementUsage.BlendIndices, 0),
              new VertexElement(VertexElementByteOffset.OffsetVector4(), VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 0)
        );
        VertexDeclaration IVertexType.VertexDeclaration { get { return VertexDeclaration; } }
    }
    /// <summary>
    /// This is a helper struct for tallying byte offsets
    /// </summary>
    public struct VertexElementByteOffset
    {
        public static int currentByteSize = 0;
        //[STAThread]
        public static int PositionStartOffset() { currentByteSize = 0; var s = sizeof(float) * 3; currentByteSize += s; return currentByteSize - s; }
        public static int Offset(int n) { var s = sizeof(int); currentByteSize += s; return currentByteSize - s; }
        public static int Offset(float n) { var s = sizeof(float); currentByteSize += s; return currentByteSize - s; }
        public static int Offset(Vector2 n) { var s = sizeof(float) * 2; currentByteSize += s; return currentByteSize - s; }
        public static int Offset(Color n) { var s = sizeof(int); currentByteSize += s; return currentByteSize - s; }
        public static int Offset(Vector3 n) { var s = sizeof(float) * 3; currentByteSize += s; return currentByteSize - s; }
        public static int Offset(Vector4 n) { var s = sizeof(float) * 4; currentByteSize += s; return currentByteSize - s; }

        public static int OffsetInt() { var s = sizeof(int); currentByteSize += s; return currentByteSize - s; }
        public static int OffsetFloat() { var s = sizeof(float); currentByteSize += s; return currentByteSize - s; }
        public static int OffsetColor() { var s = sizeof(int); currentByteSize += s; return currentByteSize - s; }
        public static int OffsetVector2() { var s = sizeof(float) * 2; currentByteSize += s; return currentByteSize - s; }
        public static int OffsetVector3() { var s = sizeof(float) * 3; currentByteSize += s; return currentByteSize - s; }
        public static int OffsetVector4() { var s = sizeof(float) * 4; currentByteSize += s; return currentByteSize - s; }
    }
}

Thanks for the replies everyone! In the end, I have changed my vertex data so I shouldn’t need the indices any more, but it’s still useful to know.

Also I discovered for myself that floats can be used as indices with seemingly no issues - cool!