Lots of surfaces on a mesh..

Blitz3D Forums/Blitz3D Beginners Area/Lots of surfaces on a mesh..

BlackD(Posted 2004) [#1]
I was studying the 3D makeup of Warcraft 3 maps, and it's fairly simple.. standard map size, is a 64x64 grid mesh, containing two polygons per grid square, or 8192 odd triangles. Now this hits me as strange first of all, as thats a lotta triangles to be drawing, but War3 DOES limit on-screen viewing (even in the map editor) up to a maximum of about a 30x30 viewing size (approx 1800 polys - still allowing plenty for character/scenery models, etc).

However, every square of that can contain a separate texture. Questions:

1. How can this kind of density be achieved in Blitz? Is using 4096 surfaces (one per square) on a mesh realistic? It doesn't sound it.

2. How much will this affect performance considering that only 900 of these surfaces are on-screen at a time?

3. Would splitting up the terrain into say, 64 meshes of 8x8 grid squares each (128 polys, 64 surfaces) be a more likely way to achieve a similar result? Would it save on processing power?

4. Another alternative - creating a massive image in memory and assigning the single image as the texture and dynamically changing/reassigning the texture to "emulate" an effect of each square having a different texture - possibility or insanity?

I'm still trying to get my head around some of this 3D stuff. I mean, playing with sprites having a few hundred on-screen seriously hampers performance, so surely having a few-hundred surfaces on-screen is gonna cause an even bigger performance hit. Any ideas/experience appreciated. :)

+BlackD

PS. Sorry for asking questions I know I could answer by playing around in Blitz for a while, but I'm not that good in 3D and it'd take me days of coding to find answers some folk here probably already know. :)


