Advertisement

is there a better way top refer to assets in a game?

Started by November 15, 2014 12:41 AM
32 comments, last by Norman Barrows 9 years, 9 months ago


Yes using a string to refer assets is slower than integer. But it will not be "noticeably" slower. Unless you are referring it ten thousand times each frame, and that means your design is probably wrong.

a typical "busy" scene is 16,000+ non-instanced draw calls, each of which requires a mesh and texture. there are currently 321 meshes and 386 textures to search though. so doing an on-the-fly string to mesh or texture array index lookup would be rather time consuming. easy to code, good on read-ability and write-ability, easily human editable, but runs slow.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php


Since you are doing this on a PC, time and space spent on this simply do not matter. I would say you should not waste too much time on this, it would probably give you a 0.01% performance gain with a super fast resource id;

this is not about performance. right now i hard code array indices - nothing runs faster.

this is about making the code more readable and writeable, without major performance hits or doing a lot of work just to get the convenience of being able to code something like: playwav(teratornis_attack), instead of looking up that teratornis_attack.wav = wav index 193, and then coding playwav(193).

a combo of data driven, enums for frequently coded assets, and paper and pencil lists of non-data driven assets and their indexes might be the best that can be hoped for.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Advertisement


In every modern engine I've worked with, yeah. The primary motivation is to eliminate the engineer from the content iteration loop, since engineering resources are costly and slow. And in the case of updating asset references, greatly misused.

in my case, i'm a lone wolf. so the engineer IS the content creator, and therefore can't be eliminated from the content creation loop. being a content creator with full knowledge of and access to the source code and compiler tools, about all data driven does is save me a few re-compiles.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php


Good grief, who is modelling all these? Surely you mean 160 -- not 16,000?

16,000 non-instanced draw calls of one mesh and one texture each, drawn from a mesh pool of 321 meshes and a texture pool of 386 textures.

this screenshot was just under 15,000 calls:

http://www.gamedev.net/gallery/image/4895-lots-of-batch-calls/

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

To avoid having to do the string->index conversion every time, whatever code has the string can just do the lookup once and then store the result.


this screenshot was just under 15,000 calls:

http://www.gamedev.net/gallery/image/4895-lots-of-batch-calls/

That is a ton of draw calls for what I see. Are you planning to do any culling and/or instancing?


That is a ton of draw calls for what I see. Are you planning to do any culling and/or instancing?

that's fully culled, except for occlusion culling. all 14,000+ meshes are visible, except the few which are entirely occluded by the rolling terrain or intervening vegetation. by using terrain chunks which are pre-sorted render lists, all i have to do is a quick frustum cull on meshes in the visible chunks. frame rates are fast enough that no performance slowdowns occur, so i don't have to resort to instancing. OTOH, i "cheat" and frame rate limit the game to 15fps, which is as slow as you can run with acceptably smooth animation and input responsiveness. i do this to get 66ms per frame processing time for render, input, and update. it allows me to shoehorn more game onto a given PC.

in a future version, i may go to instancing in order to increase the number of entities i can draw at once. but i'm already using rigid body entities as opposed to skinned meshes, and can get about 125 entities onscreen at once (in a non-complex terrain scene) without slowdowns. i was originally shooting for 150-200 in a complex terrain scene. given that i'm stili working with fixed function dx9.0c, i find the results acceptable for the moment. 200 onscreen in complex terrain with instancing is about the only thing right now that would force me to move to a more advanced version of dx. and even then, there is a kludgey form of instancing possible on dx9.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Advertisement


Good grief, who is modelling all these? Surely you mean 160 -- not 16,000?

16k draw calls [...] 321 meshes and 386 textures.

Ah OK, that is much more like it.


[screenshot]

That is a ton of draw calls for what I see. Are you planning to do any culling and/or instancing?

Yes indeed. This looks like approx. 13,900 of the 14,000 drawn meshes are grass and shrubs.

You should really consider array textures, instancing, and indirect draw calls if there is any possibility. Since a really old graphics card probably won't be able to handle that amount of overdraw anyway, you should have it available on your target hardware.

Array textures alone can probably reduce the number of state changes to like 5-10% of what it is now. Assuming the minimum guaranteed supported number of layers (256), you would need a maximum two array textures, assuming that you reference each and every texture that exists in your pool (which likely won't be the case!).

Even without indirect draws and not using instancing, you could batch draw calls together considerably, just not as efficiently. In the easiest case, you could write 100 or 200 of those shrubs into a dynamic vertex (well, ... index) buffer object at a time, and use primitive restart to separate them. That's pretty poor performance-wise but probably still much faster than doing thousands of draw calls for thousands of 20-vertex meshes.

Of course, using instancing for something that totally begs for instancing would be preferrable (same for indirect calls). Really, this is what instancing was made for.


Yes indeed. This looks like approx. 13,900 of the 14,000 drawn meshes are grass and shrubs.

two tree trunk meshes, two tree top meshes, 4 plant meshes, maybe 12 interleaved ground meshes, two tree trunk textures, two tree branch textures, 4 plant textures, and 4 ground textures.

in the scene visual range is 500 i think. there and 1300 trees per 800x800 area. and a plant every 5 units. ground meshes are 300x300, with 4 interleaved meshes of one texture each per 300x300 area.

each 300x300 terrain chunk is pre-sorted by texture then mesh, and there are perhaps 4 chunks visible. so there are only redundant mesh and texture changes between chunks. and i may be running it through the render list first, don't recall offhand, don't think i did that yet, which would eliminate those few extra state changes.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php


You should really consider array textures, instancing, and indirect draw calls if there is any possibility. Since a really old graphics card probably won't be able to handle that amount of overdraw anyway, you should have it available on your target hardware.

i'm developing on a low end PC similar to the minimum system requirements for the game. that screenshot was from a 2011 compaq model CQ-2014. AMD E-300 APU w/ radeon HD graphics chip on the motherboard. 1300 Mhz, 2 cores , 2 logical processors. runs windows 7. its basically a laptop motherboard in a mini tower case. IE a "baseline box" as i call them. go into any PC store or online and buy the most basic PC they have - and don't get a graphics card for it! <g>.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php


Of course, using instancing for something that totally begs for instancing would be preferrable (same for indirect calls). Really, this is what instancing was made for.

well, i'm still using dx9 fixed function, so going to dx 10 or better for real instancing would be non-trivial. i would need a set of shaders to replicate the basic dx9 fixed function capabilities (alpha test, alpha blend, simple 2 stage texture blend).

at the moment, i still have enough unused processing power to implement distant LOD backgrounds, smoke particle systems etc.

and the next step after that would be stepping up to skinned meshes vs rigid body animation. but i don't think even dx11 and the latest card could do it: 125 characters onscreen at once without slowdowns at 15fps. that would be 62 characters at once at 30 fps, or 31 skinned mesh characters onscreen at once at 60fps. games can't really do this yet can they? total war draws a lots of characters, but they're not high resolution, like a character in a typical shooter.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

This topic is closed to new replies.

Advertisement