Help Slow Rendering

Hi!, I am a new in JME3 and I have some troubles with rendering.

The code is simple, and I am trying to practise after reading the wiki, I tried to find online, but I didn’t find something useful. I am making a 100 x 10 x 100 terrain using Box geometry with size 0.5, the creation and the texture works perfect, but I have really slow FPS, and I know that JME3 has Dynamic Culling, but for some reason that I haven’t managed to solve, the app still render the 100000! Geomtry, here’s a pic:

But when I look away (Or just look few blocks), I get back that 60 fps (I am using VSYNC). Here it’s the code, please feel free to correct me and if I am making anything wrong I am open to critics. Thank you!

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.texture.Texture;

public class LaunchGame extends SimpleApplication{
	
	Box cube;
	Material cubeMat;
	Texture cubeText;

	@Override
	public void simpleInitApp(){
		this.flyCam.setMoveSpeed(10);
		createCube();
		createWorld(100, 10, 100);
	}

	public void createCube(){
		cube = new Box(0.5f, 0.5f, 0.5f);
		cubeMat = new Material(this.assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
		cubeText = assetManager.loadTexture("Textures/cube_g.png");
		cubeText.setMagFilter(Texture.MagFilter.Nearest);
		cubeMat.setTexture("ColorMap", cubeText);
	}

	public void addCube(float X, float Y, float Z){
		Geometry geom = new Geometry("cube", cube);
		geom.setMaterial(cubeMat);
		geom.setLocalTranslation(X, Y, Z);
		rootNode.attachChild(geom);
	}
	
	public void createWorld(int xSize, int ySize, int zSize){
		for(int X = 0; X < xSize; X++){
			for(int Y = 0; Y < ySize; Y++){
				for(int Z = 0; Z < zSize; Z++){
					addCube(X, Y, Z);
				}
			}
		}
	}

	public static void main(String[] args){ new LaunchGame().start(); }
}

While this code might seem like an easy and obvious way to create a block-based voxel world, creating a unique box for each block/voxel is actually extremely taxing on the GPU - one of the primary bottlenecks for GPU performance is the total geometry count - so 10k verts split between 10k geometries will run extremely slower than a single geometry with 10k verts.

So the solution in your case would be to use a voxel engine that handles batching many blocks/voxels into a single geometry everytime a block is added or removed, and that will give the player the illusion that each block is unique. So Minecraft, for example, uses a single irregular geometry for each chunk, even though a chunk can consist of atleast 64x64x256 blocks.

I am no expert on voxel based games, but I know there’s a few voxel libraries for JME that you could find with a quick search, and hopefully other users on these forums can also help to recommend the best one for your use case.
(however this is the most commonly used and up to date one, to my knowledge: Blocks)

3 Likes

While this code might seem like an easy and obvious way to create a block-based voxel world, creating a unique box for each block/voxel is actually extremely taxing on the GPU - one of the primary bottlenecks for GPU performance is the total geometry count - so 10k verts split between 10k geometries will run extremely slower than a single geometry with 10k verts.

Thank you!, I didn’t think in that way, that helped me a lot :smiley: . Yes, I saw some voxel engines, but I didn’t think in using them yet because I dont want to overpopulate the maven pom dependencies. But I will investigate it!! Ty so much for the help.

2 Likes

Also, block worlds are not made of blocks. They are made of batches of visible faces.

Be careful not to fall into the “block worlds look simple so they must be simple” trap. It’s the deep end of the pool and one of the hardest places to start. Literally everything you do will be a little harder or a lot harder… or take some mesh expertise at a relatively low level (unless you use someone else’s library… then you have a different learning curve to climb).

Versus any game where you can model levels/assets in Blender, load them up, add them to physics and go. They look “higher fidelity” but are 1000x easier to make.

2 Likes

Thanks for the advice!

@Grubsic
also its not just about:

  • “voxel worlds are not made of blocks”
  • “voxels show only visible(surface) faces”

its also about optimizations like:

  • “greedy meshing”
  • “LOD scaling”
  • light optimizations (floodfill light)

for example you can see here gredy meshing part:

Like mentioned there are many libs, i would suggest you try Blocks lib:

1 Like

The greedy mesh looks awesome, gonna try the engine too, thanks!.

Though note that there are 100 things to get right aside from greedy meshing. For example, none of my block world stuff uses greedy meshing. Not even Mythruna.

You can get pretty far without worrying about it. Or just use someone’s library that already has it.

1 Like