OGRECave / ogre-pagedgeometry

Paged Geometry is a component for rendering of dense vegetation
https://ogrecave.github.io/ogre-pagedgeometry/
21 stars 7 forks source link

Add optimized rendering for GL3+, D3D11 #15

Open cryham opened 9 months ago

cryham commented 9 months ago

I'm not being rude here, just speaking from experience, from its use in StuntRally at least. This is the single worst Ogre library to use in modern times. I'm sure before HW instancing it had it's uses, maybe in 2006-2010 or so. That's like ancient history today.

So, instead of making people think it's useful ("highly optimized"), I'd rather write plainly that this is an obsolete or outdated library. Ogre now has auto instancing and LOD, just place vegetation objects and it'd be way better than using this library now. Okay, there is grass paging here too, but modern ways of doing grass don't even have vertices, almost all can be done on GPU way more efficently. Paged geometry for vegetation does go though each vertex on CPU, one thread everytime when making pages, which even on new hardware makes significant delays (lags) while moving. It does not scale with HW at all.

paroj commented 9 months ago

no offense taken, but for reference, you are not quite qualified to judge what paged geometry (PG) is doing ;)

You run an outdated copy with custom shaders in stuntrally. I tried to forward port some fixes, but it is currently impossible to say whether all the necessary bits are there to judge performance of PG with stuntrally.

Addressing some of your points more specifically: PG implements automatic imposter generation for LOD, LOD fading, a wind effect and paging for geometry. All of the above features are still relevant with todays hardware and are more efficient than instancing with mesh based LOD. See also: https://ogrecave.github.io/ogre/api/latest/_instancing.html#Static-Geometry-vs-Instancing So to say PG, is static geometry on steroids.

Where PG falls short is efficient rendering on modern APIs. It is not terrible, but one can do better nowadays, if we do away with D3D9. Note that this does not regard instancing, but rather vertex fetch: https://www.yosoygames.com.ar/wp/2018/03/vertex-formats-part-2-fetch-vs-pull/ Writing fetch shaders is now much easier thanks to c32e33393206d7eea4a275ec4b5583c2a491633b.

The CPU work can also be moved to (multiple) background threads rather trivially, if this is a bottleneck. However, I rather suspect that the stuttering on paging is caused by non write-combined buffer updates (something missed in 95194bc024188ad08d4b85fb3b7141334cf041f7)

But adding this features requires coding and not so much complaining. Thus changing the title of the issue ;)

cryham commented 9 months ago

Allright my bad, I did indeed miss all the new commits here since 2015 and was talking about SR old version there. Still, if PG is processing each vertex of each mesh for page on CPU in 1 thread (is it still so? when creating pages), then this just adds horrible delays (for me) and not the desired effect of speeding vegetation up. Doing anything on CPU instead of moving everything possible to GPU is slower, right? Same as for grass and terrain.

Anyway I have really good smooth demo with plenty of vegetation using just Ogre-Next auto instancing, it does one draw call per one vegetation model with LODs (all visible). Are you saying that using PG would do better results, e.g. more vegetation with no delays when moving? Of course it's difficult to compare due to different engine, shadows, other shaders etc. Since the demo does not have impostors and allows plenty of vegetation, I agree with Matias saying that I can do it witout impostors. And I've seen somewhere (UE IIRC) similar approaches to drop impostors. They seem to bring more trouble than benefits: always look different, pop out, add own implementation.

paroj commented 8 months ago

Still, if PG is processing each vertex of each mesh for page on CPU in 1 thread (is it still so? when creating pages)

can you link the source code you are referring to? Doing this once per page is not bad (can be backgrounded, parallelized). Doing it each time the page is paged-in is not good.

Doing anything on CPU instead of moving everything possible to GPU is slower, right?

no. there is a cost of moving stuff to the GPU, so for small problems CPU is faster.

Are you saying that using PG would do better results, e.g. more vegetation with no delays when moving?

probably not with the current PG shaders, but when using optimized shaders then yes. Or rather, it depends on your definition of "better results". It would be definitely faster as fewer computations would need to be performed. But if your scene is not bottlenecked by VRAM or vertex shader performance then you probably would not notice any improvements by paging and imposters.

Or to put it in other terms: the ideas in PG did not got old, but the scene size where one needs to think about them drastically increased. Maybe you can simply resolve your paging hiccups by disabling paging as stuff fits in your VRAM anyway?

Also, PG offers many non performance related functions that not everybody is comfortable implementing from scratch on top of ogre-next.

And I've seen somewhere (UE IIRC) similar approaches to drop impostors.

probably not UE: https://github.com/ictusbrucks/ImpostorBaker

cryham commented 8 months ago

Right, yeah current PC HW got much better so all vegetation can fit and be rendered. I think though I could still use impostors for thousands of far trees on horizon terrain. Will try just meshes someday, maybe it's not needed.

Code is in here IIRC: void WindBatchedGeometry::WindSubBatch::build(), start, goes for each mesh and inside for each vertex.

Just for info anyway, IDK if this improved. And IDC about PG at all, since I moved to Ogre-Next and I'm doing just fine without it. And I'm really glad I can forget about all its issues and requirements and fixes I needed to do in 2010 to get it "working", like:

It was in UE5: video, impostors looked bad, IDK the details but he says it's now geometry not billboards in distance. That ImpostorBaker is 5 years old.

paroj commented 8 months ago

Code is in here IIRC: void WindBatchedGeometry::WindSubBatch::build(), start, goes for each mesh and inside for each vertex.

ah.. this is the batch building. It only happens once per scene and is not critical at all. Any stuttering during runtime can be alleviated by pre-loading. However, this part particularly would benefit by using HW instancing.