-
Notifications
You must be signed in to change notification settings - Fork 933
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Grass instancing #3023
Grass instancing #3023
Conversation
On my device grass paging wins by a big margin: Grass instancing: My groundcover settings: OP and AG are on, cell view distance is 1.18, and OP merge factor is 450 |
Interesting that while Draw was significantly reduced, went down a small bit when it was expected to go up. Culling also was slightly reduced. |
Did something change? Something changed with the config files detection. |
Actually, the behaviour is expected - if you have small amount of large drawables, CPU spends much less time to handle them than large amount of small drawables. From the other hand, GPU loading increases a bit with large chunks since culling becomes less efficient and GPU renders some object instances outside of view frustrum. |
My latest commit just changed groundcover chunks size, it did not touch configs. Propbably there are some upstream changes that may cause the issue. Also you can try to build a previous commit from this branch and check if the issue is resolved. |
Added a configurable chunk size (0.5 cell = 4096x4096 by default). Such setting causes graphics artifacts (depth order when rotation camera) with object paging, and I did not manage to fix it, so this setting is instancing-only. The main issue left is 3 - I'd appreciate any help to figure out why refractions cause performance drop with instancing, but not with paging. Can it be that refraction camera works with "real" coordinates, not with ones which I set in shader, so refraction tries to handle all groundcover objects? |
487c9f5
to
3ed62e5
Compare
I managed to drop invisible instances (which are behind of fading distance) via vertex shader. On my setup it allows to save about 35% of time which GPU spends to handle such instances. Since it is about 20% of the time for the whole groundcover to handle invisible instances, it is about 6% of total speed to handle groundcover on GPU on my setup, and a couple of additional FPS. Note that it is harder to use the same trick with paging since I need to collect instances coordinates and send them to GPU first, what is not really good. |
Could you do a rebase? AO3 fixed the issue with config files. |
a550897
to
4b4c3ff
Compare
Done. |
4b4c3ff
to
b44f82d
Compare
I hope that we are done with crashes now. |
With latest changes, cell transition with grass instancing is even snappier than grass paging (and before), seems like still shots with lots of grass has more stable FPS than before and increased by 8-15, for me FPS is still more consistent and better with grass paging. Now what to do with "Cell reference 'unknown_grass' not found!" message spam in the log? I'm using Remiro's grass for OpenMW |
If i remembered correctly, it is a bug in the mod itself (it contains a lot of garbage records). I doubt that we should "fix" it on the engine side. |
To your points:
|
I made an additional investigation about instancing performance. Different sources state that paging is generally faster than instancing with low-poly meshes (as Morrowind ones), while instancing should be faster with complex meshes instead (several thousands of triangles per shape) and\or with dozends of thousands of the same mesh instances - you need to load a lot of redundant data with paging in such case. |
I'd not disable groundcover in refraction because there are mods which add an underground flora. |
4b35126
to
4062034
Compare
While playtesting Lyithdonea: Azurial Isles with grass enabled, this happened: |
Looks similar to this issue (a comberry mesh from modern Graphics Herbalism was affected). I suspect that the mod uses an esoteric texture format, which OSG (at least, your binary) does not support properly. Can you try to enable your groundcover mod as a common one ("content" instead of "groundcover") and check if the issue persists? |
Does instanced groundcover now cast shadows? |
Can you attach an affected mesh and texture? |
19b715d
to
0dafb7e
Compare
cf74f13
to
16bb561
Compare
According to feedback, an approach with IsGroundcover flag for statics does not work in cases when groundcover mod contains only instances of groundcover statics, while statics definitions are from another ESM. SHOTN uses this approach (grass itself is defined in Tamriel_Data.esm, while its instances is in the Sky_Main_Grass.esp). I see two ways to avoid this issue:
I try to use second approach for now. A main idea is that I load all groundcover plugins after common ones, so I know an index of first loaded groundcover mod during game start. Since I know this index, I can save it and then compare it with content file index of every ESM::CellRef to determine if this object instance comes from groundcover file. I also tried to use flag in the ESM reader, but without success - some parts of the engine work with ESM files directly. |
0b5c8d7
to
c3cf513
Compare
c3cf513
to
be652e2
Compare
Note that I do not like additional optional arguments in |
be2b5db
to
5225ec9
Compare
on the android version of OpenMW, when the grass instancing function is enabled, the GPU is loaded by 100% and the fps drops to 12-15. At the same time, the CPU is almost idle and the load does not exceed 20%. When grass instancing is turned off, the FPS stays stably around 30-40 in the busiest places. The GPU load does not exceed 80% and the game runs smoothly. Is it possible to redistribute threads for a uniform load between the CPU and GPU when this function is enabled? |
GL4ES doesn't actually use the GPU's support for instancing even when it's available and instead fakes it CPU-side. It's not an OpenMW problem. If the graphics driver tells us it supports instancing, it's supposed to mean that it can do it quickly. |
I cannot say what exactly is to blame for the drop in FPS performance when the grass instancing function is enabled, since I do not understand this. But I see a significant difference both in benchmarks and in personal feelings when disabling grass instancing in OpenMW settings. in the first screenshot grass instancing is enabled, in the second it is disabled. The monitoring data can be seen in the screenshot in the center. |
Judging by the first screenshot from the last post, you just enabled groundcover mod as a common one. Are you sure that you uploaded correct screenshots? |
An alternative to #3010. Opened to have build artefacts to test the feature and compare performance with paging PR.
Existing settings:
A main idea - instead of merging grass instances to large shapes draw the same shape many times without uploading the same data every time. Since all instances of the same shape use the same transformations, we need to move, scale and rotate every instance via vertex shader. It allows to decrease CPU and RAM usage compared to paging, but causes higher GPU usage due to additional calculations in shaders.
Note that roundcover objects can not cast shadows since shadows system is not aware of any transformantions in the vertex shader. Can be fixed in follow-up PR, but such shadows will cause a really large performance drop. Probably it would better to use port-processing shaders (e.g. SSAO) instead of real-time shadows for groundcover.
In my testing instancing is a bit slower than paging (it has higher GPU usage, but lower Draw and Cull, but my setup is GPU-limited). An advantage of instancing is that it uses less RAM (roughly near 100MB in my testing), also cell transitions are faster since OpenMW does not need to load a lot of instances and then merge them to batches.
This behaviour is fully expected since the main purpose of instancing is to reduce CPU usage at the cost of additional GPU overhead (more complex shaders and an overhead to bind per-vertex data).