Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Obi7 | I made a pool
#1
Gran sonrisa 
So happy I can make a pool now  Gran sonrisa
This is not able with earlier versions of Obi whoo.



I'm just testing with a pool size width 20x10 height 3m
To cover this pool, I used extremely big particle (resolution 0.02, count 15k) on a RTX 3070.

Tbh I do not expect a swap chain crash with just 15k particle, since Unity CPU shuriken only has problem at 10k, so I don't think 15k is heavy for GPU.
But the pool will crash when it about to reach 11k particle.

After more testing, I found out this crash is about the Memory Budget foldout. After I set Max Surface Chunks to 150k (425mb) it can run now, but the GPU cry for help  Sonrojado

This is a very important part that will crash Unity if not properly set, so I suggest: when the Emitter detect user give it a very big particle count blueprint, can show a big red warning box telling user must scale the max Surface Chunks accordingly, or even better, suggest a value to set.


Also, in PlayMode the Solver only show Chunks and memory we set, not the Chunks and memory we used up.
Suggest adding to the display used up Chunks  / set Chunks . With that I can set the Max Surface Chunks with better value. For now, I can only blindly set. The values I set may be much more than it actually need. 

Window Build test: 20ms for this pool, optimization tips please?

Btw, the pool is there, I'll move next to scripting buoyancy, if you please can give some demo code about adding force based on character volume displacement inside the Fluid that would be big help!
Reply
#2
Hi!

The issue is not the amount of particles, but the amount of surface chunks you're using. If you need half a gigabyte worth of memory to avoid a swapchain crash, that means your surface voxel size is tiny. Under the hood this will force every voxel to traverse the entire chunks hash table to find an empty chunk to use, which may take several seconds per frame in some cases leading to a swap chain crash as the system detects the GPU has been working on a task for too long. Your solution of increasing the amount of max surface chunks will make the hash table larger, avoiding excessive waiting time but at the cost of a large amount of memory.

The likely cause is that you've reduced particle resolution a lot to have a large pool, but kept the default small voxel size which would be way too small for meshing a 20x10x3 volume.

The manual suggests using a voxel size that's about the size of your particles. Note this will only land you in the ballpark of a good value, as you may have particles of different sizes in your solver, or you might need more/less surface detail depending on your use case:
http://obi.virtualmethodstudio.com/manua...ering.html

Quote:A good starting value for the voxel size is the size of your fluid particles. You can check the size of a particle in the info bubble that appears at the bottom of your fluid blueprint's inspector.

I made a test using a blueprint resolution of 0.02: this is the wireframe view of only 200 particles with a voxel size of 0.08. As you can see the mesh is so dense you can barely tell individual triangles apart:

[Image: Opsltpw.png]

This is with voxel size set to 0.2 (slightly less than the particle size, which is 0.36). This doesn't require more than the default 32k chunks, for a pool similar to the one in your screenshot:

[Image: DBRKtQS.png]

Note all sizes (particle sizes, voxel size, etc) are expressed in meters, as usual in Unity.

(07-05-2024, 06:10 AM)spikebor Wrote: This is a very important part that will crash Unity if not properly set, so I suggest: when the Emitter detect user give it a very big particle count blueprint, can show a big red warning box telling user must scale the max Surface Chunks accordingly, or even better, suggest a value to set.

Surface chunk count is not related to the amount of particles at all. It depends on the surface area of the fluid, which in turn depends on the kind of scene you're simulating: If you're making a big sphere of fluid in zero-gravity, the surface area will be small even if you use many particles. If you're making a waterfall with many isolated particles moving around, the surface area will be large even if you use few particles.

As such, it's not possible to give an estimate of the amount of surface chunks you should use as the system does not know what kind of scene you're making. It's up to the user to balance memory consumption vs performance, and adjust the amount of memory allocated for chunks as needed.

The default values for every setting (max chunks, voxel size, blueprint resolution) work well with each other, even if you modify them a bit. However modifying one of them by order of magnitude or more -as in your use case- will require adjusting the others.

(07-05-2024, 06:10 AM)spikebor Wrote: Also, in PlayMode the Solver only show Chunks and memory we set, not the Chunks and memory we used up.
Suggest adding to the display used up Chunks  / set Chunks .

This would require reading chunks back from the GPU, which is a very expensive operation. We will likely add a debug mode of sorts, that allows to asynchronously retrieve the amount of chunks used by your particular scene, to give a better idea of utilization percentage even if it's not entirely accurate.

(07-05-2024, 06:10 AM)spikebor Wrote: Window Build test: 20ms for this pool, optimization tips please?

Using Unity's GPU profiler is always a good idea. However in this particular case, just increasing your voxel size should considerably improve performance as surface meshing is sure to be your bottleneck.

(07-05-2024, 06:10 AM)spikebor Wrote: Btw, the pool is there, I'll move next to scripting buoyancy, if you please can give some demo code about adding force based on character volume displacement inside the Fluid that would be big help!

Buoyancy is fully automatic. When you submerge a rigidbody in the fluid, it will sink (or float) based on the mass of the rigidbody vs the density of the fluid. You only need to adjust the fluid blueprint's density and/or your rigidbody mass.

kind regards,
Reply
#3
(07-05-2024, 07:36 AM)josemendez Wrote: Hi!

The issue is not the amount of particles, but the amount of surface chunks you're using. If you need half a gigabyte worth of memory to avoid a swapchain, that means your surface voxel size is tiny. Under the hood this will force every voxel to traverse the entire chunks hash table to find an empty chunk to use, which may take several seconds per frame in some cases leading to a swap chain crash. Your solution of increasing the amount of max surface chunks will make the hash table larger, avoiding excessive waiting time but at the cost of a large amount of memory.

