Instancing

Started by
1 comment, last by osiris11 12 years, 1 month ago
Hey.

I have been following this tutorial , but while experimenting I reached a dead end. The addition I was trying to implement is a dynamic updating rotation per instance.

So first, i define


// TriangleTest.h
struct InstanceType
{
D3DXVECTOR3 position;
D3DXVECTOR3 rotation;
};

for my Instance buffer Type, which leads me to define


// vertexshader.vs
struct VertexInputType
{
float3 position : POSITION;
float4 color : COLOR;
float3 instancePosition : POSITION1;
float3 instanceRotation : POSITION2;
};

in my vertex Shader file. Note that I have changed the usage of semantic type TEXCOORD from the tutorial, as I feel more comfortable having positions use POSITION, as well as giving the position a float3 type.

I set up my InputElementDescription array like this


//shaderclass.cpp
polygonLayout[0].SemanticName = "POSITION";
polygonLayout[0].SemanticIndex = 0;
polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
polygonLayout[0].InputSlot = 0;
polygonLayout[0].AlignedByteOffset = 0;
polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
polygonLayout[0].InstanceDataStepRate = 0;
polygonLayout[1].SemanticName = "COLOR";
polygonLayout[1].SemanticIndex = 0;
polygonLayout[1].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
polygonLayout[1].InputSlot = 0;
polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
polygonLayout[1].InstanceDataStepRate = 0;
polygonLayout[2].SemanticName = "POSITION";
polygonLayout[2].SemanticIndex = 1;
polygonLayout[2].Format = DXGI_FORMAT_R32G32B32_FLOAT;
polygonLayout[2].InputSlot = 1;
polygonLayout[2].AlignedByteOffset = 0;
polygonLayout[2].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
polygonLayout[2].InstanceDataStepRate = 1;
polygonLayout[3].SemanticName = "POSITION";
polygonLayout[3].SemanticIndex = 2;
polygonLayout[3].Format = DXGI_FORMAT_R32G32B32_FLOAT;
polygonLayout[3].InputSlot = 1;
polygonLayout[3].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
polygonLayout[3].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
polygonLayout[3].InstanceDataStepRate = 1;


and create the input layouts.
In my model class (TriangeTest), i use this to update the dynamic instance buffer ( completely created as D3D11_USAGE_DYNAMIC, with D3D11_CP_ACCESS_WRITE)


void TriangleTest::Frame(ID3D11DeviceContext* deviceContext) {
for (int i = 0; i < this->i_instanceCount; i++) {
D3DXVec3Add(&(m_instanceList.rotation), &(m_instanceList.rotation), &D3DXVECTOR3(1,0,0.0f));
}
UpdateBuffers(deviceContext);
}
void TriangleTest::UpdateBuffers(ID3D11DeviceContext* deviceContext) {
HRESULT result;
D3D11_MAPPED_SUBRESOURCE mappedResource;
InstanceType* instancePtr;

result =deviceContext->Map(m_instanceBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if(FAILED(result)) throw CException("Could not remap instance buffer");
instancePtr = (InstanceType*)mappedResource.pData;
memcpy(instancePtr, (void*)m_instanceList, (sizeof(InstanceType) * i_instanceCount));
deviceContext->Unmap(m_instanceBuffer, 0);
}

, where m_instanceList is an array of InstanceType holding all information on the position and rotation per triangle. Of course, theFrame(...) function gets called once per frame.

Then I use the shader as provided and replace instancePosition with instanceRotation,which should make my triangles slide out to the right.


PixelInputType TextureVertexShader(VertexInputType input)
{
PixelInputType output;

// Change the position vector to be 4 units for proper matrix calculations.
input.position.w = 1.0f;
Here is where we use the instanced position information to modify the position of each triangle we are drawing.
// Update the position of the vertices based on the data for this particular instance.
input.position.x += input.instanceRotation.x;
input.position.y += input.instanceRotation.y;
input.position.z += input.instanceRotation.z;
// Calculate the position of the vertex against the world, view, and projection matrices.
output.position = mul(input.position, worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);

// Store the texture coordinates for the pixel shader.
output.tex = input.tex;

return output;
}


But when I run it (complete without errors), the triangles stay still on the screen. Even when using instancePosition again. They move however, if I change the semantic type of inputPosition to TEXCOORD and update the position in the Frame procedure, but even then I get no motion from the instanceRotation.

Which leads me to think, that my InputElementLayoutDescription is wrong. But how? I have tried many a combination already, but don't understand.

Can anyone enlighten me with their ideas?
Advertisement
I'm taking a bit of a guess here but it might be because your first semantic usage of POSITION is not POSITION0 (zero) which is causing the binding to fail for some reason; try giving it the semantic POSITION0 and see if that helps.
That actually did the trick.
Thank you so very much, i thought I had tried this before, but my mind was so messed up with this, I screwed it completely and tested it with some update code disabled. I was already going to tell you how it doesn't work, but kept trying once more to consider your answer, and Voila.

It actually works.

This topic is closed to new replies.

Advertisement