20

I would like to draw voxels by using opengl but it doesn't seem like it is supported. I made a cube drawing function that had 24 vertices (4 vertices per face) but it drops the frame rate when you draw 2500 cubes. I was hoping there was a better way. Ideally I would just like to send a position, edge size, and color to the graphics card. I'm not sure if I can do this by using GLSL to compile instructions as part of the fragment shader or vertex shader.

I searched google and found out about point sprites and billboard sprites (same thing?). Could those be used as an alternative to drawing a cube quicker? If I use 6, one for each face, it seems like that would be sending much less information to the graphics card and hopefully gain me a better frame rate.

Another thought is maybe I can draw multiple cubes using one drawelements call?

Maybe there is a better method altogether that I don't know about? Any help is appreciated.

Xavier
  • 8,828
  • 13
  • 64
  • 98

3 Answers3

21

Drawing voxels with cubes is almost always the wrong way to go (the exceptional case is ray-tracing). What you usually want to do is put the data into a 3D texture and render slices depending on camera position. See this page: https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch39.html and you can find other techniques by searching for "volume rendering gpu".

EDIT: When writing the above answer I didn't realize that the OP was, most likely, interested in how Minecraft does that. For techniques to speed-up Minecraft-style rasterization check out Culling techniques for rendering lots of cubes. Though with recent advances in graphics hardware, rendering Minecraft through raytracing may become the reality.

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
  • Yes, render back to front along the axis that is most aligned with the view direction. Start by rendering quads with transparency. Once that works you can try to insert the "sides" between each layer as well. – phkahler Sep 27 '10 at 16:58
  • Your link is broken now. – Ruslan May 06 '17 at 18:29
  • 1
    @ybungalobill using [DOOM technique in 3D](https://stackoverflow.com/a/48092685/2521214) instead of layers is more interesting for beginners but the idea is almost the same – Spektre Jan 10 '18 at 12:12
8

What you're looking for is called instancing. You could take a look at glDrawElementsInstanced and glDrawArraysInstanced for a couple of possibilities. Note that these were only added as core operations relatively recently (OGL 3.1), but have been available as extensions quite a while longer.

nVidia's OpenGL SDK has an example of instanced drawing in OpenGL.

Ruslan
  • 18,162
  • 8
  • 67
  • 136
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
1

First you really should be looking at OpenGL 3+ using GLSL. This has been the standard for quite some time. Second, most Minecraft-esque implementations use mesh creation on the CPU side. This technique involves looking at all of the block positions and creating a vertex buffer object that renders the triangles of all of the exposed faces. The VBO is only generated when the voxels change and is persisted between frames. An ideal implementation would combine coplanar faces of the same texture into larger faces.