Smaller is better.

Miscellaneous Forums/General Discussion/Smaller is better.

Suffering from poor Frames Per Second? Use smaller textures!

Come see : http://modules.indiepath.com/forum/viewforum.php?f=7

That's fine when detail isn't an issue. :)

So uh, single surface texture sheets and uv offset technique is actually a bad idea then?

Nope. A 128x128pix texture with 32x32pix frames maintains the same speed as a 32x32pix texture. It's all to do with the number of pixels.

This compares both solutions. On my machine they are exactly the same (294 FPS). I would have thought the single-surface to be faster, at least by some FPS, even tho only 8 polygons are drawn.
Graphics3D 640, 480, 0, 2
AmbientLight 255, 255, 255

Dim t(4)
Dim s(4)

Const T_SIZE = 2048

AppTitle "Single Surface Texture Sheet"
tex = CreateTexture(T_SIZE*2, T_SIZE*2)
SetBuffer TextureBuffer(tex)
Color 255, 0, 0
Rect 0, 0, T_SIZE, T_SIZE, True
Color 0, 0, 255
Rect 0, T_SIZE, T_SIZE, T_SIZE, True
Color 0, 255, 0
Rect T_SIZE, 0, T_SIZE, T_SIZE, True
Color 255, 0, 255
Rect T_SIZE, T_SIZE, T_SIZE, T_SIZE, True

SetBuffer BackBuffer()

t(0) = CreateMesh()
s(0) = CreateSurface(t(0))
EntityTexture t(0), tex

For i = 1 To 4
	Select i
		Case 1
			v1 = AddVertex(s(0), -1 + i*3, 1,  0, 0,   0)
			v2 = AddVertex(s(0), 1 + i*3,  1,  0, 0.5, 0)
			v3 = AddVertex(s(0), -1 + i*3, -1, 0, 0,   0.5)
			v4 = AddVertex(s(0), 1 + i*3,  -1, 0, 0.5, 0.5)
		Case 2
			v1 = AddVertex(s(0), -1 + i*3, 1,  0, 0.5, 0)
			v2 = AddVertex(s(0), 1 + i*3,  1,  0, 1,   0)
			v3 = AddVertex(s(0), -1 + i*3, -1, 0, 0.5, 0.5)
			v4 = AddVertex(s(0), 1 + i*3,  -1, 0, 1,   0.5)
		Case 3
			v1 = AddVertex(s(0), -1 + i*3, 1,  0, 0,   0.5)
			v2 = AddVertex(s(0), 1 + i*3,  1,  0, 0.5, 0.5)
			v3 = AddVertex(s(0), -1 + i*3, -1, 0, 0,   1)
			v4 = AddVertex(s(0), 1 + i*3,  -1, 0, 0.5, 1)
		Case 4
			v1 = AddVertex(s(0), -1 + i*3, 1,  0, 0.5, 0.5)
			v2 = AddVertex(s(0), 1 + i*3,  1,  0, 1,   0.5)
			v3 = AddVertex(s(0), -1 + i*3, -1, 0, 0.5, 1)
			v4 = AddVertex(s(0), 1 + i*3,  -1, 0, 1,   1)
	End Select	
	AddTriangle(s(0), v1, v3, v4)
	AddTriangle(s(0), v1, v4, v2)
Next

cam = CreateCamera()
MoveEntity cam, 2*3+1, 0, 10
TurnEntity cam, 0, 180, 0

Color 255, 255, 255

While Not KeyDown(1)

	m = MilliSecs()
	If m >= tm Then
		d = m - tm
		tm = m + 1000
		fps# = Float(f) / Float(1000+d) * 1000.0
		f = 0
	Else
		f = f + 1
	End If
	
	Cls
	
	RenderWorld

	Text 0, 0, "FPS: " + fps
	
	Flip False
	
Wend

While KeyDown(1)
Wend

ClearWorld

AppTitle "4 Textures, 4 Surfaces"
t1 = CreateTexture(T_SIZE, T_SIZE)
t2 = CreateTexture(T_SIZE, T_SIZE)
t3 = CreateTexture(T_SIZE, T_SIZE)
t4 = CreateTexture(T_SIZE, T_SIZE)
SetBuffer TextureBuffer(t1)
Color 255, 0, 0
Rect 0, 0, T_SIZE, T_SIZE, True
SetBuffer TextureBuffer(t2)
Color 0, 0, 255
Rect 0, 0, T_SIZE, T_SIZE, True
SetBuffer TextureBuffer(t3)
Color 0, 255, 0
Rect 0, 0, T_SIZE, T_SIZE, True
SetBuffer TextureBuffer(t4)
Color 255, 0, 255
Rect 0, 0, T_SIZE, T_SIZE, True

SetBuffer BackBuffer()

