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)

tree_trunk_fix.diff (5.8 KB ) - added by wraitii 9 years ago.
noShadowFromSmallObjects.diff (800 bytes ) - added by wraitii 9 years ago.
onematerial.patch (1.1 KB ) - added by wraitii 9 years ago.
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.
Instancing_v1b.patch (10.8 KB ) - added by wraitii 9 years ago.
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
Trees_demo.xml (2.5 KB ) - added by wraitii 9 years ago.
Tree sandbox to test instancing. Should run much faster than without the patch.

Download all attachments as: .zip

Change History (15)

comment:1 by wraitii, 9 years ago

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.

by wraitii, 9 years ago

Attachment: tree_trunk_fix.diff added

by wraitii, 9 years ago

comment:2 by Stan, 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 historic_bruno, 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 wraitii, 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 Stan, 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 wraitii, 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 wraitii, 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 wraitii, 9 years ago

Attachment: Trees_demo.xml added

Tree sandbox to test instancing. Should run much faster than without the patch.

comment:6 by wraitii, 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 wraitii, 9 years ago

I have setup a git branch for this work and will try to occasionally pump out SVN patches.

https://github.com/wraitii/0ad/tree/Instancing

comment:8 by leper, 9 years ago

Is anything here actually requiring a review?

comment:9 by Itms, 9 years ago

Keywords: review removed
Milestone: Alpha 19Alpha 20

comment:10 by elexis, 8 years ago

Milestone: Alpha 20Backlog

Backlogging due to lack of progress.

Note: See TracTickets for help on using tickets.