Good Morning jMonkeys,
[edit] I’m sorry, i see this post is too long so here is the questions only:
- I see a continously increasing amount of direct memory usage, since i create new geometries for all chunks each time they are loaded i guess its related to that, so how do i delete old meshes buffers?
- how do i use the LOD level stuff in jme? i know the buffer types from the meshes site in the wiki and the setLODLevels(VertexBuffer[] lod) method of the mesh but i dont get how to set the dufferent buffers when the section listing all buffers only mentions one buffer for vertices, indices etc?
- is it woth it switching from a 3d-array to a 1d-array memory overhead-wise?[/edit]
I’m working on some VoxelEngine stuff for a while now, I basically started with a simple cube, implemented chunks as groups of blocks, added some sort of culling-meshing to only display the faces that are visible and since I didn’t really get how LODs work in jME I came up with my own way of LODs meaning I create completly indepentant geometries for each LOD per chunk, while the node that holds the chunk’s geometries keeps attaching and detaching the required LOD-geometries dependant on the distance to the camera. So far so good (not actually good but meh).
Now there is a bunch of questions coming into my mind about further improvements (I know there is always discussions about weather to improve at that point or first improve once you feel like you got low FPS but since I’m programming on a somewhat mediocre notebook and I actually want to play my own game with rather solid FPS and i just started with some basic AI and stuff that’s not actually gonna speed up the game but make it more heavyweight instead, i need some buffer in terms of processing power that I could make use of).
So back to what I currently have:
- chunkwise: although I might still play with it, I currently got a chunksize of 32x256x32, the data is stored in a 3d-array that’s put into a buffer once the chunk is unloaded and as soon as another chunk needs to be loaded it does not create a new 32x256x32 array but takes one from the buffer, zeroes it out and loads in the data needed for that chunk.
- meshingwise: I got greedy meshing and marching cubes working (except for the texturecoords), since I’m not yet 100% sure which one to use in my game, whenever a chunks data was loaded it’s given to the mesher that creates a new geometry for that chunk (currently one geometry per blocktype per chunk (and also per LOD but more about LOD problems later) and replaces the old geometries of that chunk with the freshly created ones. The List(Vector3f), List(Vector2f) and List(Integer) needed during meshing for the vertices, texturecoords and indices respectively are array lists that just like the chunks arrays are put in a buffer, same is true even for the Vector3fs and Vector2fs (all that buffering together resulted is some really decent meshing boost).
- an additional ChunkHolderAppState (name might be misleading, it does not actually hold any chunks it just checks which chunks should be loaded/unloaded, depending on an given array of positions of characters (multiplayer), ensures chunks that would be loaded by more than one character are only loaded once, makes sure chunks that are closer to characters are loaded first (doesn’t actually load them itself but tells the WorldData instance to do so in the given order) and such
- bunch of more stuff that’s not important for now
Now onto my first question:
When I switched from my culling-meshing to the greedy meshing, as I mentioned, I continued to produce one geometry per blocktype per chunk instead of meshing it all together and using a texture atlas (which as far as I know would mean I have to write my own shader to check which pixel to give what color since the built-in ones only support repeating textures or “cutting” the textures as used in a texture atlas but not a combination of both, i might be wrong here though but I just cant imagine how to tell it that information or how it would make use of it since there is more information needed than 2 floats for texturecoords per vertex when I want repeating textures from a texture atlas I guess). But when I was hinted towards the TextureAtlas class that can batch stuff together, create a texture atlas from the textures used, and probably update the texture coords of the vertices regarded I thought that might just be what I need but I realized using TextureAtlas.makeBatch on my chunks nodes results in as many materials as chunks are loaded (yeah was actually obvious), meaning in case of voxel related stuff it’s no improvement at all when using it for the chunks. Then I found out about texture arrays and I also considered to make use of mipmapping, so performance wise (since I guess after minecraft basically everyone wanted to make his/her own voxel related game, meaning people have experience regarding which techniques work good or bad and I don’t want to reinvent the wheel) I was wondering is it better to go for a textureatlas of mipmapped textures or for a texture array of mipmapped textures and can I still mesh all different types of blocks together when using a texture array and get data from that array of textures in the shader? (I guess I should be able to but I don’t really see the difference between texture array and texture atlas then since the texture atlas data internally should be stored in an array too?)
And the second question:
As I mentioned I currently create independant geometries per LOD (and currently still per blocktype), I thought about instead of creating independant geometries, i can just add the list of vertices fpr the different LOD to the list of vertices from the fully detailed geometry and then just change the list of indices dependant on the distance to the camera to use the vertices from the corresponding LOD.
https://wiki.jmonkeyengine.org/jme3/advanced/mesh.html told me about the different types of buffers and also mentions the setLodLevels(VertexBuffer[] lodLevels) but in the list of buffers I dont see several buffers for several LODs for the vertices or indices, and since my LOD generator might need vertices at positions where there are no vertices in the fully detailed version I’m wondering if I can actually use the built in LOD thing or not.
And somewhat regarding the same topic: since I currently only create new geometries when chunks are loaded and a once loaded chunk’s geometry stays visible even if the chunks data is unloaded (it switches LODs but first updates once you get into chunk-load-distance again; you can imagine it a little like age of empires in terms of whats invisible on the one hand, visible on the other hand and whats visible, showing enemies and getting continuously updated on the last hand) when moving on I’m facing an always increasing amount of direct memory usage, so I was wondering how can I modify the buffers of the already generated meshes instead of creating new meshes? (and shouldn’t actually the buffers of old geometries meshes that are not attached to the scenegraph anymore, since they were replaced by a later loaded version of that chunk, be deleted, if not, how to delete them manually?)
And one last thing I’m wondering, though it’s not actually jMonkeyEngine related:
Currently using a 3d-array in my chunks for the data instead of a 1d-array, would that result in 8704 bytes overhead more per chunk meaning for a chunk-load-distance of 16 chunks (= 805 chunks loaded) that would only be a difference of 6.68 mB for all loaded chunks, but also be more efficient in terms of time it takes to access the data or am I wrong on that?
In case I break a rule by asking that non-jMonkeyEngine related 3rd question I can sure just remove it but since it belongs to the topic of improvement here I though I might quickly throw it in to make sure i got that right.
I know it’s quite a long post, so if you made it all the way down to here thanks a lot for that already and thanks a lot in advance for every hint, idea or thought related to the topic, that you might leave here
Greetings from the shire, Samwise
[edit] changed the generics stuff in the lists I mention for the meshing to be put into parenthesis instead of tags because that tag stuff screwed it all up [/edit]
[edit2] put the questions summed up at the top so the rest is only needed in case there is questions about my questions lol[/edit2]