jfk EO-11110(Posted 2004) [#2]
Sprites can be slow when they use alpha transparency. When the card has to handle a lot alphaed sprites that are filling most of the screen, it can become real slow, esp. when the camera looks trough a lot of layers of sprites.

It is true, a high number of seperate surfaces can also slow things down. If I was you, I would combine both: use a number of 1024*1024 texel textures and each of them contains eg: 4*4 textures. So you would have 16 times less surfaces in use. BTW on some cards 1024*1024 is the max anyway. so you couldn't use eg. a 10'000^2texels texture.


BlackD(Posted 2004) [#3]
Well, after much extended experimentation, I found option #3 works the best.

Using option #1, 4096 separate surfaces on a single mesh, it ground the engine down to about 12fps, on an nVidia 5900 Ultra.

Option 2 isn't really an option.

Option #3 - Create 256 meshes, each with 16 surfaces. This worked very well, and would be how I imagine programs like ALE work to make up large landscapes. I could fit quite a large number of these meshes onto screen and still max out the FPS. Even 512 meshes (a 128X64 map) worked without speed impedence, with 8192 surfaces.

An interesting thing I found though - while moving around this terrain while zoomed in, it would be very jaggy while moving over "new" areas, then once they were viewed, this movement would be smooth and fast. I attributed this to allocating chunks to video memory, and confirmed it by zooming my camera out to view the whole scene, doing an update and render without a flip, then zooming in to the correct level and re updating/rendering/flipping in the main loop - at which stage because it had all been "viewed" in the non-flipped render, it was now all fast and smooth. What is the cause of this? Does Blitz not load objects into video memory when they are created, only when they are first viewed on-screen?


CyBeRGoth(Posted 2004) [#4]
When I first started to code a 3d puzzle game I am working on I had a similar problem to yours, I needed a grid like playing area that could potentially contain hundreds of different textured tiles, the soloution I came up with was to use AddMesh to merge the play area into one mesh.

This could be used to create warcraft 3 style tiling textures that you see on the ground. Using addmesh is pretty fast.

Here is an example I knocked up at work, all from memory but it seems to work ok :)


Graphics3D 800,600,0,2

;##################################################################
; Change Test from 1 to 2
;##################################################################
; 1 = Lots of individual entities making up the 'grid' (Slow)
; 2 = One big mesh created with addmesh				   (Fast)
;##################################################################

Const Test = 1

; Change Width and Height, the bigger the more 'grid' the play area has, you will really see a difference in speed when you try 50 or so with Test 1 (slow :)

Const Width = 30
Const Height = 30

Dim GRID(WIDTH,HEIGHT)

For Y = 0 To HEIGHT
	For X = 0 To WIDTH
		GRID(X,Y)= Rand(0,4)
	Next ; X
Next ; Y

; CAMERA TYPE

Global MVX#,MVY#,MVZ#
Global OMX,OMY
Global Mesh
Global Cube0,Cube1,Cube2,Cube3,Cube4
Global Brush0,Brush1,Brush2,Brush3,Brush4


Type Camera_Type
	Field Mesh
	Field DummyMesh
End Type

;-------------------------
; Set up the Camera
;-------------------------

Global Camera.Camera_Type = New Camera_Type

Camera\DummyMesh 	= CreatePivot()
Camera\Mesh			= CreateCamera(Camera\DummyMesh)
CameraRange 		  Camera\Mesh,0.1,1000

PositionEntity Camera\DummyMesh,Width ,Height,28
RotateEntity Camera\Mesh,0,180,0

Global TileTexture = CreateTexture(32,32,1,5)
SetBuffer TextureBuffer(TileTexture,0) : Color 255,0,0 : Rect 0,0,32,32
SetBuffer TextureBuffer(TileTexture,1) : Color 0,255,0 : Rect 0,0,32,32
SetBuffer TextureBuffer(TileTexture,2) : Color 0,0,255 : Rect 0,0,32,32
SetBuffer TextureBuffer(TileTexture,3) : Color 255,255,0 : Rect 0,0,32,32
SetBuffer TextureBuffer(TileTexture,4) : Color 255,0,255 : Rect 0,0,32,32

SetBuffer BackBuffer()

L=CreateLight(2)
PositionEntity l,150,50,150

; ####################################################################

Cube0=CreateCube() 
Cube1=CreateCube() 
Cube2=CreateCube() 
Cube3=CreateCube()
Cube4=CreateCube()

BRUSH0 = CreateBrush() : BrushTexture BRUSH0,TileTexture,0
BRUSH1 = CreateBrush() : BrushTexture BRUSH1,TileTexture,1
BRUSH2 = CreateBrush() : BrushTexture BRUSH2,TileTexture,2
BRUSH3 = CreateBrush() : BrushTexture BRUSH3,TileTexture,3
BRUSH4 = CreateBrush() : BrushTexture BRUSH4,TileTexture,4

PaintMesh CUBE0,BRUSH0
PaintMesh CUBE1,BRUSH1
PaintMesh CUBE2,BRUSH2
PaintMesh CUBE3,BRUSH3
PaintMesh CUBE4,BRUSH4

; #####################################################################################
;				      Try Method 1 or Method 2 to Compare Speed
;
;
If Test = 1 Method1() ; Each Cube is a completely seperate entity which is individually textured
If Test = 2 Method2() ; Each Cube is merged into the overall mesh, so only 1 mesh is created

; #####################################################################################

Repeat

	If KeyDown(200) TranslateEntity Camera\DummyMesh,0,0,-0.3
	If KeyDown(208) TranslateEntity Camera\DummyMesh,0,0,0.3
	If KeyDown(203) TranslateEntity Camera\DummyMesh,0.3,0,0
	If KeyDown(205) TranslateEntity Camera\DummyMesh,-0.3,0,0
	
	UpdateWorld()
	RenderWorld()


	VWait
	Flip False


Until KeyHit(1)


Function Method2()


Mesh = CreateMesh()

For Y = 0 To HEIGHT
	For X = 0 To WIDTH

		CUBE = 0

		Select GRID(X,Y)

		Case 0
			cube = CopyMesh(CUBE0)
			PositionMesh cube,X*2,Y*2,0 ; * 2 because a cube = 2x2x2
		Case 1
			cube = CopyMesh(CUBE1)
			PositionMesh cube,X*2,Y*2,0 ; * 2 because a cube = 2x2x2
		Case 2
			cube = CopyMesh(CUBE2)
			PositionMesh cube,X*2,Y*2,0 ; * 2 because a cube = 2x2x2
		Case 3
			cube = CopyMesh(CUBE3)
			PositionMesh cube,X*2,Y*2,0 ; * 2 because a cube = 2x2x2
		Case 4
			cube = CopyMesh(CUBE4)
			PositionMesh cube,X*2,Y*2,0 ; * 2 because a cube = 2x2x2
		Case 99
		Goto SKIP
			
		End Select

		   	AddMesh Cube,Mesh
			FreeEntity Cube

	.SKIP
		
		
	Next ; X
Next ; Y
End Function

Function Method1()
For Y = 0 To HEIGHT
	For X = 0 To WIDTH

		Select GRID(X,Y)

		Case 0
			cube = CreateCube()
			PositionMesh cube,X*2,Y*2,0 ; * 2 because a cube = 2x2x2
			EntityTexture Cube,TileTexture,0
		Case 1
			cube = CreateCube()
			PositionMesh cube,X*2,Y*2,0 ; * 2 because a cube = 2x2x2
			EntityTexture Cube,TileTexture,1
		Case 2
			cube = CreateCube()
			PositionMesh cube,X*2,Y*2,0 ; * 2 because a cube = 2x2x2
			EntityTexture Cube,TileTexture,2
		Case 3
			cube = CreateCube()
			PositionMesh cube,X*2,Y*2,0 ; * 2 because a cube = 2x2x2
			EntityTexture Cube,TileTexture,3
		Case 4
			cube = CreateCube()
			PositionMesh cube,X*2,Y*2,0 ; * 2 because a cube = 2x2x2
			EntityTexture Cube,TileTexture,4
		End Select
	Next ; X
Next ; Y
End Function




BlackD(Posted 2004) [#5]
Thanks heaps for that, I really appreciate your time. :) I've been working on this a bit since I asked the question, and I've come up with this so far: (needs to be extracted)

http://www.geocities.com/kinneargames/war3.zip

Very early stages, completely unoptomized code. Arrow keys move around, ESC quits (takes a few secs to quit though as I have a very thoughrough "free"ing routine).

On my machine at least, that runs very fast/smooth. 4096 individual surfaces, spread over 256 meshes, 16 per mesh, ie - a 64x64 map grid. Although increasing it to 128x64 and 128x128 results in no performance loss. I haven't included a toggle to do so - as i said, the code is unoptomized so at the moment changing the map size means a bunch of hard-coding. :)

Feedback on its performance elsewhere is appreciated.

+BlackD


CyBeRGoth(Posted 2004) [#6]
Cool

At work the PC I am using is really bad, has a built in VIA / S3 oboard 3d card, your demo runs at 38fps, I will try when I get home soon and I guarentee it will run a lot faster :)

The warcraft 3 map editor is really powerfull, I would love to create something that is as powerfull and intuative as that for creating terrain style maps.


Who was John Galt?(Posted 2004) [#7]
I don't think 8192 polys will kill many cards - my Gforce 2 could easily cope with that. Reckon a good bet is single surface full of squares and use texture coords to select the right part of the texture


BlackD(Posted 2004) [#8]
falken, its not the polys i'm concerned about, its the number of surfaces (individual textures in the mesh).