Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add engine scale parameters to specify the scales of 3D units #1851

Open
madmiraal opened this issue Nov 17, 2020 · 8 comments
Open

Add engine scale parameters to specify the scales of 3D units #1851

madmiraal opened this issue Nov 17, 2020 · 8 comments

Comments

@madmiraal
Copy link

Describe the project you are working on:
Working with multiple projects at different scales. See discussions at #43547, #41140, #42769, #1617, and others.

Describe the problem or limitation you are having in your project:
The engine operates at a single scale which works well when working with objects that are sized around the unit scale (think metres). However, when working with, for example, VR, the objects are sized closer to the 1/100th of a unit (think centimetres). And, when working with, for example, a space simulation, the objects can be sized in the 1000s (think kilometres) or even more.

The main problem is the physics engine always works to the same level of precision. In 3D, for example, it has a default collision margin of 0.04 (think 4cm) and a minimum of 0.001 (think 1mm) and a maximum of 10 (think 10m). This scale is generally too big when working with VR and way to small when working with space simulations. A frequently touted suggestion is to change the scale of the assets, but this doesn't work (see discussion in #43547, for example) and is shifting a problem with the physics engine onto the asset designers, who should be creating assets at the "right" scale (Blender assumes one unit is 1m, but other tools make different assumptions).

Similarly, the camera always works to the same level of precision; CSG shapes work to the same level of precision, etc.

Describe the feature / enhancement and how it helps to overcome the problem or limitation:
Have an engine scale setting. This will enable different games to set the scale of the engine according to their needs.

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:
Two project settings to define the scale parameters would be required:

  1. Define what one unit represents within the engine. All settings are scaled by this unit representation. For example, when setting the scale to 1 = 1cm, the physics margin of 0.04, will be viewed as 0.04cm. Similarly, the camera and editor view will scale meshes so that z-limits, offsets, etc. work at the scale defined.
  2. Define the scale of the assets. This scale would only need to be changed if assets are not designed with the Blender assumption of 1 unit is 1m.

If this enhancement will not be used often, can it be worked around with a few lines of script?:
No.

Is there a reason why this should be core and not an add-on in the asset library?:
It's the inability to workaround this issue that is driving this proposal.

@Cykyrios
Copy link

Somewhat related, some fields in the editor round input to 2 decimal places, which makes millimeter precision impossible at the currently assumed 1 unit = 1 meter scale.

I also want to say that some settings cannot follow the first option you propose: if 1 unit = 1 meter, then default gravity is 9.8 m/s², which is fine; however with 1 unit = 1 centimeter, default gravity becomes 9.8 cm/s², or 0.098 m/s², which is definitely not good. I'm also curious about the effects of other settings such as damping, for instance.
This would require either automatically adjusting the settings depending on the scale, or displaying some kind of warning so that users don't get surprised everything feels strangely floaty.

And a third point, rendering (I suppose this is covered by the z-limits and etc. you mention): there is the clipping planes issue, but lighting will also be affected (falloffs and probably some other rendering settings).

@TokageItLab
Copy link
Member

TokageItLab commented Nov 17, 2020

@Cykyrios As of 3.2.3 we have a problem with large minimum units. The hints of Camera clipping and Shape3D used for CollisionShape were fixed in #43547 (this was to remove the differences with CSGShapes), but there may be other hints of parameter that need to be fixed. If you need fixing them, please list them.

Regarding the scaling of units, I believe that the name "engine scale" assumes that not only the scale of the object, but also physical parameters such as gravity and other physics, as well as the parameters of the renderer are properly scaled.

@aaronfranke
Copy link
Member

aaronfranke commented Nov 18, 2020

I am very against having different scale options in the engine, it would complicate the engine codebase and be a complete disaster for third party addons, while really just masking the actual physics problems with the engine that cause users to want a different scale. Issues with physics not working properly at different scales are due to bugs in the physics code. Physics problems should be solved in the physics code, not in the rest of the engine.

Instead, we should:

  • Fix physics bugs that cause different behavior at different scales. Perhaps change the minimum margin to 0.000001 or something, and the maximum margin to 1000000 or something.

    • As far as I understand it, very small margins work fine if the objects are very small, but are a bad idea on large objects, so if you are dealing with small objects it's fine, and vice versa. In theory you should be able to divide the size of your objects object by 2 and divide the margins by 2 and it should work the same way (ignoring gravity/etc).

    • For PRs like Lowering the Minimum Unit at Shape3D and Cameras godot#43547 that @TokageItLab made, I think we should take this idea even further and give users lots of freedom in the values they pick, perhaps changing the minimum and step size to CMP_EPSILON.

  • To help improve physics accuracy, allow compiling Bullet with doubles and/or make this the default. Bullet can use doubles without the rest of the engine using doubles, and it helps a lot with jitter and inaccuracy. Some Godot developers are already doing this on their own games using custom Godot builds.

  • Encourage 1 unit = 1 meter scales, and anywhere that this assumption breaks things, treat it as a bug moving forward.

  • As @Cykyrios noted, some inspector fields forcibly round to a set amount of decimal places. These are bugs, since Godot already has a setting to control this, but it's not used in many places where it should be:

