Can I use an array in my vertex input layout?

Started by
4 comments, last by cephalo 11 years, 1 month ago

Here is what I want to do in my dx11 vertex shader:


struct VertexInput
{
	//imediate data
	float3 PositionLocal		: POSITION;
	int index		        : TEXCOORD;
	//instance data
	float3 Translation		: NORMAL;
	float Altitudes[3]		: TEXCOORD;
};

struct VertexOutput
{
	float3 PositionWorld	: POSITION;
	float2 MainTexCoord	: TEXCOORD;
};

VertexOutput VS(VertexInput vin)
{
	VertexOutput vout;

	//Add altitudes
	float3 transPos = vin.PositionLocal + vin.Translation;
	transPos.y += vin.Altitudes[vin.Index];

	vout.MainTexCoord = transPos.xz;
	vout.PositionWorld = transPos;

	return vout;
}

Is it allowed to use an array this way in dx11? I can easily fake it with swizzling I suppose, but I would prefer that the code convey its meaning more clearly. What would be the proper way to create the input elements for an array?

Advertisement
Yes, this is possible. You can specify this in your input layout with the semantic index.

So, would I specify that each element in the array is its own element in the input layout, or should I just use a three element R32G32B32_FLOAT and access it with an index? I'm still kindof new to dx11, so I'm unsure exactly how to do this properly. In dx9 I would have just used a vector3 and swizzled x for 0, y for 1 and z for 2.

EDIT: The fact that my array only has three elements confounds what I'm trying to learn here, since its easy to access a Vector3 with an index. What if I wanted an array in my input stream with 10 elements though? Would that be possible? I have no idea how to set that up.

For a 3-element array the corresponding input layout would look something like this:


{"TEXCOORD", 0, DXGI_FORMAT_R32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1},
{"TEXCOORD", 1, DXGI_FORMAT_R32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1},
{"TEXCOORD", 2, DXGI_FORMAT_R32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1},

(I set this up as per-instance in slot 1 with a step-rate of 1 based on the comment in your VertexInput struct that this is for instance data).

Note that the semantic name is "TEXCOORD" for all 3 elements, but semantic index goes 0/1/2; then your VertexInput can stay the exact same as it currently is; i.e defining "float Altitudes[3] : TEXCOORD;".

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.


struct VertexInput
{
float3 PositionLocal : POSITION;
int index : TEXCOORD;
float3 Translation : NORMAL;
float3 Altitudes : TEXCOORD;
};

If your Altitudes is defines as float3 (as above), you may access xyz-elements as Altitudes[0], Altitudes[1] .. etc, while using R32G32B32_FLOAT in your vertex declarations.

Cheers!

Thanks everyone for the replies.


struct VertexInput
{
float3 PositionLocal : POSITION;
int index : TEXCOORD;
float3 Translation : NORMAL;
float3 Altitudes : TEXCOORD;
};

If your Altitudes is defines as float3 (as above), you may access xyz-elements as Altitudes[0], Altitudes[1] .. etc, while using R32G32B32_FLOAT in your vertex declarations.

Cheers!

This seems a very easy way to do it, but for completeness sake I have a question. In previous shader models, swizzling Altitudes[0], Altitudes[1] etc. is NOT the same as saying Altitudes[vin.index] because the previous example is resolvable at compile time, while the latter can only be resolved at run time.

So the question is, in DX11, can I use a variable index for swizzling at run time? As per the OP,can I use Altitudes[vin.index] if Altitudes is a float3 in a single register?

This topic is closed to new replies.

Advertisement