Highly Lazy Slacker Life (the series)

After being extremely lazy, I decided to get back into hobbyist programming. This time, I'm looking at shader programming, which is something I've always been interested in. Like last time, I'm in XNA, coding in C# and HLSL.

So, it's not really obvious... or at least, I don't know if it's in some help file somewhere, but a point of confusion happened when I was looking at some sample code for shader effects.

Now, when loading models using the generic Model class... I guess if you load them up without doing anything else to them, have the VertexDeclaration...

Vector3 Position
Vector3 Normal
Vector2 TextureCoordinate

... which makes total sense. Again, I don't know if that's documented somewhere, but it's what I'd expect, and it's what shows when I crack into the model's data.

However, these shader effects were declaring their inputs...

float4 Position : POSITION0
float3 Normal : NORMAL0
float2 TexCoord : TEXCOORD0

Now, the thing about this is, if we were being really fast compiler creators and blaming everything on the people who use your langauge, then I'd expect something like a straight memcpy or something going on.

What confused me for a second was if you look at the Position variables, the one in the vertex buffer is Vector3, but the input to the shader is float4. This means that memory looks like...

Buffer: (Position.x, Position.y, Position.z, Normal.x, Normal.y, ... )
Shader: (Position.x, Position.y, Position.z, Position.w, Normal.x, ... )

How's the shader know not to stick the buffer's Normal.x into the shader input Position.w?

I guess it turns out that whatever links up to the shader just knows, probably looking at the buffer's VertexDeclaration or something and filling things automatically. In fact, in the shader input, you can overallocate to Normal or TexCoord by declaring them as float4's, and the shader would still be padding values.

Based on what I looked at, the padded values are what I'd expect: if you allocate too many floats in your shader input than is in your buffer's VertexDeclaration, it will pad all the values with 0.0, except for the last w or alpha component, which will be 1.0.

Pretty convenient. I'm glad I don't have to do that myself.