🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Issues with floating origin

Started by
58 comments, last by dragonmagi 2 years, 3 months ago

Nagle said:
If you always move the origin by an integer distance, that ought to put an relatively small upper bound on the creep. I think. That is, if you have a floating point number, and you do something like this, which corresponds to moving the origin and moving it back,

If your assumption is that adding integer numbers to floats would preserve more precision than adding real numbers, i don't see how the technical representation of mantissa and exponent bits would back such assumption.

Advertisement

dragonmagi said:
you don't want to do new often during runtime (frame-by frame code). Memory allocation is slow.

Not in .NET, not in the Gen 0-2 heaps. It's the garbage collection that's slow. Furthermore, the Vector3 is a struct, not a reference type, so updating its properties vs. creating a new is not handled the same as a reference type. For example:

It's dead Jim.

Remember, I said this before before: I am not using Unity. This is my own stuff, and the math library is from System.Numerics and backed by SIMD instructions.

As for looping through every object and moving it, yeah, I get that it's not as performant as moving a root node. And if I had thousands upon thousands of objects, it'd be a real killer. But we're talking 20 objects at most here. If it can't loop through this code in a blink of an eye, then something is seriously wrong. Regardless I am aware of it, and should I need to, I'll optimize it.

Regardless, anyone who thinks that your CFO method is slow is dead wrong, and have likely implemented it incorrectly.

Anyway, we're getting off topic. Again. This thread is not about performance, but about the issues I was facing regarding floating point precision problems while using floating origin.

dragonmagi said:
true, it is very creepy so don't do it!

OK, so how would you suggest I offset the world? I'm guessing that by using the root node and having everything as a child of that node, it won't compound floating point error in all objects, just the root? I can give that a shot and see if it improves the precision.

Update

So far, so good. Looks like putting it under a root node has helped. However, just to note: Performance has NOT changed. Which is fine by me.

Update the 2nd

And now things are broken again. Back to the drawing board…

dragonmagi said:

@Tape_Worm

Care to help a brother out? It'd be nice to know what I'm missing.

Honestly, beyond the information i have given, the best way for me to help is for you to buy at least the CFO asset. It cost almost nothing, has C# code implementations, documentation, demo code. I can't explain it all in detail here.

I missed this reply from earlier…

  1. Don't assume everyone has money to burn, no matter how cheap your package may be.
  2. If I buy this, what guarantees do I have? If I can't get it to work with my systems (remember, not using Unity here), then can I get my money back?
  3. This isn't a market place, I posted here for help and to learn, not to be sold a product.

I get that you want to make some money off of your work, but to be honest, I find this kind of off putting. Why bother posting? Did you really want to help or was it so you could get another customer?

Such subordinating tone isn't motivating to provide further help, i guess. Not the first time you behave like that.
Papers are free to read - no reason to complain.

I propose you try the following options:

  1. Don't change the objects - change the modelview matrices you give to GPU so it transforms the objects to the origin where your camera is.
  2. If this does not work, probably your objects world space coordinates are too large and can't represent small distance between objects as intended at all. Visuals are your least problem if so. To proof, log numbers to a text file to see if the small physics changes you apply are accurately represented.
    If not, you need subspaces and to make objects coordinates local to them, and apply physics in those local coordinates, which are small and thus precise. To render, make modelview matrices per object to transform them to the view space at the origin. That's some work ofc. You no longer have a simple global worldspace for your game.
  3. Do it all on CPU, if only to debug and look up the numbers. But instead changing objects every frame accumulating error, apply the transformation(s) to a copy of your objects.

JoeJ said:
Papers are free to read - no reason to complain.

  1. I've read the papers - I'm not complaining about those, but I do find them vague (or maybe I'm just dumb and don't grasp the finer details).
  2. I don't like being sold something when I'm just asking for information/clarification. If you don't mind a sales pitch, then that's fine for you, not for me.

JoeJ said:
Such subordinating tone isn't motivating to provide further help, i guess. Not the first time you behave like that.

If all he wants to do is sell me something, then I don't want that kind of “help”. And, just for my curiosity, when exactly did I “behave like that” prior? Because I don't want people derailing my thread into topics like optimization? It's my thread dude, if I want people to stay on topic, I'll be as “subordinating” as I like.

JoeJ said:
Don't change the objects - change the modelview matrices you give to GPU so it transforms the objects to the origin where your camera is.

I don't have that level of access from this application, so that's out.

JoeJ said:
If this does not work, probably your objects world space coordinates are too large and can't represent small distance between objects as intended at all. Visuals are your least problem if so. To proof, log numbers to a text file to see if the small physics changes you apply are accurately represented. If not, you need subspaces and to make objects coordinates local to them, and apply physics in those local coordinates, which are small and thus precise. To render, make modelview matrices per object to transform them to the view space at the origin. That's some work ofc. You no longer have a simple global worldspace for your game.

