DrawInstanced problem

Started by
8 comments, last by hupsilardee 11 years, 4 months ago
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.
Advertisement
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.
I have never thought about instances inside a vertex buffer, where can i found more about that. I thought an instance could only be a whole vertex buffer.
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.
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.
Think of it this way (pseudo 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);
}
}
}


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.
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.

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.


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!
You can, but I think the vertex buffer is a better idea. And the 4th parameter only matters if you are using the vertex buffer to pass instances data.

You can, but I think the vertex buffer is a better idea.


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


// 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
...
}


fairly contrived example I concede

This topic is closed to new replies.

Advertisement