Sign in to follow this  
lomateron

DrawInstanced problem

Recommended Posts

lomateron    491
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
Such1    435
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
lomateron    491
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.

Share this post


Link to post
Share on other sites
Such1    435
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
lomateron    491
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
CryZe    773
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
Such1    435
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.

Share this post


Link to post
Share on other sites
kauna    2922
[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
Such1    435
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.

Share this post


Link to post
Share on other sites
hupsilardee    491
[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