The likely cause is that you've reduced particle resolution a lot to have a large pool, but kept the default small voxel size which would be way too small for meshing a 20x10x3 volume.

The manual suggests using a voxel size that's about the size of your particles. Note this will only land you in the ballpark of a good value, as you may have particles of different sizes in your solver, or you might need more/less surface detail depending on your use case:
http://obi.virtualmethodstudio.com/manua...ering.html


I made a test using a blueprint resolution of 0.02: this is the wireframe view of only 200 particles with a voxel size of 0.08. As you can see the mesh is so dense you can barely tell individual triangles apart:

[Image: Opsltpw.png]

This is with voxel size set to 0.2 (slightly less than the particle size, which is 0.36). This doesn't require more than the default 32k chunks, for a pool similar to the one in your screenshot:

[Image: DBRKtQS.png]

Note all sizes (particle sizes, voxel size, etc) are expressed in meters, as usual in Unity.


Surface chunk count is not related to the amount of particles at all. It depends on the surface area of the fluid, which in turn depends on the kind of scene you're simulating. If you're making a big sphere of fluid in zero-gravity, the surface area will be small even if you use many particles. If you're making a waterfall with many isolated particles moving around, the surface area will be large even if you use few particles. As such, it's not possible to give an accurate estimate of the amount of surface chunks you should use as the system does not know what kind of scene you're making. It's up to the user to balance memory consumption vs performance, and adjust the amount of memory allocated for chunks as needed.


This would require reading chunks back from the GPU, which is a very expensive operation. We will likely add a debug mode of sorts, that allows to optionally retrieve the amount of chunks used by your particular scene, to give a better idea of utilization percentage.


Using Unity's GPU profiler is always a good idea. However in this particular case, just increasing your voxel size should considerably improve performance as surface meshing is sure to be your bottleneck.


Buoyancy is fully automatic. When you submerge a rigidbody in the fluid, it will sink (or float) based on the mass of the rigidbody vs the density of the fluid. You only need to adjust the fluid blueprint's density and/or your rigidbody mass.

kind regards,

Thanks for the answers!
Yes, the editor only debug mode for chunk used will be helpful!
Also, I suggest draw a small 2x2 grid cube with the size of each cube = the voxel size in scene view when select the Emitter will also visualize it better for user to adjust it.

I adjust the voxel size to 0.2 relation to particle size 0.34, now I can have 16k particles with just 3000 surface chunks (8.5mb)! 
Great save!

[Image: W5MxrnM.png]

The pool now cost only ~2.4ms in build (2.6 because printscreen stutter). Super speedy now!

[Image: d1wjddy.png]

I know that Buoyancy is automatic, as all particle collisions in Obi world. that's big reason I move all my gameplay code toward Obi solutions.
But still need some custom coding in some area, for example, an airplane will not just sink if it is rotated side way in Tears of the Kingdom, it will rotate about to either face up / face down for the player to have a better area to stand on when player crashed the airplane into water, not realistic physics but a quality of life for the player.
I think that is some adjustment force to try to maintain a target rotation of the object. Or some object material that have more buoyancy force multiplier than others.

Currently my pool with particle size 0.34, with mass =2kg. It cannot add enough buoyancy force to pull the orange plate (20kg) up when it sank. But when it on the surface of water, it does not sink.
I then try with a massive mass=20kg each particle, now I can see the buoyancy force more clearly when I drag it down, it will be violently pulled up and jump up the air. But when I drag it all the way down to the bottom of the pool, it just lay there. Is this the expect behavior?
Reply
#4
(07-05-2024, 08:45 AM)spikebor Wrote: But still need some custom coding in some area, for example, an airplane will not just sink if it is rotated side way in Tears of the Kingdom, it will rotate about to either face up / face down for the player to have a better area to stand on when player crashed the airplane into water, not realistic physics but a quality of life for the player.

This can be done using collision callbacks, or even just regular Unity triggers in case your fluid is supposed to be confined in a specific area like a pool: whenever an object is inside the fluid area, rotate it upright. This behavior not physically based, so you can skip physics entirely: specific forces applied by individual fluid particles don't really matter.

(07-05-2024, 08:45 AM)spikebor Wrote: Currently my pool with particle size 0.34, with mass =2kg. It cannot add enough buoyancy force to pull the orange plate (20kg) up when it sank. But when it on the surface of water, it does not sink.
I then try with a massive mass=20kg each particle, now I can see the buoyancy force more clearly when I drag it down, it will be violently pulled up and jump up the air. But when I drag it all the way down to the bottom of the pool, it just lay there. Is this the expect behavior?

A plate vs large enough particles means simple mechanical forces will have a non-negligible effect on buoyancy: the plate can become "stuck" due to its shape, not allowing denser particles to move past it towards the bottom of the pool because it acts kinda like a shield/net that captures particles as they move down.

Using smaller particles, or rounding the edges of the plank collider (you can do this automatically by increasing the collider "thickness" slightly) to facilitate particles sliding past its edges and towards the bottom will improve behavior.
Reply
#5
Wow thank you; I don't think about using thickness in any case, don't know it can let particle move past.
Reply
#6
(07-05-2024, 01:31 PM)spikebor Wrote: Wow thank you; I don't think about using thickness in any case, don't know it can let particle move past.

You can think of it as how "hydrodynamic" a shape is: if a shape allows particles to smoothly flow around it, the net buoyancy force it feels will be greater than that of a shape that prevents particles from flowing past it.

Increasing the thickness of a shape rounds its corners too, making it slightly more hydrodynamic.
Reply