glTranslatef() very far from origin results in gaps between neighboring translates

Started by
2 comments, last by voodoodrul 10 years, 5 months ago

It's a plain old Minecraft clone ("oh no.. not another one of these..."), chunked rendering, "infinite" terrain. I have a 2D plane of WorldChunk objects. Each chunk is converted to a minimal mesh of exposed faces and stored as a VBO. Once the chunk is ready for render, I might need to place it somewhere very far from the origin, because this chunk is at, say, (16384, 16384). What happens in my rendering is that gaps appear between the chunks and, as I pan my camera around, each chunk jitters a bit due to lack of precision in absolute placement. Each chunk might jitter around 1-2 pixels, sometimes landing exactly lined up with its neighbor, other times 2 pixels offset with a gap. The problem gets worse as you go farther from the origin. Near the origin, such as below (4096,4096) the problem is not obvious. At the origin is it not possible to spot the problem at all. I know there must be limited precision in translates, so I need to do things in a fundamentally different way.

For each chunk, when it has a VBO that is ready to draw, I do:

glPushMatrix();

glTranslatef(16384.0f, 0.0f, 16384.0f);

....

glDrawArrays(GL_TRIANGLES, 1, this.numVerts);

glPopMatrix();

I thought about making my translates more like a "local world" where I simply place them relative to the viewer, but it makes a few other things difficult. I'm sure I'm doing this wrong by trying to use very large glTranslatef() values relative to the origin.

Any advice out there?

The rendering test app is @ https://voodoo.arcanelogic.net/CYDI-latest.jar if anyone cares to look at it, but it would take a while to fly far enough away from the origin to notice big gaps and jitter

Thanks!

Advertisement

You could avoid doing that huge translate if you combine the chunk position with the camera position first, because they cancel each other out when you are near the chunk to watch it. Then create a single matrix from the result (or do a single OpenGL matrix stack call).

This way you avoid those irregularities from first creating 2 matrices with huge opposite translations inside, which give bigger float rounding errors when they are combined.

Thanks wintertime! You're suggesting an idea similar to the "localized world" I was thinking of. That did indeed fix the gaps. However, now I have the same problem with my camera - it lacks float precision and jitters around when far from the origin, simply because the floats don't have the decimal precision.

My outer render loop does:

1) glLoadIdentity();

2) Look through the camera - rotate pitch/yaw, then translate to some obscenely large x,y,z

For some reason, I have to negate all the values when I do this. glTranslatef(-vectorPos.x, -vectorPos.y, -vectorPos.z);

3) Render the world

First translate to camera position

4) For each chunk, translate only the difference between the camera position relative to the chunks position.

I wonder if I'm doing this all wrong. Should I keep the entire world near the origin ( camera essentially fixed at (0,y,0) ) and just move the world around relative to the origin?

Eh.. That probably won't help. The fundamental problem is that there isn't enough decimal precision for acceleration on vectors to be smooth. I guess I need to convert to doubles instead of floats, or accept the fact that things jitter around when I go to 500000,0,500000 and beyond.

I switched to the local rendering, placing chunks relative to the camera, and keeping the camera at (0,y,0), at least as far as glTranslatef() is concerned. I also switched to doubles throughout. I can now travel to extremely far locations from the origin.

Thanks again Wintertime

This topic is closed to new replies.

Advertisement