Screenshot from 2020-05-13 02-37-14

@madmiraal
Copy link
Author

I am very against having different scale options in the engine, it would complicate the engine codebase and be a complete disaster for third party addons, while really just masking the actual physics problems with the engine that cause users to want a different scale. Issues with physics not working properly at different scales are due to bugs in the physics code. Physics problems should be solved in the physics code, not in the rest of the engine.

I think you misunderstand what this proposal is about. This proposal is not about increasing the level of precision of the physics engine. This proposal is about adjusting the level of precision to the needs of the game. At large scales, precision should be reduced for better performance. At smaller scales precision needs to be increased. This not only applies to the physics engine, but to other components as well. The problem is that third party addons, like the Bullet physics engine, don't have this flexibility. Yes, this will increase the complexity of the engine, but that is the point of good code: hide the complexity from the user. It will make things easier for the users, who are desperately trying to get things to work, adjusting the few parameters that they're able to change, but failing and getting frustrated, as the links I provided in the OP show.

@aaronfranke
Copy link
Member

aaronfranke commented Nov 18, 2020

This proposal is not about increasing the level of precision of the physics engine. This proposal is about adjusting the level of precision to the needs of the game. At large scales, precision should be reduced for better performance. At smaller scales precision needs to be increased.

The problem is that you're not actually changing the precision level. You're just scaling everything up or down. Your proposal states "All settings are scaled by this unit representation" and how the camera, editor view, meshes, z-limits, offsets, etc would need to be scaled in accordance with this setting.

as the links I provided in the OP show.

With godotengine/godot#42769 (comment), your proposal doesn't actually solve any of the things in that comment.

I had to set gravity to the 1E5 range to get noticeable orbits at 100-1000 units distance. The slider only goes to 1024. At higher distances this would need to be even higher.

Let's say that this user chooses 1 unit = 1 kilometer so that the 1E5 value fits within the artificial 1024 maximum. Then they later want to make orbits 100x bigger than that. Oops, they can't because they hit the limit again, I guess they need to scale their game down again? The proper solution here would be to allow setting values above 1024.

Further, dividing a large G with the square of a large distance may lead to computational errors at high distances, since the square could lead to incredibly large numbers.

This isn't actually an issue for the exact same reason as godotengine/godot#43547 (comment). If you have numbers around a few million units, with 32-bit floats you can expect the margin of error to be around 1 unit. If you have numbers around a few thousand units, with 32-bit floats you can expect the margin of error to be around 0.001 units. In both cases the percentage of error is the same, so scaling everything does literally nothing. If you have incredibly large numbers, the error will be "large", but that would still be very small compared to the numbers you're using. So if you scale down everything by 1000x to have a "smaller error", that error is just the same percentage of a smaller number.

#41140: "The default (and minimum) CSGShape Snap is 0.001"

If the scale was millimeters, then 0.001 would be micrometers. Or... hear me out: we should just allow users to change this value to be smaller, so that you can set 0.000001 to mean micrometers.

The problem is that third party addons, like the Bullet physics engine, don't have this flexibility.

If small margins on small objects don't work properly in Bullet, then that's a bug with Bullet and should be fixed in Bullet.

@Calinou Calinou changed the title Engine scale parameters Add engine scale parameters to specify the scales of 3D units Dec 12, 2020
@jdumas
Copy link

jdumas commented May 20, 2021

If small margins on small objects don't work properly in Bullet, then that's a bug with Bullet and should be fixed in Bullet.

While I agree with the statement, in practice Bullet has a lot of hardcoded thresholds that assume units to be within a certain range. So those "bugs" may be 1) hard to fix and 2) it might take time to merge those back upstream.

@aaronfranke
Copy link
Member

aaronfranke commented May 20, 2021

@jdumas In the future, Bullet will no longer be included with the engine, but instead will be an official plugin as stated here. Moving forward the main focus will be on Godot Physics and not on Bullet.

While an official plugin implies effort made by the dev team to fix issues, at some point it can't be expected that Godot fixes the bugs in Bullet when instead the Godot devs could work on Godot Physics. Also, Bullet isn't very well maintained. It's currently maintained by one guy from Epic Games Google who isn't very active and doesn't often listen to downstream projects or review PRs. Basic things like clang-format aren't enforced and CI checks don't pass. As time passes, supporting Bullet is becoming more of an uphill battle.

@jdumas
Copy link

jdumas commented May 20, 2021

Completely agree with all that. Looking forward to Godot Physics, this looks neat!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants