Opened 9 years ago
Last modified 8 years ago
#3073 new enhancement
[PATCH] Reduce the number of state changes/draw calls when rendering
Reported by: | wraitii | Owned by: | |
---|---|---|---|
Priority: | Should Have | Milestone: | Backlog |
Component: | Core engine | Keywords: | patch |
Cc: | Patch: |
Description
The pyrogenesis renderer isn't terribly slow, but it is not terribly quick either. One reason for this is that the game tends to perform many draw calls per frame, and we often have to change the state of the driver (binding new uniforms, binding textures, models… This is pretty bad overall, particularly as 0 A.D. models tend to be fairly low-poly by today's standards.
See http://stackoverflow.com/questions/4853856/why-are-draw-calls-expensive on why draw calls are bad.
To reduce the number of draw calls, several steps can/need to be taken: -reduce the number of objects we draw at anytime -use real instancing (available in OpenGL 3.2 and later) -fake instancing by grouping meshs together.
In parallel, we need to reduce/limit the number of state changes. To this end, the game "batches" models. That is, it sorts models by material, textures etc. so that we avoid sending new textures to the openGL driver all the time.
This means that to be efficient we need to: -reuse textures as much as possible -use the same models as much as possible -avoid having too many texture variations on models if possible
But the big thing is draw calls.
Attachments (5)
Change History (15)
comment:1 by , 9 years ago
by , 9 years ago
Attachment: | tree_trunk_fix.diff added |
---|
by , 9 years ago
Attachment: | noShadowFromSmallObjects.diff added |
---|
comment:2 by , 9 years ago
I ´m not sure removing props shadows is a good idea graphically wise. We tend to look for graphical quality so I think an option to enable disable them would be better than not having them at all.
I believe than when that parch gets commited Îll have to fix all the ROTE trees ? (Since you removed the material)
comment:3 by , 9 years ago
Keywords: | patch review added |
---|---|
Summary: | Reduce the number of state changes/draw calls when rendering → [PATCH] Reduce the number of state changes/draw calls when rendering |
comment:4 by , 9 years ago
stanislas: I didn't remove it, merely renamed it to be more coherent with what it actually did. But yes. Shouldn't be too difficult using a find replace though.
For the record, I've been doing some testing on instancing, and on a "perfect" test map, using batches of 250 trees, I get a real increase in FPS from circa 15/20 FPS to 60FPS (or more?)
comment:5 by , 9 years ago
Yup, was mainly a concern of compatibility :)
So we agree it should be an option ?
By batches of 250 trees you mean one mesh ?
by , 9 years ago
Attachment: | onematerial.patch added |
---|
Incompatible with the "tree trunk fix". Makes all objects in-game use only a diffuse texture, use the wind effect, and be opaque, for testing purposes.
by , 9 years ago
Attachment: | Instancing_v1b.patch added |
---|
Simple instancing patch. This will actually instance objects the game wants to instance. Requires GL_ARB_draw_instanced. Naive and probably buggy but it works with onematerial.patch
by , 9 years ago
Attachment: | Trees_demo.xml added |
---|
Tree sandbox to test instancing. Should run much faster than without the patch.
comment:6 by , 9 years ago
Stan: I'm certainly not against using it as an option but I guarantee you that with default settings it's impossible to notice. But that was just a suggestion.
And no, by "batches", I mean that the instanciation can take up to 250 meshes.
BTW the above patch might not work on all computers since you require GL_ARB_draw_instanced, and you need to support a certain number of uniforms. YOu cna chande the value in model_common.vs of instancingTransform to something lower than 250 to fix that.
comment:7 by , 9 years ago
I have setup a git branch for this work and will try to occasionally pump out SVN patches.
comment:9 by , 9 years ago
Keywords: | review removed |
---|---|
Milestone: | Alpha 19 → Alpha 20 |
Some quick data, which really shouldn't be used to draw conclusions but I'm going to anyway: On a map similar to Units Demo but empty except for 5000 trees of one type: Rendering 5000 Oak trees (which is 10k draw calls as the foliage is separate) is giving me 380,000 polys and 14 FPS Rendering 5000 Pine trees (which is 5k draw calls) gives me 445,000 polys and 24 FPS Rendering 5000 Tropical Palm Trees (5k draw calls) gives me 7,758,760 polys and 17 FPS and rendering 5000 cretan_date_palm_patch is 10k draw calls, 15,320,000 polys and 5 FPS
I'm running those tests on a GMA 3000 intel card which is going to affect results, but it goes to show that draw calls are pretty bad.
Furthermore I noticed that we rendered tree-trunks twice as if they were transparent which is useless, so I attached a patch for that (we're currently in Feature Freeze).
Finally I'm adding another patch to not render shadows from too small objects that wouldn't be seen, such as spears or units heads. This has an effect only where there are many units on screen, and then again it's fairly small, but it is there and it's an idea.