I'm trying to generate thousands of identical text nodes. It doesn't work

Hello all,



I’m trying to begin working on a game I’ve had in my head for a while now. Basically, it would involve moving around in a world of “numbers” that would vary between 1 and 9. Essentially, it would look something like this, but would have effects and varying opacities added later to give a better sense of a depth (and less headaches).



My problem is that I would need this world to be huge, and at the moment I am unable to generate even a 40x40x40 sized cube without the FPS dropping to almost unbearable levels.



At the moment, I am simply generating bitmaptexts to do what I want. Is there a better way? Someone in IRC suggested a particle system, but I need to be able to control individual particles so that I can change their values depending on events in the game.



Any help would be greatly appreciated. I attempted this a few months ago with another library and got frustrated; I’d love it if I could get past this stage this time.

videocards can handle millions of polygons, but not millions of objects. You need to use the GeometryBatchFactory on your nodes to group them



Just like minecraft-style voxel games, they do not and cannot render each box separately. They are grouped together as one mesh.

read this first https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:intermediate:optimization



then you can have a look at GeometryBatchFactory

Or even into the BatchNode if you don’t mind working with a WIP.

@Sploreg said:
videocards can handle millions of polygons, but not millions of objects. You need to use the GeometryBatchFactory on your nodes to group them

Just like minecraft-style voxel games, they do not and cannot render each box separately. They are grouped together as one mesh.


@nehon said:
read this first https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:intermediate:optimization

then you can have a look at GeometryBatchFactory
Or even into the BatchNode if you don't mind working with a WIP.


While that sounds good in theory, according to the page linked, it won't work well for information that needs to change frequently (which mine would):

Using GeometryBatchFactory merges individual Geometries into a single mesh. Thereby it becomes hard to apply specific Materials or to remove a single Geometry. Therefore it should be used for static Geometry only that does not require frequent changes or individual materials/texturing.


Is there a way around this? Other options?

Heh… I was about to mention @nehon 's BatchNode class then saw that he did already. I’ve been playing around with it in another WIP. It is VERY cool indeed. Solved a mess of problems for me.



EDIT: This would be the work-around your looking for.

@t0neg0d said:
Heh... I was about to mention @nehon 's BatchNode class then saw that he did already. I've been playing around with it in another WIP. It is VERY cool indeed. Solved a mess of problems for me.

EDIT: This would be the work-around your looking for.


Thanks. Do you or @nehon happen to have any example code using BatchNode? I've tried googling around to no avail. I'm quite new to jMonkeyEngine.

How about using the in-site search and our wiki?

@normen said:
How about using the in-site search and our wiki?


I appreciate your work on the project, so I won't be a dick.

I did search; I'll just try experimenting with it.

Try the javadoc first, its also installed in the SDK: http://hub.jmonkeyengine.org/javadoc/com/jme3/scene/BatchNode.html And the advice was serious. Google will give you some information, our site will give you the information we assembled for people wanting to learn about jme3.

@normen said:
Try the javadoc first, its also installed in the SDK: http://hub.jmonkeyengine.org/javadoc/com/jme3/scene/BatchNode.html And the advice was serious. Google will give you *some* information, our site will give you the information we assembled for people wanting to learn about jme3.


I might write up a little tutorial for it once I get finished. The information I found was pretty sparse, though the javadoc was helpful. I have successfully generated thousands of cubes with great performance :)

Thanks for the help everyone. I will probably keep posting new information here for future searchers.

Well, the good news is I have managed to generate 50x50x50 cubes with seemingly no degredation in performance. My only issue now is the memory footprint is nearly 3 GB for something like this. Here’s a sample of the code I’m using:



[java]@Override

public void simpleInitApp() {

Logger.getLogger("").setLevel(Level.SEVERE);



bnode = new BatchNode();

rootNode.attachChild(bnode);

initKeys(); // load my custom keybinding



Material mat_stl = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

Texture tex_ml = assetManager.loadTexture(“Interface/Logo/Monkey.jpg”);

mat_stl.setTexture(“ColorMap”, tex_ml);

bnode.setMaterial(mat_stl);

generateCube(50);

bnode.batch();



}



private void generateCube(int size) {



for (int x=0; x < size; x++) {

for (int y=0; y < size; y++) {

for (int z=0; z < size; z++) {

Box b = new Box(0.1f, 0.1f, 0.1f);

Geometry cube = new Geometry(“My Textured Box”, b);

cube.setLocalTranslation((float) x, (float) y, (float) z);

bnode.attachChild(cube);

}

}

}

}[/java]



My goal now is to determine how I can lower this memory footprint, as well as remove nodes on the fly and add nodes to other batchnodes.

@anirak Depending on the actual final mesh shape you need, (in this case, I’m assume a cube) I believe that most of the people working on minecraft type (boxel I think its called) games are generating only the faces of the cube that are needed (visible to the client) either by define a custom mesh using vertex buffers or possibly just quads?



This is a complete guess on my part as to how they are actually doing this for large landscapes, but I am sure they are not using the Box primitive and for the same reason you mentioned above. Doing a search in the forum area on either boxel? voxel? minecraft maybe? should yield a TON of threads on this and how to go about doing it.



Oh… and if you do find some useful info… please let me know. I’m very interested in seeing different peoples uses of batching meshes. I used nehon’s work as a final solution for a weather particle system… which originally was going to be a post processing filter without using geometries at all. Buuuut… I never got around to figuring out anything past drawing the deformation vectors for perspective rendering images. It was more than likely a useless effort that would have been far more expensive than just using geometry batching to begin with. lol But, was fun to try /shrug

@anirak, yeah the memory issue is known, that’s part of the Wip.

Right now the underlying geometries mesh are kept in memory.

I plan to add a way to flush them.



However 3gb seems high for a scene of that size…

How is your memory without batching?

Box b = new Box(0.1f, 0.1f, 0.1f);



dont reate one for every box, share them for all, that saves 50x50x50*8Vertices → resulting in quite some change i guess

@EmpirePheonix - I won’t be able to change the local translation if I do this though, will I?

@EmpirePheonix , @nehon



Thanks to your suggestion EmpirePheonix, I solved the memory problem (or at least brought it much lower). Essentially it was exactly what you said: I simply moved the generation of the box outside of the triple loop.



At the moment, my bottleneck seems to be back to a graphical one. Going up to a 80x80x80 cube now causes my FPS to begin dropping. I’m glad I’m getting a larger and larger area, however :slight_smile:

Well yeah, you could now do the following :



chunks, (there is a real reason to use them)

→ only part of the geometry needs to be regenerated

→ the chunks behind you can be frustrum culled, reducing rendering costs, if your world is kinda like minecraft infinite, that saves up to 3/4 (assuming 90degree fov) on rendering costs in average

Yeah you’d better do some kind of partitioning at this level, let’s say, batches of 10x10x10 or 20x20x20.

This way you have not that much objects on screen,and the batches off screen will be culled.

So I’ve tried creating some chunking, and the culling does seem to be working (according to the bottom left information section, which shows a reduced number of triangles and vertexes being rendered). Still, despite being culled, performance doesn’t go up any…

Striking a balance between chunking and batching is tricky and largely depends on your data.



Still, at some point you will hit limits that just can’t be surmounted.