Search Unity

Sorting Fudge

Discussion in 'General Graphics' started by ScottPZ, Jan 9, 2017.

  1. ScottPZ

    ScottPZ

    Joined:
    May 26, 2015
    Posts:
    6
    What does sorting fudge in ParticleSystems actually do? I have several questions that could be answered if I have a better understanding:
    • What are the units? Sometimes I need to set high values such as -2000, or 2000 to have an effect. I had assumed that Sorting Fudge is in world-space units which are added to the distance from the camera before an object is sorted with other objects, but the units in the thousands didn't make sense in my scale.
    • How are particle objects sorted between each other, without considering sorting fudge? I assume that either the centroid or the closest corner of the bounding box is sorted, and that order becomes the draw order. Is there a way for me to explicitely set a reference point for geometry for the purpose of computing a sort order (i.e. can I set the bounding box via code)? Because the bounding box is changing every frame, I'm finding that the sort order between different particles changes frequently causing visual popping. I could prevent the popping by setting the world-space sort point to something that doesn't vary each frame.
    • How does Sort Fudge effect drawing with other transparent objects in the scene? Can MeshRenderers have a sort layer?
    I'm facing two different challenges, and I'm hoping that I can use Sorting Fudge to solve them, but I haven't had success yet.

    1) I have a smoke trail that is built by a custom component that creates a Mesh and MeshRenderer. This trail is overlapped by smoke particles that serve to break up the edge. The particles and smoke trail sometimes pop in the order that they sort. I would like the smoke particles to almost always draw behind the smoke. I prefer not to use explicit renderQueues because I have other effects that can overlap, such as an explosion. I don't want to force the smoke particles to draw always behind the explosion if the explosion is actually the most distant object.

    2) Within an explosion effect, I have separate non-batching particles for sparks, fire, and a glow sprite. If I have two explosions that sit roughly at the same distance from the camera, I would like Unity to sort in a batch-friendly manner (e.g. this order: fire1, fire2, spark1, spark2, glow1, glow2). Only if the depths vary dramatically, such as by more than the sort fudge, would the two explosions' particles stagger (e.g. fire1, spark1, glow1, fire2, spark2, glow2).

    I appreciate any details about how sorting works, and how sorting fudge effects sorting.
     
    zhuhaiyia1 and LaurieAnnis like this.
  2. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    World units, i.e. it subtracts the value from the computed camera distance. So a value of 5 would mean "pretend you are 5 units closer to the camera"

    The same way all transparent objects are distance-sorted in unity, which is simply using the center of the AABB (I just checked the code for this, and it surprised me a bit actually.. I would have expected some consideration of box size and closest point to the camera, but it is purely the centre of the box)

    It is simply tricking the sorting into thinking that the object is closer/further away than it really is. So it can be combined with other sorting techniques, such as layers.
     
    LaurieAnnis, Agent0023 and karl_jones like this.
  3. ScottPZ

    ScottPZ

    Joined:
    May 26, 2015
    Posts:
    6
    Thank you for digging and finding this!

    I noticed that the sort fudge units are world space only when the camera's transparency sort mode is TransparencySortMode.Orthographic. It appears to be something else odd when sorting is based on TransparencySortMode.Perspective. Can you tell us how distance is computed for Perspective sort order? After some testing, the camera angle doesn't effect the fudge. However, the distance to the camera unintuitively does effect fudge (i.e. greater camera distance needs higher values of fudge to alter the sort order). That explains why I needed something in the 1000's range to see an effect, and the value was wildly inconsistent.

    I think I have ample reason to switch our games' transparency sort order to Orthographic, which will solve our problem. However, the additional knowledge about how distance is computed will be useful in case we can't switch for some reason.
     
  4. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Just looked at the code some more... it looks like, for efficiency, we store squared distances, when using perspective sorting. On the one hand, this is fine, as they will sort relative to each other just fine, but, on the other hand, this means that when adding a non-squared sorting fudge on, it will give you an unexpected result.

    You could square your sort fudge value as a hack, but we really ought to be fix this bug :(

    EDIT: in fact, I'm going to fix this bug right now!
     
    karl_jones likes this.
  5. ScottPZ

    ScottPZ

    Joined:
    May 26, 2015
    Posts:
    6
    Great that you found this!

    However, a fix won't be as easy as squaring the sorting fudge because the delta between two squared distances != the distance^2 of the distance between the two objects. Take for example, object A with a distance away of 2, and object B with a distance of 3. The difference of squares does not equal the square of differences 3^2 - 2^2 != (3 - 2)^2. If your sort fudge of object A is 2, then squaring that to 4, still does not push object A behind object B, even though any fudge value > 1 should be sufficient. The fix _may_ be for any object that has a nonzero sort fudge, dist = sqrt(dist) + fudge; dist *= dist;. This is somewhat lame, but avoids having to use sqrt on every distance (only the ones with sort fudge).
     
  6. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    So I ran off to make this really simple fix, and then realised the exact same thing - it's not as simple as using a squared sorting fudge.

    I'll look at it in more detail tomorrow..! I have a feeling that your suggested fix is exactly what we will need to do.

    And I can't take much credit, you basically found this bug yourself ... and told me the fix too! :D
     
    LaurieAnnis and karl_jones like this.
  7. ScottPZ

    ScottPZ

    Joined:
    May 26, 2015
    Posts:
    6
    Thank you, kindly. One more thought occurred to me. Users can add a negative sort fudge, so you actually should probably try to preserve the sign of the results after you square the distance. (e.g. dist = sign(dist) * dist * dist;)
     
    LaurieAnnis likes this.
  8. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Yeah, I found that too.. and it got even more complicated with our "custom axis" sorting, where not only can we apply a negative fudge, but we can also have a negative starting distance, which we need to "un-square".

    so, Sqrt(negativeSquaredDistance) would fail. Tricky bit of code :(

    And thanks again for your help... this may make it into 5.6, otherwise it will be in 5.7 definitely!
     
  9. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Hey again, I can confirm that these fixes are going into 5.6.0b8 :)
     
    Ryan-Gatts likes this.
  10. mfCleRIC

    mfCleRIC

    Joined:
    Jan 14, 2016
    Posts:
    7
    Hello.
    You wrote:
    I would like to see in the particle system the choice of a point which is depth of particle system.
    At least for choice to change centre of box to closest point to the camera.


    The gif shows problem.
    Smoke from shot draws over smoke from funnels, because centre of smoke from funnels further than centre of smoke from shot.
     
  11. alpe0504

    alpe0504

    Joined:
    Dec 5, 2017
    Posts:
    2
    Hello.
    Bumping this thread again I have a issue where i have multiple instances of a smoke particle effect prefab. but if the smoke effect has a force over lifetime effect the rendering order gets weird the smoke effects without force gets rendered above the ones that has force. Any suggestions on this issue?

    EDIT: If all the effects has a force over life time it switches between the effects to render first depending on something i can't determine it may be the highest particle that decides which particle system gets rendered in the front.
     
    Last edited: Dec 6, 2017
  12. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Hey, it will use the center of the bounding box to decide the order.
     
  13. alpe0504

    alpe0504

    Joined:
    Dec 5, 2017
    Posts:
    2
    Here is some pictures of the problem if it makes it more clear what the problem is.
    5kX-HCr5RUqCVTp_4AdTZQ.png uJ1NAFDORtaw0gZtM6mn7A.png
     
    LaurieAnnis likes this.
  14. ifurkend

    ifurkend

    Joined:
    Sep 4, 2012
    Posts:
    350
    AFAIC Sorting Fudge only sorts particles of the same particle system, it does not affect particles of different particle systems. In your case, you should use Order in Layer to sort them in a fixed order and limit their exposure to camera rotation.

    However I do have a different thought on this matter. Back then I insisted assigning sub emitter to more than one spawning emitter, one of the reasons (besides the prefab nested depth limitation) was exactly for allowing all sub particles from different spawning emitters to be sorted universally by distance. Of course now that Unity discourages this practice, is it possible at least to introduce some sort of global particle sorting fudge as long as they share the same material and layer?
     
  15. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    This is wrong. Sorting fudge applies a bias to the whole particle system, making an entire system appear either in front or behind other systems.
     
  16. ifurkend

    ifurkend

    Joined:
    Sep 4, 2012
    Posts:
    350
    Oops. I messed up "sorting fudge" and "sort by age/distance" which indeed affects particles of same system. Anyway, is that the incorrect sorting shown in alpe's 2nd screenshot caused by the overstretching of the farthest (black) particle system bounding box?
     
  17. forestrf

    forestrf

    Joined:
    Aug 28, 2010
    Posts:
    230
    TL;DR when using a Scriptable Render Pipeline, "sorting fudge" is relative to the distance to the camera when sorting with perspective. The result is not consistent depending on how far/close the camera is to the particle system, making this not usable.

    This is an old thread, but I'm trying "sorting fudge" and I don't think this is right". With a perspective camera and a positive fudge so that a particle system appears behind a 3d mesh, when moving the camera back the fudge stops being enough, so a larger value is needed to keep the particles behind. This "go far away, set a larger sorting fudge" repeats forever, but once you go as far away as you expect it will ever be seen in game and come back, now the fudge is so large the particles appear behind things I don't want. So, in this state, this feature can't be used as it only does what layers do, but worse, instead of actually moving the object back in world space the amount told.
     
    Last edited: Jun 18, 2020
  18. forestrf

    forestrf

    Joined:
    Aug 28, 2010
    Posts:
    230
    I recorded a video to show the problem, so it's more clear.

    To replicate this, use a Scriptable Render Pipeline and just add a particle system in front of a cube, both using the same render queue. Now use "sorting budge" until the particle gets behind the cube and finally move the camera backwards, which will bring the particle system in front of the cube again.

    Sorting fudge can be clearly seen as relative to the camera's distance to the objects instead of it being a world space offset applied to the particles bounds. Notice in the video that after setting sorting fudge to such a high value, the particle ends up rendering behind everything, so it's like a layer or rendering order instead.


    I decided to report the bug (case 1256788) but given that I can't wait years for it's fix, I will try using orthographic perspective as this feature seems to work there, and hope I can deal with the wrong transparency order problems that will appear, as I need this feature. Other options would work, like being able to render a group of several renderers in a specific order, but it doesn't seem possible to do it that way, making this feature what seems my last "easy" hope
     
    Last edited: Jun 18, 2020