3d occlusion removal

I am writing Minecraft as the static world of 3d blocks in C ++ / openGL. I am working on improving the frames, and so far I have implemented truncated iron removal using an octet. It helps, but I still see moderate and poor frame rates. The next step will be the rejection of cubes that are hidden in terms of closer cubes. However, I could not find many resources on how to do this.

+6
3d opengl
source share
5 answers

Creates a render target with a Z-buffer (or depth buffer). Then do not forget to sort all the opaque objects so that they appear front to back, i.e. Those that are closest to the camera. Everything that uses alpha blending should be brought back to the forefront, AFTER you have selected all of your opaque objects.

Another technique is disabling occlusion: you can cheaply “dry-visualize” your geometry and then find out how many pixels have failed the depth test. There is support for occlusion requests in DirectX and OpenGL, although not every GPU can do this.

The disadvantage is that you need a delay between rendering and getting the result - depending on the setting (for example, when using predicated tiles), it can be a full frame. This means that you need to be creative, for example, rendering a bounding box that is larger than the object itself, and rejecting the results after cutting the camera.

And one more thing: a more traditional solution (which you can use simultaneously with occlusal rejection) is a room / portal, where you define regions as “rooms” connected via “portals”. If the portal is not displayed in your current room, you cannot see the room associated with it. And even that, you can click your viewport on what is visible through the portal.

+7
source share

The approach I used in this minecraft level renderer is essentially fluorescence filling. The 16x16x128 columns are divided into 16x16x16 chunklets, each with a VBO with corresponding geometry. I start a flood in the channlet grid in the player’s place to find chunklets for rendering. Filling is limited to:

  • View frustum
  • Solid chunklets - if the entire side of the chunklet is opaque, then the flood will not go into the chunklet in that direction
  • Direction - the flood will not divert the direction, for example: if the current honker is located north of the starting fragment, do not flood in the chunklet to the south.

Everything seems to be working fine. I am on android, therefore, although more sophisticated analysis (anti-portals, as Mike Daniels noted), will select more geometry, I am already limited by the processor, therefore not so much.

I just saw your answer to Alan: culling is not your problem - this is what and how you send to OpenGL, which is slow.

What to draw: do not display a cube for each block, visualize faces of transparent blocks that border an opaque block. Consider a 3x3x3 cube of, say, stone blocks: there is no point in drawing a central block, because there is no way that the player can see it. Similarly, the player will never see the face between two adjacent stone blocks, so do not draw them.

How to draw: As Alan noted, use VBO for batch geometry. You won’t believe how much faster they do something.

A simpler approach with minimal changes to your existing code would be to use displayed lists . This is what minecraft uses.

+5
source share

How many blocks are you rendering and on which equipment? Modern equipment is very fast and very difficult to suppress geometry (if we are not talking about a pocket platform). On any moderately recent desktop hardware, you can display hundreds of thousands of cubes per frame at 60 frames per second without any fancy garbage.

If you draw each block with a separate draw call (glDrawElements / Arrays, glBegin / glEnd, etc.) (bonus points: do not use glBegin / glEnd), then this will be your bottleneck. This is a common trap for beginners. If you do this, you need to collect all the triangles that separate the texture and shadow parameters into one call for each setting. If the geometry is static and does not change the frame per frame, you want to use one vertex buffer object for each batch of triangles.

This can still be combined with the separation of a truncated sheet with an octet, if you usually have only a small part of your overall game world in the form of truncation at a time. Vertex buffers are still loaded statically and not changed. Frustum selects an octet to only generate index buffers for truncated triangles and dynamically load them into each frame.

+4
source share

If you have surfaces close to the camera, you can create a truncated area, which is an area that is not visible, and select objects that are completely contained in this truncated state. The diagram C below shows the camera, | - a flat surface near the camera, and a region in the shape of a truncated cone, consisting of . represents an occlusal region. The surface is called antiportal .

  . .. ... .... |.... |.... |.... |.... C |.... |.... |.... |.... .... ... .. . 

(Of course, you should also include in-depth testing and depth, as indicated in other answers and comments - this is very easy to do in OpenGL.)

+3
source share

Using Z-Buffer ensures that the polygons overlap correctly.

Enabling the depth test causes each drawing operation to check the Z-buffer before placing pixels on the screen.

If you have convex objects, you should (for performance) enable back-flipping!

Code example:

glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE);

You can change the behavior of glCullFace () by passing GL_FRONT or GL_BACK ...

glCullFace(...);

// Draw a "game world" ...

-2
source share

All Articles