Advertisement Jump to content
Sign in to follow this  
neroziros

Million Particle System

This topic is 1736 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

Hi there!

 

My current particle system its based on the example: http://content.gpwiki.org/index.php/D3DBook:Dynamic_Particle_Systems

 

However I have one remaining doubt. During the development I noticed that the particles emission rate its capped at 128 per frame due the memory limits of the geometry stream output. However, I would like to implement a particle system able to handle millions of particles at the same time. This is possible with the current particle system, but I need to wait 130 seconds to reach the millions (using particles with 130 sec lifetime), which is not very optimal.

 

I was wondering if any of you knows a way to achieve this using the GPU.

 

Cheers,

José

Edited by neroziros

Share this post


Link to post
Share on other sites
Advertisement

I don't see any reference that you are pointing to, but can't you just execute the particle injection draw call more than once per frame?

Share this post


Link to post
Share on other sites

I don't see any reference that you are pointing to, but can't you just execute the particle injection draw call more than once per frame?

 

Sorry about that, just updated the post.

 

The problem its that the particle injection happens inside the geometry shader, so it has a limit of 1024b per emission (that its equal to 128 particles since each one have 8 components)

 

Cheers

Share this post


Link to post
Share on other sites

Oh nice now I get what you mean. But in order to do that, wouldn't I need need to separate the Update logic of the particles from the Particle Emission? otherwise the particles will move too fast since I would be executing their update a lot of times per frame.

 

Thanks for the help and awesome article smile.png

 

PS: I tried to transfer the particle creation to the CPU using a 3rd buffer which appends the new particles to the streamOutput, however right now it doesn't work and I am not quite sure why. If anyone can check it out I would be more than grateful.

 

FX Code: https://github.com/neroziros/PSDX11/blob/master/ParticleEffect.fx

Class: https://github.com/neroziros/PSDX11/blob/master/Particleclass.cpp

Edited by neroziros

Share this post


Link to post
Share on other sites

I believe the main problem its here, in the mapping procedure:

Class: https://github.com/neroziros/PSDX11/blob/master/Particleclass.cpp

 

I hope my code can also help anyone else interested in building a million particle system based on the GPU :) Cheers

    // CPU PARTICLE CREATION
    // Add new particles if they were created
    if (!newParticlesCreated)
    {
        // Map to the buffer and render the new particles to add them to the pipeline
        D3D11_MAPPED_SUBRESOURCE mappedResource;
        PARTICLE_VERTEX* dataPtr;


        m_D3D->GetDeviceContext()->Map(g_pNewParticles, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
        dataPtr = (PARTICLE_VERTEX*)mappedResource.pData;


        // Copy the data into the vertex buffer.
        memcpy(dataPtr, (void*)newParticlesArr, (sizeof(PARTICLE_VERTEX)* emissionRate));


        // Unmap the buffer
        m_D3D->GetDeviceContext()->Unmap(g_pNewParticles, 0);


        // Set the buffer as the input
        pBuffers[0] = g_pNewParticles;
        UINT stride[1] = { sizeof(PARTICLE_VERTEX) };
        UINT offset[1] = { 0 };
        m_D3D->GetDeviceContext()->IASetVertexBuffers(0, 1, pBuffers, stride, offset);
        m_D3D->GetDeviceContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);


        // Point to the correct output buffer
        pBuffers[0] = g_pParticleStreamTo;
        m_D3D->GetDeviceContext()->SOSetTargets(1, pBuffers, offset);


        // Draw the buffers
        D3DX11_TECHNIQUE_DESC techDesc;
        g_pAdvanceParticles->GetDesc(&techDesc);
        for (UINT p = 0; p < techDesc.Passes; ++p)
        {
            g_pAdvanceParticles->GetPassByIndex(p)->Apply(0, m_D3D->GetDeviceContext());
            m_D3D->GetDeviceContext()->DrawAuto();
        }


        // Get back to normal
        pBuffers[0] = NULL;
        m_D3D->GetDeviceContext()->SOSetTargets(1, pBuffers, offset);


        // Free the particle array memory
        delete (newParticlesArr);


        // Reset variables
        newParticlesCreated = false;
    }

Share this post


Link to post
Share on other sites

Hi there, I managed to do as suggested and separated the emission logic from the update logic. Feel free to check the code here:

https://github.com/neroziros/PARTICLESYSTEM/

 

Now the problem its that I can only reach around 460800 particles before the fps start to drop too low (around 25-35 fps). I have a Phenom II X6 & NVIDIA 560GTX.

 

This is probably an optimization problem, any suggestion its welcomed.

 

Cheers!

Share this post


Link to post
Share on other sites

Are you pursuing this technique because you're stuck on DX10-era hardware? Because this sort of thing can be done more efficiently using compute shaders.

Share this post


Link to post
Share on other sites
And just to bring up an important point; I don't think you REALLY want to spawn 1,000,000 particles from one emitter in one frame... if nothing else it'll be bloody slow to do and you can do a lot with surprisingly few particles per emitter.

However if you DO want to do this, because you want an effect which has a lot of particles, then I suggest creating them at load time either on the CPU or via a one off GPU task instead of trying to spawn them like normal particles.

(As to why you don't want 1,000,000 particles consider this; a 1920*1200 screen only has 2,304,00 pixel on it so at 1million particles each one would be filling a little over 2 pixels on average. )

Share this post


Link to post
Share on other sites
@phantom: hmm I hadnt considered that. Though I am ok with just one million particles per simulation, no need for the 60.000.000 particles per second :P

@mjp: actually I must use DX11 ( I plan on using tesselation later for better particle lighting ). I thought that the compute shader performance was similar to the geometry shader's one. But if I am wrong I will gladly check that option

Thanka for the advice! Will read about compute shaders then :)

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!