Jump to content
  • Advertisement
Sign in to follow this  
osiris11

DX11 Instancing

This topic is 2487 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!