# DirectX particle system. ConstantBuffer

I'm new in DirectX and I'm making a 2D game. I want to use a particle system to simulate a 3D starfield, so each star has to set its own constant buffer for the vertexshader es. to set it's world matrix. So if i have 500 stars (that move every frame) i need to call 500 times VSsetconstantbuffer, and map/unmap each buffer. with 500 stars i have an average of 220 fps and that's quite good. My bottelneck is Vs/PsSetconstantbuffer. If i dont call this function i have 400 fps(obliviously nothing is display, since i dont set the position of the stars). So is there a method to speed up the render of the particle system??

Ps. I'm using intel integrate graphic (hd 2000-3000). with a nvidia (or amd) gpu will i have the same bottleneck?? If, for example, i dont call setshaderresource i have 10-20 fps more (for 500 objcets), that is not 180.Why does SetConstantBuffer take so long??

LPVOID VSdataPtr = VSmappedResource.pData;
memcpy(VSdataPtr, VSdata, CszVSdata);
context->Unmap(VertexBuffer, 0);

result = context->Map(PixelBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &PSmappedResource);
if (FAILED(result))
{
outputResult.OutputErrorMessage(TITLE, L"Cannot map the PixelBuffer", &result, OUTPUT_ERROR_FILE);
return;
}
LPVOID PSdataPtr = PSmappedResource.pData;
memcpy(PSdataPtr, PSdata, CszPSdata);
context->Unmap(PixelBuffer, 0);

context->VSSetConstantBuffers(0, 1, &VertexBuffer);
context->PSSetConstantBuffers(0, 1, &PixelBuffer);


this update and set the buffer. It's part of the render method of a sprite class that contains a the vertex buffer and the texture to apply to the quads(it's a 2d game) too. I have an array of 500 stars (sprite setup with a star texture). Every frame: clear back buffer; draw the array of stars; present the backbuffer;

draw also call the function update( which calculate the position of the sprite on screen based on a "camera class")

Ok, create a vertex buffer with the vertices of each quads(stars) seems to be good, since the stars don't change their "virtual" position; so.... In a particle system (where particles move) it's better to have all the object in only one vertices array, rather then an array of different sprite/object in order to update all the vertices' position with a single setbuffer call. In this case i have to use a dynamic vertex buffer with the vertices positions like this:

verticesForQuad={{ XMFLOAT3((float)halfDImensions.x-1+pos.x, (float)halfDImensions.y-1+pos.y, 1.0f), XMFLOAT2(1.0f, 0.0f) },
{ XMFLOAT3((float)halfDImensions.x-1+pos.x, -(float)halfDImensions.y-1+pos.y, 1.0f), XMFLOAT2(1.0f, 1.0f) },
{ XMFLOAT3(-(float)halfDImensions.x-1+pos.x, (float)halfDImensions.y-1.pos.y, 1.0f), XMFLOAT2(0.0f, 0.0f) },
{ XMFLOAT3(-(float)halfDImensions.x-1.pos.x, -(float)halfDImensions.y-1+pos.y, 1.0f), XMFLOAT2(0.0f, 1.0f) },


where halfDimensions is the halfsize in pixel of a texture and pos the virtual position of a star. than create an array of verticesForQuad and create the vertex buffer

ZeroMemory(&vertexDesc, sizeof(vertexDesc));
vertexDesc.Usage =      D3D11_USAGE_DEFAULT;
vertexDesc.BindFlags =  D3D11_BIND_VERTEX_BUFFER;
vertexDesc.ByteWidth =  sizeof(VertexType)* 4*numStars;

ZeroMemory(&resourceData, sizeof(resourceData));

result = device->CreateBuffer(&vertexDesc, &resourceData, &CvertexBuffer);


and call each frame Context->IASetVertexBuffers(0, 1, &CvertexBuffer, &stride, &offset);

But if i want to add and remove obj i have to recreate the buffer each time, havent i?? There is a faster way? I think i can create a vertex buffer with a max size (es. 10000 objs) and when i update it set only the 250 position (for 250 onjs for example) and pass this number as the vertexCount to the draw function (numObjs*4), or i'm worng

• It is a very bad idea to update a constant buffer for every particle. You should have each particle's attributes in the vertex buffer and updating the whole thing once each frame. Then the constant buffer would contain camera matrices and be updated once each frame. May 5, 2014 at 7:54
• Ok,i can do this but: -I need to create a shader that has an array of positions with a maximum planned capacity, so i can't add infinite particles.-if i set a matrix composed by 16 positions, how can the 6th star, for example, know that it has to read the sixth position?? May 5, 2014 at 8:33
• No you are wrong, you need to do a draw call for all of your particles at once for the whole vertex buffer. No need for any arrays in the shader at all. The vertex shader will run through all your vertices (particles). May 5, 2014 at 8:55
• so a single vertex buffer that contains the vertex of all the particles' quads, set the primitive topology as triangle list and call contex->draw(4*numparticles) once ?? -because i don't update the vertex buffers, since they don't contain the world coordinates(i obtain them multiply it by a world matrix), but only the texture size and coordinates; and i have to change a lot of my code. May 5, 2014 at 10:14
• Yes you should use a dynamic vertex buffer which you update. You store the positions for a single vertex anyway. If you want to billboard them you can also rotate them in the vertex shader based on your view matrix. May 5, 2014 at 12:43