VertexShader consts for instancing

Started by
1 comment, last by HeroOfSpielburg 16 years, 4 months ago
Hello, I'm writing something similar to a particle engine, where I have a bunch of quads in a vertex buffer, and modify each quad via two transform structures, child and parent, in the vertex shader.
struct SpriteParent
{
	float4		mtxParentRS;		// Parent sprite rot/scl
	float4		fParentPosAlpha;	// Parent position and alpha
};

struct SpriteChild
{
	float4		mtxChildRS;		// Child primitve rot/scl
	float4		fTextureUVAlpha;	// UV offset (pattern) and alpha	
};
So I can reference them easily in HLSL, I define a couple of arrays in the shader file as well.
SpriteParent		g_SpriteParents[30];	
SpriteChild		g_SpriteChildren[90];
The number of "child" primitives per "parent" sprite is variable, so the ratio of SpriteParent to SpriteChild structures that I actually use changes per DrawIndexedPrimitive call. Although I define 90 children in the shader, I may not use them all, or may actually need more if the ratio of Children:Parent is quite high. I keep track of which structures to reference for each quad primtive via blend indicies in the vertex data, and upload batches of the SpriteParent and SpriteChild structures via ID3DXConstantTable::SetFloatArray. The problem is I run into trouble when I need to access more Parent or Child structures than I define as above in the shader file; I get a D3D error telling me that the handle to the structure element is not defined. If I define the structure arrays to have the maximum possible amount utilized in any configuration, the collective size is larger than can fit in constant register memory, and the shader doesn't compile. Is there a way to manage the allocation of these structures in the shader more dynamically so I can get the optimal packing I'm calculating on the game engine side? Or do I have to abandon user-defined structures then and write my shader in terms of pure constant registers and address offsets? (Never done this before, a little leery.) Thank you for the advice!
Advertisement
As both structures just consist of two float4s then I think your simplest option is to merge them into one big array, and pass in the index of where the second half of the array starts as a constant.
You're right, this will provide optimal throughput without requiring much change to my shader. Thanks for the insight, I was buried in the details. :)

The only downside is when/if either of the data parameters needed in the parent or child struct changes to a different number of register lines, things start to get a little tricky, at which point I'll probably have to move to just a general "I have a very large array of float4s" and further generalize the structure element names.

Thank you again.

This topic is closed to new replies.

Advertisement