Search Unity

DOTS for floating origin

Discussion in 'Entity Component System' started by awesomedata, Jan 10, 2020.

  1. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    1,419
    So I've just started digging into DOTS again (there have been major changes in workflows since I dug into the MegaCity demo) and so I was wondering if anyone had any examples or ideas of using the most recent iterations for moving meshes and physics shapes around for the purposes of a floating origin for open world scenarios. I am curious how this sort of thing would look/function.

    I have not dug too deeply into the new DOTS workflows just yet. Are there any things I should know about the new workflows that would be related to origin-shifted worlds? I've found something about WorldMeshRenderBounds and a tiny line about GameObjectConversionUtility.ConvertGameObjectHierarchy, which both seem important, but I've not dug into them yet -- Are these still relevant for open worlds with the new DOTS entity workflows? If not, what are the best practices so far to get something like a floating origin / physics / meshes functional with DOTS these days?
     
  2. mentics

    mentics

    Joined:
    Aug 18, 2015
    Posts:
    10
    I was curious about this, too. I created a scene and spawned 200,000 cubes. Then created a simple system that would change all their translation (shifting to the new zero). Running it in the editor and shifting every frame, it showed ~0.03 for the system in the entity debugger. I haven't looked into hooking into subscene activation to shift on load, but the general idea seems doable.

    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.Jobs;
    3. using Unity.Mathematics;
    4. using Unity.Transforms;
    5.  
    6. public class RezeroingSystem : JobComponentSystem {
    7.     private GameManager game;
    8.  
    9.     protected override void OnCreate() {
    10.         game = UnityEngine.GameObject.FindObjectOfType<GameManager>();
    11.     }
    12.  
    13.     protected override JobHandle OnUpdate(JobHandle inputDependencies) {
    14.         if (game != null && game.move) {
    15.             game.move = false;
    16.             float3 modify = (game.newZero - game.currentZero);
    17.             game.currentZero = game.newZero;
    18.  
    19.             var jobHandle = Entities
    20.                     .ForEach((ref Translation trans) => {
    21.                 trans.Value += modify;
    22.             }).Schedule(inputDependencies);
    23.  
    24.             return jobHandle;
    25.         }
    26.         return inputDependencies;
    27.     }
    28. }
    29.  
     
    awesomedata likes this.
  3. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    We are currently looking at adding new APIs to make floating origin easier in DOTS.
    It is possible to hook all the places yourself, but i wouldn't call it straightforward right now.

    Our goal is to make it simpler & provide samples on how to do it.
     
  4. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    1,419

    Are you guys also considering applying this to in-editor workflows for tools (i.e. for contextual content-authoring?)


    For example, I would like to quickly author simple content in-context, far away from the 0,0,0 origin (using existing tools like Probuilder or Polybrush). The workflow I imagine is that I would use my tool, Snapcam, to instantly "snap" around my world to various far away locations, then use Probuilder to quickly author new content for this area. In some cases, I might want to hop into Blender and sculpt something there too, then have it appear in my scene when I hop back. Ultimately, I would prefer to maintain access to as many Unity-native development tools as possible in a new, powerful, open-world context.


    Another consideration on the API:

    Floating origins can be handled in a few different ways, but hexagonal origins are best for visual-rich games where the viewer looks at the skyline a lot (FPS or TPS games). A hexagonal streaming grid is basically a standard square grid, but with the 4 corners sliced off, and the points (used to load the world) are duplicated and offset, making it a hexagonal cell. This is important because only 6 scene globs must be loaded around the origin (instead of the standard 8 that would be required with square grid), making everything run loads faster. On top of this, LOD and Imposter rendering can now easily be handled via a singular distance from a central radius. This radius can also affect loading/unloading scenes too!


    Grid API considerations:

    The hexagonal grid is how a game like Spiderman with distant detailed skyscrapers (see my later World Streamer posts) and also Xenoblade Chronicles X and Xenoblade Chronicles 2 (Switch) both do their origin/chunk streaming (I would imagine Breath of the Wild uses this method too since the Xenoblade devs helped Nintendo). Ideally, anything beyond the 6 scenes would be loaded as Imposters in the Editor, and the user could configure the distance in which this imposter rendering occurs before the scene is simply clipped/culled away. @Joachim_Ante -- I know you're a programmer, but being able to visualize how in-between scenes affect the distant skyline is critical when hand-authoring content for open-worlds.





    Hopefully this stuff will be usable with the new SceneVis collections system that was supposed to be in-progress. Seems like these tools all handle visibility in the editor -- it would make sense that they'd all be working together... so, theoretically, the teams involved should probably do so as well...?


    Looped worlds:

    While you're at it, looped worlds would be important to have with a floating-origin system. After all, 2d tiled games on the NES / SNES did it way back in the early 90's.... Seems like 3d games should be able to handle this easily in 2020 too, yeah? ... Just throwing it out there...
     
    Last edited: Jan 23, 2020
  5. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    Someone mentioned that the HDRP has an origin shifting camera system do we need to manually shifting origin?
     
  6. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    The only bad thing with origin shifting is that any asset on store must be origin shifting compatible i.e. it is not allowed to store global position somhere otherwise asset must register and shift every such field in such component, array and any other memory.


    The only thing I can think of is make all positions relative to some chunk system. store additional offset in chunk and retrieve global position only if needed. Better even no use global position at all, just convert position to be local to chunk of my entity and then use in chunk local space. This approach has its own disadvantages but if something like that will become default way to do things in DOTS then every asset from store will be conpatible with infinite world.
    This also will be good fit for camera relative rendering I think.
     
  7. iamarugin

    iamarugin

    Joined:
    Dec 17, 2014
    Posts:
    883
    It is only camera-relative rendering. You need to shift origin at least for physics, or if you are using entities positions in some custom calculations.
     
  8. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    Think of it from the camera, player or even a multiplayer group perspective the entities in the world can have a global position that is translated to a local position as the game streams in assets/terrain/units within the scope of the camera/player or multiplayer group.

    Why not just use the camera/player shifted positions for the physics system, this would reduce the workload (you would only be origin shifting once) and keep both system in sync and with the most precise physics calculations centred where you need them around the player.
     
  9. iamarugin

    iamarugin

    Joined:
    Dec 17, 2014
    Posts:
    883
    Because camera-relative positions calculated only in shaders by simply subtracting camera position from the world position. But yes, it would be great to have a unified floating origin system or just a good API for that in DOTS/Physics.
     
  10. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    For loading it is ok but if already loaded part of the world and then move far away, you need to shift positions of old stuff and all mobs and player itself to be again in zero position. Stream of new content in right place dont help there unless you move entire world every frame.
    But moving every frame dont resolve issue of stored global positions inside some component or array or something.

    World Divided by chunks may be can help:
    My thoughts about it:
    • Make chunked world to be core and the only way to create games in DOTS.
    • For simple games scene will consist from only one chunk so no need to think about it
    • Make Chunks to be hexagons (so we always will have central chunk and 6 chunks around)
    • All dynamic objects must be auto moved to another chunks when they cross boundaries
    • Create Struct GlobalPoint with 2 fields (short3 chunk, float3 localpos) that can store global position that can survive origin shift without special processing
    • Instruct Community to never store global position as float3 only as GlobalPoint. float3 can be used for global pos only inside method as local variable
    • When Player Cross boundary of chunk - make origin shift on the very beginning of next frame and apply shift delta to every LocalToWorld component in world.
    • May be allow to choose size of one chunk
    • With chunk size of 1 kilometer diameter (hexagon) we can create worlds 65 536 kilometers in each direction in 3d
    CameraRelative rendering will just start rendering chunks from origin one to other around and never need some special processing

    Without creating ecosystem inside Unity for infinite world by default (new DOTS runtime is best time to do it) we will end up with unconsistent assets in store that can not be used for infinite worlds

    Thinking about world will be something like that:
    upload_2020-1-23_20-26-42.png
     
    Last edited: Jan 23, 2020
    awesomedata likes this.
  11. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    1,419
    If you're assuming you have a "Main Camera" concept, this _might_ be okay, but if you have two player split-screen on the same map, with large rendering distance (with the possibility of two players being on different sides of the world!), this is where the problem gets hairy.
    On most games, your suggestion could work -- but on games where you have a large rendering distance as well as multiple cameras, this could cause major design problems on a game like the one I mentioned above.


    My suggestion in this regard:

    To future-proof Unity in this capacity, I suggest Imposter positioning be (loosely) tied to camera/shader display rather than standard entity position rendering -- In other words, once entities marked as Imposters (usually large swathes of land, as seen in Xenoblade Chronicles X and 2) become too distant to be drawn normally by entity positioning, either they are culled, or depend upon being displayed as imposters on an as-needed basis by the actively rendering camera(s).




    Since these (_very_ distant) chunks would rarely require physics, they would need no additional processing. However, giving a hook for the physics system (in case it is necessary) to handle limited physics processing for anything located where the imposters exist (in case you need a LOD mesh to handle something like Star Fragments in BotW), you could simply position the physics world/mesh in this place for whatever limited physics processing you need.

    We would need to be aware of animated imposters too. These could be handled slightly differently -- e.g. perhaps they could be handled as if they were stereoscopic RenderTextures of some kind and then lerped between? Either way, it might be a good idea to look into Xenoblade Chronicles 2 to see how they do it. They do animated distant huge meshes all the time -- I think it's about time Unity supported tech like this, considering Shadow of Colossus had it way back on the PS2...
     
  12. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    struct GlobalPosition can realized in 3 forms that can be switched by Preprocessor Directives

    • Full
      Code (CSharp):
      1. struct GlobalPoint
      2. {
      3.     public int3 chunkpos;
      4.     public float3 localpos;
      5.  
      6.     //Accesors ...
      7. }
    • Short
      Code (CSharp):
      1. struct GlobalPoint
      2. [*]{
      3.  
      4.     private int _chunkpos; //12bit x, 8bit y, 12 bit z
      5. [*]    public int3 chunkpos => //...
      6.     public float3 localpos;
      7.  
      8.     //Accesors ...
      9. }
    • Empty
      Code (CSharp):
      1. struct GlobalPoint
      2. {
      3.     public int3 chunkpos => return new int3();
      4.     public float3 localpos;
      5.  
      6.     //Accesors ...
      7. }

    In empty mode GlobalPoint will be the same as float3.
    Short may be can add more speed because of less size va full (16 vs 24 bytes) default if applicable
    Full is really for space simulators where all 3 dimensions is important and needs to be huge

    Hope there is no hidden issues in this idea :)

    Also to retrieve usable float3 absolute position from GlobalPoint when far away from virtual origin we need first substract current world chunk offset from GlobalPoint and then compute absolute position, so we need access to current world chunk offset in any place in code. May be some static field that can be set from world of current running system or something.



    May be all we need is separate struct for GloalPosition, and community that use it in all places where they store AbsolutePosition. All another stuff can be created separately and will work with origin shofting and we can create square chunks on top of it, hexagonal chunks, may be triangle chunks... :)
     
    Last edited: Jan 23, 2020
  13. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    Want to see chunked infinity MEGASity demo from Unity :)
     
    awesomedata likes this.
  14. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    Another note:
    Any new system that want to write LocalToWorld component must have additional job that respect ChunkPoint component on Root Object.
    Everything will work correct while entities in zero chunk but need additional logic when in any other.

    So we need additional rule for AssetStore Asset Review Automatic Test: Shift world a little bit and check shifted positions of root entities. If someone dont correctly shifted then fail :)
     
  15. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    Solution for floating origin based on chunks can become good fit for chunked voxel games even that they usually use chunks 16 meters long :)

    In case of such small chunks we need to be able to shift world by any custom logic not only chunk boundary crossing :)
     
  16. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    567
    Why cumbersome hacks that lead to headaches with object states and cache invalidation instead of a much better and appropriate tool for the job - double-precision? The format works well today in industries (see Unigine: one, two), games like Star Citizen are utilizing 64-bit floats successfully at scale. Rendering API supports it out of the box, Godot is moving towards it through Vulkan implementation. Physics engines like Bullet Physics support it just fine, Unity has more control today over this area than before. Math can be extended for this as well, SLEEF support double-precision.
     
  17. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    I've tried getting Unity to consider this but they and the community pushed back hard https://forum.unity.com/threads/has-unity-considered-a-64-bit-floating-point-upgrade.383426/
     
    nixcs2512 and nxrighthere like this.
  18. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    567
    A lot of misconceptions about the performance and hardware constraints in that thread due to the lack of practical experience, most likely.
     
  19. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    1,419
    That's interesting. This is an excerpt from Godot engine.

    I wonder if @Unity might be able to implement something akin to this -- it's actually quite clever.
     
  20. Thygrrr

    Thygrrr

    Joined:
    Sep 23, 2013
    Posts:
    700
    I am working on a floating origin system, and I'm exploring making certain parts of it double precision. Nothing speaks against double precision floats in ComponentData. I use that for Keplerian Orbits etc.

    But as awesomedata's quote correctly points out - you will STILL need to build your local transforms for PresentationSystems from them in a System, anyway. Your GPU doesn't speak double for vertex coordinates, and even less so for fragments.

    And Star Citizen does exactly that as well, I am dead certain about this. They don't have magical vertex shaders or upgrade your rasterizer units in your GPU. Their code works in World-Space-to-View/Tangent/Screen-Space transformations that are anywhere near double precision. Even though the performance of SC might make you believe otherwise...:)

    Now, Physics systems are a bit harder, but at long distance, physics objects don't strongly interact (collide/transfer momentum) with each other at all. So thanks to Unity Physics being stateless, it is practically free and seamless to transfer entities between physics points of references, too.
     
    Last edited: Mar 16, 2020
    PrimalCoder likes this.
  21. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    567
    Yes they do, it was covered in one of the tech videos back in 2015, all rendering stuff is camera-relative. Unigine renders all objects in camera space as well, it was done in 2011.
     
    PrimalCoder and bb8_1 like this.
  22. Thygrrr

    Thygrrr

    Joined:
    Sep 23, 2013
    Posts:
    700
    But that's exactly what I described.
     
  23. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    1,419
    Obviously Unity doesn't do doubles, but camera-relative rendering in URP/HDRP is already a thing. However, apparently animation doesn't support this well, so you still get the jitters. Though, at least those "jitters" don't come from the camera itself -- only the world/environment. So I wonder if the DOTS animation / physics components would be able to handle it?

    Seems like these are focused on procedural stuff more and more these days, so can these systems be converted to use double for final positioning, and then be converted back to camera space for the latter half of update/rendering/display? -- I wonder what the performance hit would be...
     
    nxrighthere likes this.
  24. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    567
    There's also some unresolved sources of jitter that should be taken into account.

    In general, I'd say it's a good time for Unity to investigate double-precision properly while those packages are in the early development stage. The biggest benefit even for those who are not making games with large scalable worlds it's still carrying benefits like more accurate and consistent computation results.

    I guess a significant performance hit will be on some ARM processors where NEON supports only single-precision floating-point, so slower VFP will be utilized instead.
     
  25. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,264
    Floating origin and double-precision are both valid solutions to the massive universe problem.

    Floating origin has cheaper resource requirements for simulation in processing power, memory, and bandwidth. However, it introduces edge-case complexity which may or may not offset these costs.

    Double-precision has the exact opposite trade-offs.

    Unity is willing to more directly support floating origin because it is the lower-hanging fruit. Double-precision accuracy is simply overkill for most games and is why many games don't use it. Supporting two versions of animation and physics for each precision while promising absolute best performance is way more difficult than supporting single-precision and using a different approach for the massive universe problem.

    That doesn't mean you can't do double-precision in DOTS. It only takes one GameObjectConversionSystem to fix authoring, and it only takes one transform relay system to hook up to the Hybrid Renderer and do true double-precision camera-relative rendering.
     
    Scorr likes this.
  26. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    567
    Unless you are making a multiplayer game where simulation is driven on the server-side and floating origin involves more problems than it solves.

    With floating origin, game/engine subsystems bound to implementation constraints, there's no single unified approach for every type of game, unlike with double-precision which makes stuff a lot easier and keeps the entire workflow natural without any hacks.

    The performance difference on modern desktop machines is negligible unless you are memory-bound or doing micro-benchmarking masturbation. You still can selectively use math with 32-bit floats where 64-bit doubles are overkill.
     
    iamarugin likes this.
  27. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    just simple test show that double is 2x slower that single on my
    Asus ROG
    Intel(R) Core(TM) i7-8750H CPU

    Tested various cases Single vs Double, float3 vs double3 and float4 vs double4
    And it seems burst event not fill full simd line with floats so floats can be even faster

    This is how most of DOTS code looks like just simple jobs with simple math on many entities

    upload_2020-3-17_13-53-32.png

    Code (CSharp):
    1. using Unity.Burst;
    2. using Unity.Collections;
    3. using Unity.Jobs;
    4. using Unity.Mathematics;
    5.  
    6. using UnityEngine;
    7.  
    8. public class TestMB : MonoBehaviour
    9. {
    10.     void Update( )
    11.     {
    12.         {
    13.             var arr1        = new NativeArray<float4>( 10_000_000, Allocator.Persistent );
    14.             var arr2        = new NativeArray<float4>( 10_000_000, Allocator.Persistent );
    15.             var arrresult    = new NativeArray<float4>( 10_000_000, Allocator.Persistent );
    16.  
    17.             var job            = new FloatJob
    18.             {
    19.                 Arr1 = arr1,
    20.                 Arr2 = arr2,
    21.                 Arrresult = arrresult
    22.             };
    23.  
    24.             var time = Time.realtimeSinceStartup;
    25.  
    26.             job.Run( );
    27.  
    28.             Debug.Log            ( $"[TestMB] - Update Single: {Time.realtimeSinceStartup - time}" );
    29.  
    30.             arr2.Dispose( );
    31.             arr1.Dispose( );
    32.             arrresult.Dispose( );
    33.         }
    34.  
    35.         {
    36.             var arr1        = new NativeArray<double4>( 10_000_000, Allocator.Persistent );
    37.             var arr2        = new NativeArray<double4>( 10_000_000, Allocator.Persistent );
    38.             var arrresult    = new NativeArray<double4>( 10_000_000, Allocator.Persistent );
    39.  
    40.             var job            = new DoubleJob
    41.             {
    42.                 Arr1 = arr1,
    43.                 Arr2 = arr2,
    44.                 Arrresult = arrresult
    45.             };
    46.  
    47.             var time = Time.realtimeSinceStartup;
    48.  
    49.             job.Run( );
    50.  
    51.             Debug.Log            ( $"[TestMB] - Update Double: {Time.realtimeSinceStartup - time}" );
    52.  
    53.             arr2.Dispose( );
    54.             arr1.Dispose( );
    55.             arrresult.Dispose( );
    56.         }
    57.     }
    58.  
    59.     [BurstCompile]
    60.     struct FloatJob : IJob
    61.     {
    62.         [ReadOnly]    public NativeArray<float4> Arr1;
    63.         [ReadOnly]    public NativeArray<float4> Arr2;
    64.                     public NativeArray<float4> Arrresult;
    65.  
    66.         public void Execute( )
    67.         {
    68.             var length = Arr1.Length;
    69.          
    70.             for ( var i = 0; i < length; i++ )
    71.             {
    72.                 Arrresult[i] = Arr1[i] + Arr2[i];
    73.             }
    74.         }
    75.     }
    76.  
    77.     [BurstCompile]
    78.     struct DoubleJob : IJob
    79.     {
    80.         [ReadOnly]    public NativeArray<double4> Arr1;
    81.         [ReadOnly]    public NativeArray<double4> Arr2;
    82.                     public NativeArray<double4> Arrresult;
    83.  
    84.         public void Execute( )
    85.         {
    86.             var length = Arr1.Length;
    87.          
    88.             for ( var i = 0; i < length; i++ )
    89.             {
    90.                 Arrresult[i] = Arr1[i] + Arr2[i];
    91.             }
    92.         }
    93.     }
    94. }
    95.  
     
    Thygrrr likes this.
  28. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,264
    Every solution has trade-offs. There's no silver bullets here. It just so happens that the downsides of floating origin are prohibitively expensive when paired with other decisions you have made. I'm not saying that you made the wrong decisions nor that your choice to use double-precision is a bad one. Far from it. I'm just saying that different people will have different needs that encourages them to take the floating origin path. And that solution is just as viable for their needs as double-precision is for yours.

    As for the performance difference, you are right that the difference is negligible on desktop when ALU-bound and with linear-complexity or unoptimized higher-complexity algorithms. But a lot of people develop for mobile and consoles where the difference between 15 FPS and 30 FPS is critical. You can't just pretend they don't exist. Unity doesn't, and that's why they have made comments towards supporting floating origin.

    I think rather than argue for or against double-precision, it might be more useful for yourself and the Unity developers to explain what issues you are running into when using double-precision in DOTS.
     
    PrimalCoder likes this.
  29. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    567
    Here are proper tests using SLEEF benchmarking tool directly without any side factors:

    nontrigsp.png nontrigdp.png

    Trigonometric functions:

    trigsp.png trigdp.png

    Micro-benchmarking doesn't carry much value in this case. It's like comparing the performance of floating-point with fixed-point where one is intended for general-purpose computations, and another is for fully deterministic simulations, while you still can benefit from both selectively where it's absolutely necessary.
     
  30. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    567
    On desktop platforms, it's a silver bullet used in real-world projects for years across industries.

    I don't see a problem to maintain this as an option as Unigine does. If it's possible to extend all relevant subsystems for this, well, that's great.
     
  31. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,770
    If I recall correctly, it was said long time ago, that double precision is slower than float using DOTS.

    Asking for double float support, is nearly like asking for second language to support.
    It is tremendous amount of work, that would involve.
    Have you seen math library?
    https://github.com/Unity-Technologies/Unity.Mathematics
    And that is only one selected library among many.
     
  32. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    567
    Please, don't bring it to the point of absurdity. It took 8 hours for Sean Tracy to refactor and port Lumberyard to the 64-bit implementation for Star Citizen.
    Yes, it's a plain code-gen.
    Minimal amount of effort, objectively.
     
    Thygrrr, Nyanpas and e199 like this.
  33. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,770
    Appears you are on the wrong Game Engine then.
     
  34. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    567
    Not sure how it's related to the subject.
     
  35. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    Added sin and cos into logic and now it even bigger fail for double perf

    upload_2020-3-17_20-15-15.png

    Dont know what you say proper tests I have just make real game scenario when you have big amount of logic and data and proccesor works on high load and perf is important

    Simd line is limited and processor can process 2x floats vs double
    Cache line is ~64 bytes and can keep 16 floats or only 8 doubles
    Memory bandwidth is slowest part of processor performance and can deliver 2x floats vs double

    just technically doubles can not have same speed as floats.

    You are right, for some cases where we have small amount of objects in scene like mostly empty game about space, doubles can be good solution.

    But even PC GPUs that mostly always was 32bit floating point today start support for 16bit float for doubled performance. For Mobiles 16bit float id must have for perf, so just nothing to say about doubles and ability to create games with big amount of units and level parts.

    Additionally Chunked worlds is must have for graphics, LOD, memory consumption, so they can become good complementary.
     
  36. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    567
    Too many side factors: Burst might not be tuned for double-precision, as well as the memory allocator, native containers, and so on. The tests provided by SLEEF which Burst is using under the hood are isolated from that.

    On GPU side, it's a non-issue while stuff is rendered in camera space, it's already noted in this thread.
     
  37. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    1,419
    In my case, it's the "authoring in the editor" part that I struggle with.

    I have a huge world, for example, that I would like to create procedural meshes for (in the editor -- but OMG if I needed to do it at runtime, it might take 20 years for Unity to revisit this topic). To physically move the scene camera to a location in the world and expect tools like Probuilder to work is beyond insane with floating-origins. Without double-precision, pretty much all assets and other scene-based tools would need to be rewritten or redesigned. Is this what Unity plans to make us do?

    That being said -- if things like animation/physics could piggyback off of the GPU's local transformations for rendering on some level (i.e. for initial positioning of the root pivot for transform, and then do everything else via local rotation math on CPU as it currently is done now anyway), I don't see why double-precision for simple world-positioning would be so bad, as long as it doesn't require complex rotations or transforms -- and even then, those could easily be done on the CPU as they are currently with DOTS animation.

    Not arguing for or against, but I am curious if anyone @Unity has any insights on why this "piggybacking" would be bad?
     
    NotaNaN, e199 and nxrighthere like this.
  38. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    You can inspect generated asm code from burst in Single and Double precision,
    My test dont count memory allocation and native containers only processing.

    Output code have exactly same amount of asm instructions, just few of them differ because process double data.

    I dont look closely to SLEEF but think that it suffer the same as most test on internet - they try to compare perf on single operation like float add vs double add, and dont take into account memory bandwidth, processor caches and SIMD.

    Yes single double addition almost as fast as float addition but this does not scale.
     
  39. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,264
    Please don't bring misleading information to this discussion. It took Sean Tracy 6-8 hours to port the 64-bit CryEngine 3 modifications to a CryEngine 3 fork that is Lumberyard. It took him more like two weeks to implement 64-bit, and from what I understand, he only changed position to use 64-bit and most of the changes were to the Transform and Physics modules. Everything else stayed 32-bit. He was also a CryEngine developer before working on Star Citizen.

    This, I 100% agree with. We don't have the tools right now to author 64-bit positions.

    And this I 100% disagree.

    In DOTS, we have full control over our runtime representation. All of DOTS code is visible to us licensed under UCL which gives us the ability to borrow from and modify for our Unity games and projects. Also runtime mesh generation improved a lot recently with the new Mesh APIs.

    But more importantly, I think this is exactly the reason why Unity wants to use floating origin. The "origin points" would be subscenes, and all authoring tools written today for 32 bit position will work just fine. That's not to say you couldn't convert floating origins to double precision through the GameObjectConversion, unless Unity implements floating origin using an internal engine hack that somehow makes this impossible.

    Am I missing something here?
     
    Thygrrr and NotaNaN like this.
  40. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    567
    Can you share the source of that? I can be a bit mistaken about this, my bad if so.

    Two weeks of work still not outweigh the benefits of the final result.
     
  41. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,770
     
  42. runner78

    runner78

    Joined:
    Mar 14, 2015
    Posts:
    792
    Star citizen is an specific single case, Unity an all purpose Engine. Double precision on a 2D mobile puzzle game would be an overkill. Unity would have to implement two version of the position system, float for small world games and double for large world games. That would make the whole engine much more complex and leads to new bugs and problems.
     
  43. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    567
    Unigine and Godot don't suffer this, and both are general-purpose engines. The floating origin itself works only in specific cases while double-precision is a universal tool for the job. Especially if you are working on multiplayer games at scale, or games where you need a natural workflow in the editor as mentioned here and here.
     
    Vincenzo likes this.
  44. runner78

    runner78

    Joined:
    Mar 14, 2015
    Posts:
    792
    I you sure the don't suffer? I never did anything with them, but if they use only doubles, then you have no way to compare with floats. And if they have only doubles, then they have no problem with the complexity. They probably also be using doubles from the start, if Unity convert everything to doubles, nothing would be more compatible.
     
  45. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,264
    @Antypodish Has the main interview which has most of the information. I'm having a little trouble re-finding the other interview that had the time summaries.

    Anyways, that's two weeks for a (well-constructed) hack that breaks old 32-bit functionality that wasn't needed. You can do the same for DOTS right now for the runtime in probably the same or even less amount of time. Authoring is still a problem though.

    The whole point of me arguing with you was to help you scale down the size of your request (support all libraries working in both 32-bit and 64-bit, effectively maintaining two codebases in terms of optimization) to something that has an appealing value/dev cost tradeoff to Unity (support authoring that lets us position objects in 64-bit in a way that we can use our own 64-bit transform system).
    Unigine maintains two libraries which is expensive. But they probably did that for benchmarking purposes and require users to interface with one or the other directly.
    I don't know much about Godot's solution but given they are open-source, value/dev cost likely wasn't much of a consideration.
     
  46. nxrighthere

    nxrighthere

    Joined:
    Mar 2, 2014
    Posts:
    567
    I haven't requested this, my initial question is here. I'm not even using Unity for the last three years for any serious project nor involved anywhere in the long-term where the engine is used, because of its fundamental problems (but this is another story).

    They are providing it primarily because of the industries: BIM, CAD, GIS, Engineering, Professional Simulators, and so on (they are leading technology in that areas today).

    That said, the approach works well in the game development industry too. Once you encounter the most problematic issues that extremely hard to solve (if ever possible) with origin shifting, like multiplayer games with server-side simulations, then you realize that this is the last thing you would like to deal with, ever.
     
  47. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    A problem with origin shifting is some problems just get far more complex with it. Good example is what we have in our game ocean waves that are large and used in gameplay. Waves have to be global.

    Scale can force additional engineering when using shifting. Optimizations all over that assume something never moves become problematic.

    I think for a commercial game double precision is likely to be the better solution. It's a case of you do the work once and then it's done, you don't keep hitting things you have to engineer around that you will invariably hit with an origin shifting approach. In both cases you are likely to need engine source.
     
    awesomedata, Vincenzo and nxrighthere like this.
  48. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,264
    Sorry. I misinterpreted this statement.
    If I were a Unity employee and saw that request, I would book it to the nearest restroom. Not because the requenst is stupid or invalid, but because knowing Unity's currently existing technology, I wouldn't want to be the guy assigned to tackle this.

    Whenever I see a request like that, I try to advocate for the solution requiring what I suspect to be the least amount of work required by Unity. I do this in the hopes that it will get Unity to do something quickly that will unblock people and simultaneously get people to bring up pitfalls Unity should avoid.

    For what it is worth, I have done both floating origin and double-precision outside of Unity. I actually prefer double-precision position for local applications. But floating origin when done right can do a lot better when distributing the simulation across multiple machines. Bandwidth is less, and the simulation code is forced to be implemented in a way that can scale across machines in this manner. I don't believe in silver bullets.
     
    PrimalCoder and JesOb like this.
  49. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    1,419
    That's 100% assuming that all of your runtime code is in DOTS.

    In more cases than not, this won't be the situation. Even now, I've seen many brand-new (newly-released) assets using, for example, the old character controller component in their GameObjects, which will not likely have a DOTS equivalent. Without DOTS equivalents readily available for the the current API of a tool, it would mean that existing scene-based tools (even ones that have runtime equivalents) would somehow have to happily (and magically be) converted into DOTS (or that there already exists a DOTS equivalent of the API that can be edited, etc.) so that you may (easily?) modify it to support 64-bit. I really don't see that happening for everything in the current API. Due to this restriction, all of your favorite tools you purchase from the Asset Store that rely on scene positioning to calculate things (Vegetation Studio, Probuilder-esque modeling/prototyping/scene-building tools, "in-context" animation tools like uMotion/Very Animation, etc., or gameplay-centric waves as mentioned above) will all need reprogramming or redesigns that are in line with DOTS and 64 bit runtime support.

    I wonder how willing most developers would be to dig into the guts of complicated scene-based editing tools before either deciding to just write their own from scratch -- or worse -- just give up entirely? Not everyone can reprogram their own tools, since many tools are purchased from the asset store. Beyond that though, how willing (or likely) are current (or future!) tool authors to support 64-bit when their ROI (in time) may not ultimately pay off in users/sales for a feature in Unity that is so very niche? There are many more Unity developers making mobile games than are making epic open-world games, and since this is the commonality now, I wonder if floating origin support would be enough to change that?

    Overall, tools (and support for them) being 64 bit is my main worry, regardless of whether floating-origin or double-support is the best route.
    Others who have posted here wanting double-precision are not wrong in wanting an easier time with their tools/authoring since all they'd ultimately have to do (on the authoring side) is change a few (well-placed) variable declarations, or author a (well-placed) subsystem conversion point in the pipeline to deal with this at runtime. In reality though, I don't see the massive lack of support for DOTS systems changing anytime soon -- Even with the official support of Unity, DOTS is still very behind on user-adoption. This will greatly affect open-world authoring scenarios in terms of available toolsets being converted to DOTS. After all, we're still awaiting URP/HDRP to be polished to a usable level, so I think we're all still sort of treating DOTS the same way (despite it being pretty reliable), probably due to lack of clear and heavy documentation.

    I believe that, ultimately, a HYBRID system is best in terms of supporting 64-bit (as I have suggested in a previous post above.) The open-source Godot engine is able to do it by being clever (and not hacky), so I don't see why Unity can't follow suit. Unity has been clever in the past, so I think it's possible (hopefully) for them to be clever again.


    @Joachim_Ante --
    What is your opinion on the deliverability of a GPU- or camera-based hybrid approach to positioning root transforms (for animation rendering / physics positioning) and then applying local (relative) rotation/scale/positioning to that? -- I think a hybrid floating-origin + double-precision (added just in the right places) system with a DOTS-based implementation for supporting a floating origin would work well to keep all scene and world-based tools easily convertible to 64bit precision where necessary (without lots of boilerplate code). Sometimes local/relative transitions are more important, and other times global positioning is necessary (in rare cases), so I think having this sort of official support for 64bit worlds (using partly double-precision AND origin-shifting) would be immensely helpful to DOTS adoption rates simply because people will be intrigued by Unity officially saying it supports open worlds _and_ supports easily converting existing tools! -- When Unity says "hey, yeah, we're totally doing that -- and, with very slight modifications, you can still use existing tools!" -- You'll create a revolution in open-world games. Mark my words.
     
    NotaNaN and JesOb like this.
  50. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,264
    I didn't realize you were talking about already existing non-DOTS assets at runtime using hybrid DOTS. I see where you are coming from.

    User-Adoption is small because DOTS is still in preview and rapidly evolving. It's just not really feasible to build DOTS assets for the Asset Store right now. However, that's not to say that DOTS assets don't exist. A lot of us host DOTS packages as Package Manager-compatible repos. There's about as many of these repos as there are HDRP-compatible assets on the Asset Store.
     
    NotaNaN likes this.