Rendering Many Rectangles

Started by THEREDBARON24, August 23, 2016, 01:51:47

Previous topic - Next topic

THEREDBARON24

I am working on a simple terrain generation system that will render many small terrains in 3D space. I am having a little trouble optimizing the code however. Right now, I have 1600 terrains being rendered, and am getting around 450 fps. While this is good, it decreases quickly, well below 100 fps by the time I am rendering 10000 terrains. I render the terrains in batches. First I bind the model of a certain terrain, then for every model, I go through mapped textures, and bind the correct one for each batch. Finally, I draw each of the terrains with triangle strips since each terrain is a quad. Are there any other tips that I can use to further optimize the game? Let me know if I need to explain anything better.

Cornix

First of all you have to understand that FPS is a very poor tool to measure performance. At least the way you use it.
If the FPS drops from 100 to 99 it is not nearly as big a deal as when it drops from 10 to 9. Instead you should look at the average time you need to render one frame. For 40 FPS it is 20 ms, for 60 FPS it is 16 ms, for 100 FPS it is 10 ms 200 FPS is 5 ms, 400 FPS is 2.5 ms.
If you go from 400 to 200 you only lost 2.5 ms but you lost 200 FPS. If you go from 60 to 40 you only lost 20 FPS but 4 ms. That is a much more severe loss.


Back to your question about optimization: The general rule of thumb is to have as few state changes as possible. Render as many triangles with the same draw call as you can without changing shaders / textures / buffers / etc. You could also try to find a simple way of culling triangles which should not be visible on screen. But if this is too complicated then you will just move the problem from the GPU to the CPU which is usually not a good idea.
You could also try to optimize the shader if it is currently doing too much. I dont know how big of a difference this could make but if your shader does some crazy shit then it sure can help.

THEREDBARON24

Thanks for the tips! I really appreciate that. From what you are saying, I believe what I need to do is put as many triangles together in the same buffer. Currently, in each buffer (VBO), I am storing 4 floats for the vertices, and rendering with triangle strips to produce quads. This works, however, I am wondering, how do I put different quads together in the same vbo?
for example, the vbo could store: {0, 1, 2, 3, 4, 5, 6, 7}. What I would want is 2 quads rendered with the subsets {0, 1, 2, 3}, and {4, 5, 6, 7}, however, I am not sure how to attain that. I have been reading up on glPrimitiveRestartIndex, however, I am not quite sure how to implement it. I am drawing with glDrawArrays currently, however, from what I have read, I need to use glDrawElements. If someone could point me in the right direction, or even just give me a few tips, that would be fantastic. Thanks.

THEREDBARON24

Just curious if anyone has an answer for my last question

Kai

In order to render two quads beneath each other, you can still use the "triangle strip" primitive type. You don't need primitive restart. Just think about what the vertex positions would be to produce two quads.
Maybe this illustration helps:

(source: http://http.developer.nvidia.com/CgTutorial/elementLinks/fig1_4.jpg)