I'm trying to implement a camera, which is able to go very close to a planet/moon surface, without flickering surface.

The problem: Right now the position of a planet / moon is saved at the center of the planet / moon. When looking at the earth, its radius is ~6371km. So when creating a sphere with such a radius the problem starts when the camera is very close to the surface. The surface (ground) bumps up and down like randomly (~1 meter) which I am trying to prevent. This behavior is simple to understand: The vertex position in VBO is like 6371km away from the origin. And the camera (when it is close to the surface) is also like 6371km away from the planets center. So the viewmatrix is working with such high numbers, so that the result (position) flickers because of the floating precision. Right now I am using km as base unit. To use meter or other units as baseunit will not solve the problem, because it only shifts the comma. So the problem is that I need more, than the I think it was 8 digits of precision a float has, to avoid the flickering. So using doubles would solve the problem, but as far as I found, double vectors are available in GLSL, but double matrices not. Are there other algorithms which I can use?

later I want to tessellate the mesh in camera region and put a heightmap on top of it to visualize mountains. I also would like to add Simplex-noise on top of it to have a realistic surface.

The idea I have right now: To describe my idea in a simpler way I'll use a 2D representation of the problem. In the image below you can see several parts of a circle. These meshes will be used depending on the camera distance to the surface like LOD. So when being far away from the planet, the circle (sphere) should be rendered. when coming closer, smaller parts of the planet will be visible. The black dot represents the real center of the planet. The red dot represents the origin of the mesh (VBO) which will be calculated on CPU (double) before rendering the scenario. This sub mesh need to be rotated so that the camera will always be in a line with the black and red dot. enter image description here

As you can see, the red dot is moving towards the camera, so the precision problem will be solved. What is problematic here is, that the earth for example is not a sphere but a ellipsoid. So the sub-parts somehow need to be scaled non uniformly. But I think that other heads (better ones) already thought about a perfect solution for that problem.

  • $\begingroup$ Use a smaller scaling to correspond to 6371km. $\endgroup$
    – lightxbulb
    Jan 11 at 10:55
  • $\begingroup$ like I wrote it does not work. so for a radius of 6371km I would need a 0.000001 km precision. for a 6.371 mega meter I would need a 0.000000001 mega meter precision. So it is the same problem $\endgroup$
    – Thomas
    Jan 11 at 11:12
  • $\begingroup$ so the problem is that the value needs more digits than a float can store with 1bit +- 8bit exponent and 23bit mantissa so the result with different units would only change the exponent value and therefore only changes the comma position $\endgroup$
    – Thomas
    Jan 11 at 11:20
  • $\begingroup$ Partition your space and work at different precisions/lods for different parts. When you start nearing a planet switch to a higher lod and rescale things appropriately. At certain scales it's fine to have the planets as just sphere and using one scale, when you get closer to a planet you can keep the faraway ones at lower lod and increase the lod only for the ones you are closer to. Don't use too large numbers when scaling your world, try smaller numbers and just pretend that they correspond to something larger. $\endgroup$
    – lightxbulb
    Jan 11 at 12:29
  • $\begingroup$ Did you consider using plain old integers? They have the full 2^32 precision. $\endgroup$
    – pmw1234
    Jan 11 at 13:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.