To increase accuracy and significantly decrease simulation times, I made the ray marching step size vary based on a few heuristics: the rate of change of the altitude at the current location, the altitude of the current location, and an element of randomness.
The first heuristic, the rate of change of the altitude, has the biggest impact on the step size. When a short line segment is nearly parallel to the ground, the altitude doesn't varying much along the segment, which means that the density and other properties of the air also don't vary much along the segment. So if we're travelling parallel to the ground we can take much larger step sizes than if we're travelling perpendicular to the ground. When we're travelling up and down, the atmospheric properties change much more quickly and we need to smaller step sizes to accurately capture the changes and details of atmospheric properties.
These are all just a temporary improvements because I just realized that I could replace ray marching with an unbiased technique, which should also be cleaner and faster. I'll write more about this later, after I implement it.
If I were to stick with ray marching, I would want to additionally vary the step sizes based on wavelength and other factors, and I would want to take different step sizes when computing different types of scattering and absorption.