For i = 1 To 4
	t(i) = CreateMesh()
	s(i) = CreateSurface(t(i))
	v1 = AddVertex(s(i), -1, 1,  0, 0, 0)
	v2 = AddVertex(s(i), 1,  1,  0, 1, 0)
	v3 = AddVertex(s(i), -1, -1, 0, 0, 1)
	v4 = AddVertex(s(i), 1,  -1, 0, 1, 1)
	Select i
		Case 1
			EntityTexture t(i), t1
		Case 2
			EntityTexture t(i), t2
		Case 3
			EntityTexture t(i), t3
		Case 4
			EntityTexture t(i), t4
	End Select	
	AddTriangle(s(i), v1, v3, v4)
	AddTriangle(s(i), v1, v4, v2)
	MoveEntity t(i), i * 3, 0, 0
Next

cam = CreateCamera()
MoveEntity cam, 2*3+1, 0, 10
TurnEntity cam, 0, 180, 0

Color 255, 255, 255

While Not KeyDown(1)

	m = MilliSecs()
	If m >= tm Then
		d = m - tm
		tm = m + 1000
		fps# = Float(f) / Float(1000+d) * 1000.0
		f = 0
	Else
		f = f + 1
	End If
	
	Cls
	
	RenderWorld

	Text 0, 0, "FPS: " + fps
	
	Flip False
	
Wend


I get 245 fps with the first, 150 fps with the second.

Stevie

We noticed this way back when GEOM was being developed, we were suffering on some low-end machines so we reduced the texture sizes and let the good times roll.

Hey, good to know. I was going to use really large textures and then use the same textures even in smaller resolution displays, but I guess that isn'ta good idea.

Are you sure this isn't a fillrate phenomenon?

I'm not sure if this could be attributed to fillrate. I'm not changing the size of the object, I'm only changing the resolution of the texture.

They say that mipmaps are meant to help not just with filtering and removing shimmering effects in the distance, but also to make rendering faster when things are further away, so it makes sense that if it has to look through less memory to get to the texels it wants it's going to be faster. I wonder if the gfx card is using some kind of cache system where it reads in a large bunch of texels at a time from adjacent positions and then only uses the ones that it needs, so it wastes time if it has to skip a lot to draw a large texture really small?

Large textures will tax the graphics card's memory system. If there's a slow memory subsystem, large textures will probably impact a lot more on performance. Sharing system RAM as graphics RAM would be a case in question. Old 64-bit or non-DDR cards might also feel the pinch.

Yeah, I've experimented with my lowly gfx440mx recently and it can only support max texture res of 2048. If I use this size instead of 1024 I get half the FPS even though I have over 30mb vmem available.

Stevie

1848.0 on both tests, would have thought Single surface would be faster also.

Like Vinylpusher stated it might be a bandwidth bottleneck...what kinda setup are you running Indiepath?
(but I wouldnt think 128x128 would hardly tax it)


Sam

It's not a bandwidth issue as the speed increase is reflected across all my test machines

1) P4 2.6Gz 800FSB 2GBDDDR FX5200Ultra 128MB (XP)
2) AMD Athalon 600Mhz 256MB Geforce3 32MB(XP)
3) P3 800Mhz 192MB MatroxG400 32MB (Win98)

With regards to the example code, you really need to push the system to see the difference. Try rendering 1000 Quads and then try it.

A 2000 tris single-surface vs 1000 surfaces.
I get around 3.01 FPS for both.
Graphics3D 640, 480, 0, 2
AmbientLight 255, 255, 255

Const T_SIZE = 2048  ; Texture size for the small textures, the sheet will be 2*T_SIZE
Const NB_QUADS = 250 ; NB_QUADS is not really the number of quad, it will be NB_QUADS*4

Dim t(4*NB_QUADS)
Dim s(4*NB_QUADS)

AppTitle "Single Surface Texture Sheet"
tex = CreateTexture(T_SIZE*2, T_SIZE*2)
SetBuffer TextureBuffer(tex)
Color 255, 0, 0
Rect 0, 0, T_SIZE, T_SIZE, True
Color 0, 0, 255
Rect 0, T_SIZE, T_SIZE, T_SIZE, True
Color 0, 255, 0
Rect T_SIZE, 0, T_SIZE, T_SIZE, True
Color 255, 0, 255
Rect T_SIZE, T_SIZE, T_SIZE, T_SIZE, True

SetBuffer BackBuffer()

t(0) = CreateMesh()
s(0) = CreateSurface(t(0))
EntityTexture t(0), tex

