(OpenB3D) FPS drops with voxel-terrain

BlitzMax Forums/MiniB3D Module/(OpenB3D) FPS drops with voxel-terrain

icebeararmy(Posted 2016) [#1]
Hello :)

I tried making a simple voxel-terrain with 3 layers of 32x32 textured blocks. The blocks are created out of surfaces. I hide surfaces you don't see with "ClearSurface" (Is it possible to hide them without deleting them?). But somehow I get only about 16 FPS while looking at the terrain. When I don't look at it (when the blocks don't render?) I get about 56 FPS.
This is my code to create the terrain:
For x = 1 To 32
	For z = 1 To 32
		AddBlock(stone,x,3,z)
		AddBlock(stone,x,2,z)
		AddBlock(stone,x,1,z)
	Next
Next

This is the "AddBlock"-function:
For i =0 To 15
	If x>EntityX(Chunk(i)) And x<EntityX(Chunk(i))+17 And z>EntityZ(Chunk(i)) And z<EntityZ(Chunk(i))+17 Then
		obj=CopyEntity(Block(id).obj,Chunk(i))
		AddMesh obj,Chunk(i)
		PositionEntity obj,x,y,z,1
		ScaleEntity obj,1/32,1/256,1/32
		For i3 = 1 To CountChildren(Chunk(i))
			obj2=GetChild(Chunk(i),i3)
			If EntityY(obj,1)=EntityY(obj2,1)+1 Then					   
                                Clearsurface GetSurface(obj,2)
				Clearsurface GetSurface(obj2,1)
			EndIf
			If EntityX(obj,1)=EntityX(obj2,1)+1 Then
				Clearsurface GetSurface(obj,6)
				Clearsurface GetSurface(obj2,5)
			EndIf
			If EntityZ(obj,1)=EntityZ(obj2,1)+1 Then
				Clearsurface GetSurface(obj,4)
				Clearsurface GetSurface(obj2,3)
			EndIf
			If EntityY(obj,1)=1 Then
				ClearSurface GetSurface(obj,2)
			EndIf
		Next
		Exit For
	EndIf
Next

I add the block to a chunk (which is like a container for 16x128x16 blocks). After that I check for unnecessary surfaces and delete them. (Btw. is there a way to do this in realtime?).
I am kinda new to this topic and really need help with this problem :)


markcw(Posted 2016) [#2]
I think this is the same problem in Blitz3d where multiple surfaces slow down rendering the more there are. So you need to use a single-surface system, you need to keep your surface count to below say 200 it depends on your minimum pc spec.


angros47(Posted 2016) [#3]
Maybe it can be done by using CSG, in a way similar to Minecraft


icebeararmy(Posted 2016) [#4]
What is CSG?

Not exactly sure, what single-surface means. Does it mean I should add my surfaces to one big surface?


angros47(Posted 2016) [#5]
CSG is "Constructive Solid Geometry". It merges different objects, removing unused parts.


markcw(Posted 2016) [#6]
Look in examples/openb3d folder (renamed standard) for csg.bmx, it shows how to use MeshCSG. From the docs: "Method 0 subtracts mesh2 from mesh1, 1 adds meshes, 2 intersects meshes".

Single-surface is just one surface there's quite a lot about them in Blitz3d threads and code. You would want to cut a large terrain into zones/chunks say 100m, so if they're out of view they won't be rendered.


icebeararmy(Posted 2016) [#7]
I found the example, but my program crashes, when I change the "CopyEntity" in my "AddBlock"-function to this:
obj=MeshCSG(Block(id).obj,Chunk(chunkid),1)


EDIT: Seems like it can add exactly 11 meshes before it crashes. When I have less than 11 meshes, the program crashes while setting the vertex-color (needed for the lighting).

EDIT2: I removed the "AddMesh" in my "AddBlock"-function. It doesn't crash anymore while adding the blocks, but it still crashes while setting the vertex-color. :/

EDIT3: I got "MeshCSG" working now without crashing, but I have two questions: "VertexColor" has no effect, but why? For each block I have 6 textures (top, bottom and sides), but when I use "MeshCSG" to add it to the chunk-entity, the block has the top-texture on every side somehow.