Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Space rendering is full of interesting problems like this. Another one is that single precision floating point doesn't have enough precision to represent both planet scale and human scale in the same coordinate system (let alone solar system scale or galaxy scale), yet GPUs don't support double precision well. So you have to make sure that you do calculations needing high precision on the CPU in double precision and only send the GPU coordinates it can handle, or your 3D models will get crunched by precision errors.

Another one is that a planet sphere renderer will often tesselate the sphere into quads in lat-lon space. Of course the quads are split into two triangles for rendering. However, at the poles, one of the triangles has zero area because two of its vertices are the same, the pole. Then when you texture map that "quad" with a square texture, half of the texture is not shown, and you get visible seams (Google Earth suffers from this artifact, or at least it did in the past). What's less obvious is that this problem is present to a lesser extent in every quad on the sphere, because the triangle with the horizontal edge nearer the pole is smaller than the other, so half of the texture is stretched and half is shrunk. The fix is to use homogeneous texture coordinates.



KSP's approach to the precision problem is surprisingly simple: whenever you get more than two kilometers away from the origin, move the entire universe two kilometers so that the location of your craft, and all the physics-relevant computations on it, have small numbers as coordinates.

(This fix was known as Krakensbane: it solved a bug known as the Deep-Space Kraken, which was essentially that floating-point physics inaccuracies would tear your ship apart when you got much further than the moon or so, before it was implemented.)


Pretty sure that the floating origin moves with the craft now every frame. The entire universe also orbits around the craft when it is below the inverse rotation altitude threshold, which means that PhysX is doing physics in the co-rotating reference frame. That means that the "First point of Ares" -- normally (1,0,0) -- rotates around the z-axis as the craft moves and you have to query Planitarium.right to determine what its current orientation is. That means that tick-to-tick coordinates change, which makes trajectory optimization hard because values in the future won't match at all. You have to remove that rotation to get something like actual inertial coordinates (after also removing the offset origin to the vessel as well).

They've also recently fixed issues with single precision calculation in KSP1 and used a double-precision QuaternionD.LookRotation in the maneuver nodes to keep interplanetary trajectories from hopping around a lot.

[ oh it also uses left handed coordinates, which is terrible which means (0,1,0) is the north pole and the left handed cross product gets used so dual vectors like angular momentum point south for east-going orbits -- except the Orbit class uses normal right handed vectors and when you forget to .xzy swizzle a vector for one reason or another you can wind up debugging an issue all day long ]


Ah, did not know that - last time I was working on KSP mods that interacted with that part of the code was in 0.19. Really caught me off guard when everything started to fly off into space when I tried to move ships past the end of the space center or so.


That's interesting. It doesn't sound that simple though, I imagine there are some gotchas with that. They are probably constrained by what Unity allows.

In my custom engine I did the world to camera transform for each object on the CPU in double precision, essentially making the camera the origin for all subsequent single precision computations on the GPU. That works for small objects and even large objects that are split into small parts, like a planet split into LOD terrain tiles. But it didn't work for orbit lines because they are a single object at planet scale that you can zoom in on to see at human scale (I didn't have an adaptive tesselation system like the one in the article).

It also wouldn't have worked for galaxy scale, where even double precision wouldn't be enough. I don't know exactly what Celestia and similar "entire universe" apps do. Emulated quad precision floating point?

Edit: I just realized that you are talking about precision issues with the physics engine, while I'm talking about precision issues in the rendering engine. Related but slightly different. Physics engines aren't constrained by GPUs and can use double precision throughout. But they often have stability issues even in normal circumstances so I can certainly imagine that solar system scales would be a problem even in double precision.


KSP's solution to the graphics problem is what they call "scaled space". Basically, nearby objects like your spaceship, the planet you're on, etc are rendered normally, but there is another copy of the solar system that's scaled down to 1/10 scale on another scene, and composited in behind everything. This is where things like orbit lines are drawn. It works well enough for KSP's solar system, which is rather small, but there are rendering issues with modpacks that add other solar systems far away from the sun; I suspect that since KSP2 is adding interstellar travel they are going to need to come up with another solution.


An interesting piece of industry-insider information, at least as far as I recall from the Sony pub regulars I knew back in the day: the colloquial term for the polar artefact you describe is the cat’s bumhole.