For j = 0 To NB_QUADS
For i = 1 To 4
	Select i
		Case 1
			v1 = AddVertex(s(0), -1 + i*3, 1,  0, 0,   0)
			v2 = AddVertex(s(0), 1 + i*3,  1,  0, 0.5, 0)
			v3 = AddVertex(s(0), -1 + i*3, -1, 0, 0,   0.5)
			v4 = AddVertex(s(0), 1 + i*3,  -1, 0, 0.5, 0.5)
		Case 2
			v1 = AddVertex(s(0), -1 + i*3, 1,  0, 0.5, 0)
			v2 = AddVertex(s(0), 1 + i*3,  1,  0, 1,   0)
			v3 = AddVertex(s(0), -1 + i*3, -1, 0, 0.5, 0.5)
			v4 = AddVertex(s(0), 1 + i*3,  -1, 0, 1,   0.5)
		Case 3
			v1 = AddVertex(s(0), -1 + i*3, 1,  0, 0,   0.5)
			v2 = AddVertex(s(0), 1 + i*3,  1,  0, 0.5, 0.5)
			v3 = AddVertex(s(0), -1 + i*3, -1, 0, 0,   1)
			v4 = AddVertex(s(0), 1 + i*3,  -1, 0, 0.5, 1)
		Case 4
			v1 = AddVertex(s(0), -1 + i*3, 1,  0, 0.5, 0.5)
			v2 = AddVertex(s(0), 1 + i*3,  1,  0, 1,   0.5)
			v3 = AddVertex(s(0), -1 + i*3, -1, 0, 0.5, 1)
			v4 = AddVertex(s(0), 1 + i*3,  -1, 0, 1,   1)
	End Select	
	AddTriangle(s(0), v1, v3, v4)
	AddTriangle(s(0), v1, v4, v2)
Next
Next

cam = CreateCamera()
MoveEntity cam, 2*3+1, 0, 10
TurnEntity cam, 0, 180, 0

Color 255, 255, 255

While Not KeyDown(1)

	m = MilliSecs()
	If m >= tm Then
		d = m - tm
		tm = m + 1000
		fps# = Float(f) / Float(1000+d) * 1000.0
		f = 0
	Else
		f = f + 1
	End If
	
	Cls
	
	RenderWorld

	Text 0, 0, "FPS: " + fps
	Text 0, 15, "Tris: " + TrisRendered()
	
	Flip False
	
Wend

While KeyDown(1)
Wend

ClearWorld

AppTitle "4 Textures, 4 Surfaces"
t1 = CreateTexture(T_SIZE, T_SIZE)
t2 = CreateTexture(T_SIZE, T_SIZE)
t3 = CreateTexture(T_SIZE, T_SIZE)
t4 = CreateTexture(T_SIZE, T_SIZE)
SetBuffer TextureBuffer(t1)
Color 255, 0, 0
Rect 0, 0, T_SIZE, T_SIZE, True
SetBuffer TextureBuffer(t2)
Color 0, 0, 255
Rect 0, 0, T_SIZE, T_SIZE, True
SetBuffer TextureBuffer(t3)
Color 0, 255, 0
Rect 0, 0, T_SIZE, T_SIZE, True
SetBuffer TextureBuffer(t4)
Color 255, 0, 255
Rect 0, 0, T_SIZE, T_SIZE, True

SetBuffer BackBuffer()

For j = 0 To NB_QUADS
For i = 1 To 4
	t(j*4+i) = CreateMesh()
	s(j*4+i) = CreateSurface(t(j*4+i))
	v1 = AddVertex(s(j*4+i), -1, 1,  0, 0, 0)
	v2 = AddVertex(s(j*4+i), 1,  1,  0, 1, 0)
	v3 = AddVertex(s(j*4+i), -1, -1, 0, 0, 1)
	v4 = AddVertex(s(j*4+i), 1,  -1, 0, 1, 1)
	Select i
		Case 1
			EntityTexture t(j*4+i), t1
		Case 2
			EntityTexture t(j*4+i), t2
		Case 3
			EntityTexture t(j*4+i), t3
		Case 4
			EntityTexture t(j*4+i), t4
	End Select	
	AddTriangle(s(j*4+i), v1, v3, v4)
	AddTriangle(s(j*4+i), v1, v4, v2)
	MoveEntity t(j*4+i), i * 3, 0, 0
Next
Next

cam = CreateCamera()
MoveEntity cam, 2*3+1, 0, 10
TurnEntity cam, 0, 180, 0

Color 255, 255, 255

While Not KeyDown(1)

	m = MilliSecs()
	If m >= tm Then
		d = m - tm
		tm = m + 1000
		fps# = Float(f) / Float(1000+d) * 1000.0
		f = 0
	Else
		f = f + 1
	End If
	
	Cls
	
	RenderWorld

	Text 0, 0, "FPS: " + fps
	Text 0, 15, "Tris: " + TrisRendered()
	
	Flip False
	
Wend


If I change the following lines:
Const T_SIZE = 64  ; Texture size for the small textures, the sheet will be 2*T_SIZE
Const NB_QUADS = 500 ; NB_QUADS is not really the number of quad, it will be NB_QUADS*4

I get 58FPS and 17FPS respectively
And this
Const T_SIZE = 64  ; Texture size for the small textures, the sheet will be 2*T_SIZE
Const NB_QUADS = 2000 ; NB_QUADS is not really the number of quad, it will be NB_QUADS*4

Gives me 12 and 1 respectively.

With 64/500 I get 26FPS and 23FPS.
With 64/2000 I get 6FPS and 5FPS.

Maybe the difference is not so much on very new GFX cards? But then my target market does not have the latest tech.