Just for clarification, my issues aren't physics related (yet). That said, I feel like sub spaces might be the only way to go just to make this work in the way that I want. And you're right, it's gonna a fair bit of rework. Hence why I've been trying to push using this particular method. But the more I mess around with it, the more I'm coming to realize this subspaces/sectors idea may be the way to go. My numbers are really large for sure, as I said earlier, 800,000 x 200,000 is the target spot I wanted to hit, and that's just too big for single precision while maintaining accuracy I'm guessing.

JoeJ said:
Do it all on CPU, if only to debug and look up the numbers. But instead changing objects every frame accumulating error, apply the transformation(s) to a copy of your objects.

Most of it is already being done the CPU. That's how I'm measuring.

Tape_Worm said:
800,000 x 200,000 is the target spot I wanted to hit, and that's just too big for single precision while maintaining accuracy I'm guessing.

Tbh, i've never had precision issues from large numbers yet in my whole life. So i lack experience.

People say we can expect 6 digits of accuracy from floats, so i guess you may have physics issues already, if units move smaller steps than something like 1000 or 100. Ofc. space games are forgiving, because no multibody problems. But still i would not wonder if accuracy suffers at greater distance. How can you be sure your jitter is only a visual issue?

You said it's only about 20 objects? If so (or less than say 10k), no optimized simd stuff might be needed, and making (or seeking) some basic math lib using doubles would be probably less work than adding logic of subspaces. Math skill isn't needed to implement matrix mulitply, dot and cross products, which are the most complex operations. Just look up some reference. But make sure it has the same conventions (row / column first, multiplication order) you're used to.
There is also the option to use doubles only for points (positions), while keeping floats for vectors (orientation, rotation). So no need for double matrices, just a double vec3 would do.

To me, it looks like this, comparing the two options:
Doubles: Will just work. No problems to expect in the future. (ofc, for rendering you still need to transform close to origin, then convert to float)
Subspaces: Doubt regarding boundary issues remains, extra logic makes the project harder now and in the future

If Chris Roberts can take the costly but easy route, then you can do too (ofc. he never intended to make a game at all, but still) ;D

JoeJ said:
he never intended to make a game at all, but still

Heh, I'm guessing you're not a fan of Star Citizen then?

JoeJ said:
People say we can expect 6 digits of accuracy from floats, so i guess you may have physics issues already, if units move smaller steps than something like 1000 or 100. Ofc. space games are forgiving, because no multibody problems. But still i would not wonder if accuracy suffers at greater distance. How can you be sure your jitter is only a visual issue?

Oh, I'm willing to bet you're 1000% correct that there are physics issues in the distance. I'm just trying to get this thing settled on a system and go with it. At that point I'll adapt my collision system accordingly. One thing at a time and all that.

JoeJ said:
Doubles: Will just work. No problems to expect in the future. (ofc, for rendering you still need to transform close to origin, then convert to float)

I'm still considering this. I found a math API for C# that allows for generic vectors, so I may give that a whirl for giggles. If it works out, I'll probably just stick with it for simplicity. After all, it's just a 2D top-down space thingy, not a realistic simulation of the solar system, I don't need to have exact distances or anything. I mean if it's good enough Chris Roberts… :P

Thanks for all your help @joej, appreciate it.

Tape_Worm said:
Heh, I'm guessing you're not a fan of Star Citizen then?

I think Roberts was paid by the AAA industry, to sabotage gamers trust in Kickstarter, to keep the rising indie competition under control.
Roberts was excited, because this way he could fulfill what always was his dream: Becoming a Hollywood movie director.

It worked. Board games outdo video games on KS, and Roberts got Hamill.

But don't feel yourself so secure, AAA… wait and see… >:D

JoeJ said:
Doubles: Will just work. No problems to expect in the future. (ofc, for rendering you still need to transform close to origin, then convert to float)

Well, I converted to using the math API that uses generics and converted to using double for everything in the application. I only cast down to graphics calls (e.g. sprite drawing, primitive drawing, etc…) and so far it's working well. Including collisions at a distance.

The only down side is that the performance has taken a slight hit. But apparently this bunch doing the math API is planning on putting in SIMD intrinsics into their math functions, so that may give a slight boost. Regardless, the hit is tiny, so I'm not too heart broken about it.

Again, thanks for your help and suggestions @joej.

@Tape_Worm

Tape_Worm said:

JoeJ said:
Doubles: Will just work. No problems to expect in the future. (ofc, for rendering you still need to transform close to origin, then convert to float)

Well, I converted to using the math API that uses generics and converted to using double for everything in the application. I only cast down to graphics calls (e.g. sprite drawing, primitive drawing, etc…) and so far it's working well. Including collisions at a distance.

Super. For some reason many people think converting to double is going to be way harder than it really is. But as I said, unless you are tied to a game engine, it's really quite simple in most cases. Just as a heads up…… If you are still using 32 bit float matrixes on the GPU side and you find you still have some jumping issues, I might suggest pulling the projection part out of the matrix and doing it as a post step. This was one issue I had, and that solved it.

This topic is closed to new replies.

Advertisement