One way around this is cube-mapping. You construct a cube then normalize all the vertices to "over-inflate" it until it's a sphere. Then you have six textures mapped to the faces of the cube, and no cat's bumhole, and no international date-line zipper. If you subdivide the faces of the cube into rectangles via equal angles instead of naively into a grid, then cut each of the rectangles into two triangles by the shortest diagonal, then you get a very nice tessellation with triangles that are nice and fat (nearly equilateral) with no thin sliver triangles and they're all of approximately equal size. The other thing you can do is double the vertices along the cube face edges, so that no two cube faces share any vertices. In that way you can avoid some "hairy ball theorem" related problems when it comes time to do normal mapping, which involves constructing tangent and bitangent vectors for each vertex. Each face of the cube can have a field of tangents and bitangents with no discontinuities, and since no texture or normal map crosses any boundary between faces, you avoid problems that come up with such discontinuities. (Hairy ball theorem says it's impossible to construct a field of tangents and bitangents covering a sphere that does not contain some discontinuity, so one solution is to stuff the discontinuities between cube map faces where they cannot bother any texture or normal map.)

Tessellated sphere looks like this: https://imgur.com/l3GmWq3


KSP does indeed use tessellated spheres. This solves texture mapping issues. however, there are still some weird camera and physics bugs due to certain systems using a longitude/latitude system for planets.


Creating astronomy visualizations often involves all sorts of fun tricks. I work in a planetarium as a 3D animator and each day has interesting unique challenges. Indeed we have to remain mindful of not pushing Maya too hard when it comes to series of scale.

We use fluids as a way to create 3D nebulae that can be flown through. https://thefulldomeblog.com/2013/08/20/the-nebula-challenge/

Or if you constrain the fluid into a sphere, then you have a dynamic volumetric sun. https://thefulldomeblog.com/2013/07/30/customizing-a-close-u...

When needing to fly through a star field, relying on particle sprites is an easy way to quickly render thousands of stars. https://thefulldomeblog.com/2013/07/03/creating-a-star-field...

Background stars are achieved by point-constraining a poly sphere to the camera. Having a poly sphere allows for easy manipulation to create realistic diurnal motion. https://thefulldomeblog.com/2013/11/13/background-stars-v2/

Flying through a galaxy field can be achieved with loads of galaxy images mapped to poly planes. For galaxies that are seen edge on, we sometimes add more detail by emitting fluid from the image colors. https://thefulldomeblog.com/2013/07/16/flying-through-a-gala...

Simulating the bands of Jupiter is tricky but I've done some experiments with 2D fluids. https://thefulldomeblog.com/2014/01/30/jupiter-bands-simulat...

And of course since the visuals are rendered for a planetarium dome, we gotta render using a fisheye camera. These days all render engines support fisheye, but 10 years ago it was a different story. https://thefulldomeblog.com/2019/09/07/exploring-render-engi... https://thefulldomeblog.com/2013/06/28/fisheye-lens-shader-o... https://thefulldomeblog.com/2013/07/23/stitching-hemicube-re...


I'm sure you've heard this before, but have you checked out Space Engine[0]? It has some pretty advanced features, like path animations and cubemap rendering. I'm not sure how well it'd integrate into existing workflows, but I've used it for creating high dynamic range skyboxes for spacecraft renders.

[0]: http://spaceengine.org/


> Simulating the bands of Jupiter is tricky but I've done some experiments with 2D fluids.

Nice! I've always wanted to do some fluid dynamics on the surface of a sphere, but the math is too hard for me. I found a video on youtube where someone has done some interesting things a few years ago: https://www.youtube.com/watch?v=Lzagndcx8go&t=1s but there's very little information about it. Then there was what was done for the film 2010: The year we make contact" http://2010odysseyarchive.blogspot.com/2014/12/

I've had to resort to simpler means myself, which means faking it. I use OpenSimplex noise on the surface of a sphere, and from this I can find the gradient of the noise field tangent to the surface of the sphere, rotate this vector 90 degrees about an axis passing through the center of the sphere -- which is equivalent to some kind of spherical curl of the noise field -- which gives me a non-divergent velocity field. Because incompressible fluid flows are also non-divergent, there's a strong but superficial resemblance -- it looks like fluid flow, even though it is just an arbitrary process. Into this field, I dump a bunch of colored particles and let them flow around, painting alpha blended, slowly fading trails behind them onto the surface of a cube to be used later as textures of a cubemapped sphere.

For the bands, I superimpose a simple velocity field of counter rotating bands on top of this curl-noise generated velocity field. Something like: horizontal_velocity += K x sin(5 x latitude)

Results looks like this: https://duckduckgo.com/?q=gaseous-giganticus&t=h_&iax=images...

The idea for using the curl of a noise field to mimic fluid dynamics is from a paper by Robert Bridson, et al.: https://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph2007-cu...

This program is open source, it's here: https://github.com/smcameron/gaseous-giganticus


> yet GPUs don't support double precision well.

Are there GPUs without FP64 functionality at all? Or are you just referring to most consumer GPUs being built for FP32 performance over FP64?


It's not that GPUs don't support fp64, it's that for domestic gamer GPUs fp64 arithmetic is normally ~1:32 performance of fp32 arithmetic.

