Search Unity

Powder simulation (How ?)

Discussion in 'Entity Component System' started by LucAubert, Sep 30, 2019.

  1. LucAubert

    LucAubert

    Joined:
    Nov 28, 2016
    Posts:
    3
    Hi !

    I am currently making a game that features a powder simulation where each pixel of the game world is treated as a "grain".
    This actually works very well using only C# on the main thread (a big fat "for" loop ^^).
    (current behaviour)
    But I feel like this could be a perfect fit for a job.
    Although I don't really know how I to do this... It seems like jobs are very good at treating a lot of entities independently of one another, but I cannot figure how I could "move" a grain from one position to another.

    As of now, the whole map is stored as an array of flags layed out just like the pixels of a texture (row by row with the origin at the bottom left corner).
    So if I iterate through this array I end up moving pixels that are lower before updating pixels that are higher, meaning pixels fall seamlessly.
    I don't really know how I could achieve this using jobs.

    It puzzles me that even though this feels like the perfect simple application for a job, this ends up being such headache to implement ^^ !

    Anyone has any idea as to how to proceed ???

    Thanks !
     

    Attached Files:

  2. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,709
    I would Imagine you would treat this like a flow field with each entity at a position having a neighboring entities component. Hard to say without getting into it.
     
  3. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    That might be because you are conflating the job system with ECS. Really all you need is to put your 2D array of pixels (there's API to get and set textures using NativeArrays and a few custom NativeArray2D wrapers on these forums) and other data into an IJob and then put your big fat "for" loop in the Execute method. Once you get that working, tack on Burst. If you get stuck with the process, post code, errors, and stack traces, and we can help you out. Don't bother with entities for now.
     
  4. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,780
    Either using OOP Jobs, or ECS, no need for each grain per entity. As mentioned already, you are better to keep all grain as array. With Jobs or ECS you can apply burst, so you can gain massive performance.

    I wold linearize array into 1D array. Keeping in array, allows easily to check neighbors cells, if these are occupied by grains.

    And pretty much you keep similar way as OOP, on that part.

    Regarding rendering, you could use ECS entities, to render grains. You basically apply render mesh to grain component and set position, based on position in array.
    Hence grain entities are only for visualization. All magic happens in single array.

    Depending of size of the grid /,array, you could use jobs later to parallelize process. It may be a bit tricky due to relation between all grains. But with a bot of tinkering, I believe could be done. But I would.only advise to try do such, if you start running to performance issue, on burst singlethreaded job.
     
    Last edited: Oct 1, 2019
  5. starikcetin

    starikcetin

    Joined:
    Dec 7, 2017
    Posts:
    340
    Probably others are right, but it would be interesting to make this with pure ECS, just to stress test the DOTS and have some barbeque on your laptop.

    /This is a joke, don't take it as an advice or something.
     
  6. LucAubert

    LucAubert

    Joined:
    Nov 28, 2016
    Posts:
    3
    Hey, thanks for all the replies !

    I am not trying to use ECS for this task, only a job. An "IJobParallelFor" to be exact.
    I just want to switch my big "for" loop, from main thread C# to a job.
    The problem I have right now is that in a job, I can only read AND write at the exact index I am in.
    If I want to check other "grains" states, I have to use double buffering.
    Although, when I do that, A higher "grain" won't know that the "grain" below it has fallen until the next frame, which creates gaps between falling "grains".
     
  7. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,780
    Have you used burst yet and profiled performance?
    Do that first if you haven't yet.
    Once you yes that, consider weather is worth to go into paralleism. It is possible but may be tricky and indeed, you will need to deal with challenge what you just observed.
     
  8. Nyanpas

    Nyanpas

    Joined:
    Dec 29, 2016
    Posts:
    406
    Try IJobParallellForBatch, maybe?
     
  9. LucAubert

    LucAubert

    Joined:
    Nov 28, 2016
    Posts:
    3
    I just found out about it. Documentation is a bit scarce though...
    Have you tried it yourself ? Can you recommend a video or post about it ?

    Anyway, it looks like it would do what I'm looking for.
     
  10. Nyanpas

    Nyanpas

    Joined:
    Dec 29, 2016
    Posts:
    406
    I tried it for a simple iteration test for NativeArrays of ints, but found later that it was ok to just use a regular IJob for my purposes with regards to the profilers. As you mention, lack of documentation stopped me from trying it further.