Planetary Precision

Hey Folks! Hope everyone had a good weekend. It was beautiful out here, and we accordingly spent a good amount of time outdoors. Some brush clearing, some playing with the toddler, and a nice afternoon sit with some drinks. And it's having a pronounced effect on my mood, so I think there was definitely some seasonal affective disorder going on. Time to start walking more!

Back at the office, progress came in a few bursts today, but it was good progress. I finally figured out why my rendering was so jittery: the precision upgrades from my last attempt weren't complete.

As I was writing my news on Friday, Michael asked me about what I was up to, and I tried talking my way through the problem with him. And as is often the case, simply trying to explain the problem produced an "ah ha!" moment. I was seeing jitter when zoomed-into Jupiter, which is roughly 780 million km out. But double precision numbers are supposed to have roughly 15 digits accuracy. 780 million km is a 9-digit number. Even if we reduced the units to meters (780 billion meters), that's 12 digits. We should be getting something like millimeter precision at that orbital range.

Something didn't add-up.

I let it stew over the weekend, and looked into it with a fresh brain this morning. And sure enough, there it was: my planets and moons were still using single precision positions. I had upgraded ships to have double precision position, and even updated the solar system to use double precision time. But I forgot to do the same for celestial bodies.

A little refactoring later, I had two circles drawn for each body, a blue one using the old single precision, and a green one for double. And at first, I didn't see the difference I expected. Both were still jittering, but slightly differently. Double-checking my work, I realized that there were one or two places more where I had to be careful about maintaining double precision as long as possible before boiling it down to single precision (since the renderer requires single x, y, and z coords to draw stuff).

Basically, do everything using double precision until the very last moment, and cast to single to assign on-screen position.

That did the trick. I could zoom into Jupiter, so close that were it to have mountains they'd be plainly visible, and it was still smoothly arcing across the screen. Smooth planet positions for the win!

With that done, I started tweaking a bit more to see if I could get the new rendered orbit map to look as good as the old one. You can see them side-by-side in today's image (left: old, right: new). There are some rendering occlusion issues in the new version, the glow doesn't look as nice/thick, and there's still a lot of logic wrapped-up in the old one. So I'm leaning towards retrofitting the old one with this new precision stuff. And that's coming along pretty well so far.

There are definitely some optimizations needed, though. Some of which I can copy from the new version, I think. And I have some ideas to try for reducing the number of draw calls, too.

And either way I go, the course-plotting needs a UI overhaul to make it more user-friendly. Currently, it's more of a debugging tool with several unrealistic buttons and widgets. We should be controlling navigational and performance parameters with this control panel, not rendering and debug commands.

I feel good, though. I was worried I might need to create a subsystem renderer or some sort of physics simulation mode to render planets at close ranges, and now I can skip all that. Hopefully, that means we have some manual flight controls to play with soon!

Tags: Ostranauts