0
votes

Im trying to draw large gridblock using OpenGL (for example: 114x112x21 cells).

As far as I know ... each cell should be drawn as 6 faces (12 triangle), each contains 4 vertices. each of the vertices has position, normal, and color vectors (each of these is 3*sizeof(GLfloat)).

These values will be passed to VRam in VBO(s). I did some calculations for the example mentioned and found out that it will cost ~200MB to store this data. I'm not sure if this is right, but if it is, I think it's way too much VRAM for such 1 model.

I'm sure there are more efficient ways to do this. and if any can point me to the right direction I would be very thankful.

EDIT: I may have been unclear about the nature of the cells. they do NOT have uniform dimensions that can be scaled/translated to produce other cells or other faces on the same cell. Almost each cell has different dimensions on each face. (these are predefined)

Also let me note that the colors are per cell and are based on a algorithmic scale of different values (depending on which the user wants to visualize). so if the user chooses a value (one for each cell) to be visualized, colors are calculated based on a scale and used to color the cells.

As @BDL suggested in his answer, I'll probably use geometry shader to calculate per face normals.

3

3 Answers

1
votes

There are several things that can be done:

  • First of all, each vertex position (except the ones on the sides) are shared between 8 cells.
  • If you need per face normals, in which case a position would require several normals, calculate them in a geometry shader instead of storing them in the VBO.
  • If each cell has a constant color, store it in a 3d-texture and sample the texture in the fragment shader.

For more hints you would have to provide more details on the cells and on what you want to achieve.

1
votes

There are a few tricks you could do.

To start with, you could use instancing per cube. You then have per vertex positions and normals for a single cell plus a single position and color per cell.

You can actually eliminate the cell positions by deriving it from the instance id, by reversing the formula id = z * width * height + y * width + x.

Furthermore, using a float per component is probably overkill for your colors, you may want to use a smaller format such as GL_RGBA8.

Applying that to your example (268128 cells) we get a buffer size of approximately 1 MiB (of which the 4 bytes color per cell is the most significant, the others are only for a single cell).

Note that this assumes that you want a single color for your entire cell. If you want a color per vertex, or per vertex per face, you can do so by using an 1D texture and indexing by instance and vertex id.

The biggest part of your data is going to be color though, unless there is a constant pattern. If you still want floats per component en per face per vertex colors it is going to take ~73 MiB on color alone.

0
votes

You can use instanced rendering. It renders the same vertex data with the same shader multiple times in just 1 draw call. Here is a link to the wiki(external): https://en.wikipedia.org/wiki/Geometry_instancing