e.g. 1080gtx

    FP16 (half) performance
    138.6 GFLOPS (1:64)
    FP32 (float) performance
    8.873 TFLOPS
    FP64 (double) performance
    277.3 GFLOPS (1:32)

e.g. 3090rtx

    FP16 (half) performance
    35.58 TFLOPS (1:1)
    FP32 (float) performance
    35.58 TFLOPS
    FP64 (double) performance
    556.0 GFLOPS (1:64)

Only generally 'tesla' class cards targeted at super computers have a 1:2 ratio (e.g. v100, A100, Titan V). Note, I believe Titan V is the only Titan series GPU with good double performance, as the Volta architecture was never available to Geforce GPUs.

https://www.techpowerup.com/gpu-specs/geforce-gtx-1080.c2839

https://www.techpowerup.com/gpu-specs/geforce-rtx-3090.c3622

https://www.techpowerup.com/gpu-specs/tesla-v100-sxm3-32-gb....

https://www.techpowerup.com/gpu-specs/a100-sxm4-80-gb.c3746

https://www.techpowerup.com/gpu-specs/titan-v.c3051


For AMD GPUs the FP64/FP32 performance ratio is twice as high compared to nVidia, it’s 1:16

https://en.wikipedia.org/wiki/Radeon_RX_5000_series#Desktop

https://en.wikipedia.org/wiki/Radeon_RX_6000_series#Desktop


There are many GPUs with no double precision floating point support in hardware. Modern ones can probably emulate it. Older ones don't have any explicit support. Most real time 3D renderers do not use double precision at all.


> There are many GPUs with no double precision floating point support in hardware.

Which ones? I'm genuinely curious about this.


I think all of the ones listed as DirectX 10.1 or lower on this page: https://en.wikipedia.org/wiki/Feature_levels_in_Direct3D

Those are all quite old now of course, but even modern GPUs may not have 64-bit ALUs and rely on emulation instead. Intel Gen11 in Ice Lake, for example: https://01.org/sites/default/files/documentation/intel-gfx-p...

In mobile architectures 64-bit ALUs can be an optional feature that is omitted for lower end configurations. I know this is true of PowerVR.


Ah interesting to know about Gen11, thanks for the links.


    Some napkin/WolframAlpha math:
    if you wanted to use simple x,y,z coordinates,
    with the sun at the center
    and be able to represent locations at 30 AU (Neptune)
    with an accuracy of 1mm, e.g. 30AU vs 30.000...0001AU
    you'd need ~16 decimal digits of precision
    which is the same number of bits as a double (FP64)
    of course there's better ways to do this,
    in the surrounding smarter comments


> Another one is that single precision floating point doesn't have enough precision to represent both planet scale and human scale in the same coordinate system (let alone solar system scale or galaxy scale), yet GPUs don't support double precision well.

Could you do double-single computations on a GPU? (By that I mean something like double-double arithmetic, only with two singles instead of two doubles.)


Sure, with a performance penalty. Some GPUs do support double precision, though again at a performance penalty. You might run into issues with the fixed function parts of the GPU being single precision even on GPUs that support double precision types in shaders, depending on how you do things. Also, shading languages probably don't have nice libraries for double single precision so you'd have to roll your own, and probably without niceties like operator overloading.

It's not required for space rendering, as once everything is in camera coordinates you no longer have any visible precision issues (as long as you are using a float reverse Z buffer). You just have to be careful to make sure your world to camera transforms are done on the CPU, and you break large objects like planets into small LOD chunks with their own local coordinate systems, which you need to do anyway.


If I recall correctly, on a CPU, the penalty of doing "double-X" is something like 1:7 or so compared to just doing X. On most consumer GPUs, the penalty of doing doubles instead of singles would be a 1:24 or 1:32 these days, wouldn't it? So there should still be a fourfold speedup or so. Mixed binary operations with one single and one double-single should be cheaper, whenever applicable.

As for "rolling your own", this is a compiler transformation, effectively. So it may depend on your workflow whether it's painful or not.


Can’t we use an icosahedron for a better sphere?


Yes, and there are many other tessellations you can use, if you texture it with a single texture. But you can't texture a whole planet with one texture if you allow zooming from planet to human scale, the texture would be terabytes. You must tile the sphere with textures that are loaded on demand, and textures are square, so it makes sense to divide the sphere into quads (actually a quadtree for zooming).


If you want to texture a sphere, the cubesphere is the best way to draw. It is what you get when you subdivide a cube using slerp instead of lerp for interpolation.

Icosahedron doesn't work well if you have textures. The triangle topology near the poles lead to bad texturing.

Icosahedron may work better if you have a fully procedural pipeline and don't need to worry about square textures.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: