First-person terrain navigation frustum clipping problem

Started by
24 comments, last by JoeJ 1 year, 3 months ago

Gnollrunner said:
However, I've found that some people are resistant to using double, but I don't really think the speed is an issue with a reasonably modern computer.

I considered using doubles for my planet renderer: see blog post, but ultimately decided against it in favor of a hierarchical coordinate system. The main factor in my decisions were:

  • Doubles don't even get you that far in practice. They're still not sufficient for anything farther than around the orbit of Pluto, depending on your precision requirements. This was not enough for me, because I want to have larger star systems and galaxies.
  • My physics engine is highly optimized using 4-way float32 SIMD for almost all calculations. This could potentially be rewritten in AVX double precision (at large effort), but not all operations translate well (e.g. cross-lane shuffles), and there are problems on the edge cases. E.g. what happens when doing mesh collision when your mesh data is float32 but your transform matrices are float64? this causes lots of unnecessary conversions that slow things down. The instructions are roughly the same speed according to Intel, so it's more about memory bandwidth/cache I think (a double 4x4 matrix uses 2 cache lines instead of 1).
  • Problems interfacing with GPU, which only takes float32 in most cases.

In contrast, a hierarchical coordinate system is more complex for some operations, but it wasn't that bad in practice to implement. It only took about 2 weeks to completely overhaul my engine to use it (including graphics, physics, and acoustic simulation, all custom implementations).

The general structure is that every object in the scene has a pointer to a CoordinateFrame object, which represents the local origin that an object is attached to. Each frame has a double-precision offset from the parent frame, and a local rotation matrix (float32). Within the same frame (about 3.2 km in size), all math is fast and easy. Only for far away objects do you pay any price for the extra math required to handle the transformations between frames, and even then the cost is not that high with SIMD optimizations. I have a few functions that make this easy: given two points in two different frames, produce the unit vector in each frame that points at the other point, as well as a distance between (double precision). This function walks the hierarchy between two frames to determine the relative vector with the best possible precision. This function can be used to implement most of what you need in a game engine for rendering and physics.

Advertisement

First if you have something working that you like there is no reason to change it, but I wanted to address your 3 points.

Aressera said:

  • Doubles don't even get you that far in practice. They're still not sufficient for anything farther than around the orbit of Pluto, depending on your precision requirements. This was not enough for me, because I want to have larger star systems and galaxies.

The main reason I use doubles is to support contiguous land such as over a single planet. I suppose if you want the orbit of Pluto to be down to the millimeter, sure doubles aren't enough. But as far as I'm concerned, Pluto can obit at meter or even less resolution and it's fine. That goes for galaxies also. If you are doing a simulation, I think you have a point but for a game, I don't think it's that important, and I'm not sure who would even notice. I also have a hierarchical system for suns, planets systems, really everything.

  • My physics engine is highly optimized using 4-way float32 SIMD for almost all calculations. This could potentially be rewritten in AVX double precision (at large effort), but not all operations translate well (e.g. cross-lane shuffles), and there are problems on the edge cases. E.g. what happens when doing mesh collision when your mesh data is float32 but your transform matrices are float64? this causes lots of unnecessary conversions that slow things down. The instructions are roughly the same speed according to Intel, so it's more about memory bandwidth/cache I think (a double 4x4 matrix uses 2 cache lines instead of 1).

If you are targeting old computers that's fine. But for new projects I don't really think that matters so much. Doubles aren't so much slower than float any more, and we do have AVX and AVX2 these days. It's also really dependent on the game you are working on. In my case collision is minimal since the target is an MMO. Right now I only sweep spheres and capsules, and the most important thing is organizing the data so you only do minimal calculations in the first place. For example, edges and vertexes are shared by faces. I have seen code where you pass it a triangle and it does all collision checks regardless of if you have already checked the same edges and/or vertexes. Then there is of course the data structure you use to find collisions in the first place. The actual calculation is only part of the problem.

  • Problems interfacing with GPU, which only takes float32 in most cases.

I don't find that's really a problem. Yes, you basically can't use double for anything substantial on the GPU. It's WAY too slow. That being said the methodology of going from double to float is not complex. I think I coved that in my previous responses.

Gnollrunner said:
and we do have AVX and AVX2 these days

On Intel, yes. But not on ARM, where the double SIMD is limited to 2-wide. So it will be at least twice as slow on ARM platforms (e.g. phones, M1 Mac).

Aressera said:

Gnollrunner said:
and we do have AVX and AVX2 these days

On Intel, yes. But not on ARM, where the double SIMD is limited to 2-wide. So it will be at least twice as slow on ARM platforms (e.g. phones, M1 Mac).

Well there you go. Different horses for different courses. I don't intend to put anything on a phone.

Gnollrunner said:
I don't intend to put anything on a phone.

M1 shows the future. RTX 4090 shows the past.
So don't be so sure… :D

This topic is closed to new replies.

Advertisement