Sign in to follow this  
lomateron

DrawInstanced problem

Recommended Posts

I suppose DrawInstanced() 4th parameter, last parameter, makes this...
If i have this
DrawInstanced( 1, 80000,0,1 );
it should draw 79999 intances and when drawing the first intace, in the vertex shader, the SV_InstanceID variable starts with 1 intead of 0.
But it doesnt matters what number I put in the 4th parameter, it does the same thing as DrawInstanced( 1, 80000,0,0 );... it can even be bigger that 80000 and there is no difference.

I just want to know if what i think the 4th parameter does is correct. Edited by lomateron

Share this post


Link to post
Share on other sites
It doesn't add to SV_InstanceId, the only difference is on the vertex buffer on the instance part. the SV_InstanceID 0 should have the data from the second instance on the vertex buffer. Hope I made myself clear. Edited by Such1

Share this post


Link to post
Share on other sites
Sorry, I guess you didn't understand.
You have this:(hypotetically)
VERTEX* vertexBuffer0;
INSTANCE* vertexBuffer1:

that 4th parameter change which one will be the SV_InstanceID data. If you say the 4th parameter is x, the hypotetical formula would be:
InstanceData = vertexBuffer1[SV_InstanceID + x];

I think this way is easier to understand.

Share this post


Link to post
Share on other sites
wait!... i still dont undesrtand
isn't the data the same in all intances?
"data" is the vertex buffer
i dont understand your second post
you could tell me what DrawInstanced( 1, 80000,0,1 ); is really doing to explain me, supposing that the vertex buffer just has one vertice in it... or 3 if that 4th parameter doesn't works when you have just 1 vertice. Edited by lomateron

Share this post


Link to post
Share on other sites
Think of it this way (pseudo code):

[CODE]
void DrawInstanced(..., int vertexCount, int instanceCount, ...)
{
for (int instanceId = 0; instanceId < instanceCount; instanceId++)
{
for (int vertexId = 0; vertexId < vertexCount; vertexId++)
{
Vertex vertex;
for (int inputLayoutIndex = 0; inputLayoutIndex < inputLayout.getCount(); inputLayoutIndex++)
{
InputLayoutElement element = inputLayout.get(inputLayoutIndex);
int vertexBufferIndex = element.getVertexBufferIndex();
int vertexBufferOffset = element.getVertexBufferOffset();

VertexBuffer vertexBuffer = vertexBuffers[vertexBufferIndex];
int stride = vertexBuffer.getByteStride();

Object value;
if (element.getClassification() == Classification.Instance)
{
value = vertexBuffer[instanceId * stride + vertexBufferOffset];
}
else
{
value = vertexBuffer[vertexId * stride + vertexBufferOffset];
}

String semantic = element.getSemantic();
vertex.setValue(semantic, value);
}

VertexShader(vertex);
}
}
}
[/CODE]

That means that your input layout could look like this:

[Semantic, VertexBufferIndex, VertexBufferOffset, Classification]
["VERTEX_VALUE_0", 0, 0, Vertex]
["VERTEX_VALUE_1", 0, 8, Vertex]
["VERTEX_VALUE_2", 0, 16, Vertex]
["INSTANCE_VALUE_0", 1, 0, Instance]
["INSTANCE_VALUE_1", 1, 8, Instance]

You than simply use 2 vertex buffers:

VertexBuffer 0: [[vertexValue0, vertexValue1, vertexValue2], [vertexValue0, vertexValue1, vertexValue2], [vertexValue0, vertexValue1, vertexValue2], ...]
VertexBuffer 1: [[instanceValue0, instanceValue1], [instanceValue0, instanceValue1], [instanceValue0, instanceValue1], ...]

And it basically takes a cartesian product of both sets to call the vertex shader. Edited by CryZe

Share this post


Link to post
Share on other sites
[quote name='Such1' timestamp='1354051979' post='5004684']
When you have intance drawing you have 2 vertex buffers, one for the vertices and the other for the instances data. I guess thats what you are confused about.
[/quote]

You don't necessary need a second vertex stream for the instancing data. DrawInstanced provides you a instance ID in the shader and it may be used to index a constant buffer or generic buffer object.

Cheers! Edited by kauna

Share this post


Link to post
Share on other sites
[quote name='Such1' timestamp='1354080698' post='5004855']
You can, but I think the vertex buffer is a better idea.
[/quote]

Sometines you might not even need any per instance data, you could generate it in the vertex shader. For example if I was drawing an NxN square of objects I might do

[code]
// game code
int squareSide = 10;
SetVertexShaderInt("SquareSide", squareSide);
DrawInstanced(numVertices, squareSide*squareSide);

// shader
int SquareSide;

VertexShader(instanceID : SV_INSTANCEID)
{
instance_pos.x = instanceID / SquareSide;
instance_pos.z = instanceID % SquareSide
...
}
[/code]

fairly contrived example I concede

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this