thoughts and questions on geomipmapping/terrain rendering

Started by
15 comments, last by MassacrerAL 16 years, 5 months ago
I am thinking about implementing geomipmapping and i think i actually understand it, just thought i'd pop on hear to clear my thoughts up with someone who knows what there talking about. :) Basically i have a terrain of say 257 x 257 vertices, at the moment this is stored in chunks of 129 x 129 vertices. Therefore i would have four chunks, each chunk has their own vb and ib and is rendered using bruteforce with drawindexedprimitive as a tirangleList. When running this on my home computer which is pretty good x1800xl intel dual e6850 2 gig ram i only get around 50fps which i think is really strange even for a brute force approach, as this is a very small terrain :S I have seen and ran demos which had terrain 4 times this size run with higher fps. My terrain is also wireframe no textures or colours or anything o.o So i figured geomipmapping might help, i currently have a array of vertices and indices stored for full level of detail, if i wanted to use a lower level of detail i would only need to store another index buffer, and i could leave the vertex buffer as it is, is that correct? The index buffer would be stored as an array of WORD, but if i store say 5 Levels of detail for every chunk will 5 arrays of WORD not increase the storage drastically. I have altered my demo app to have different chunk sizes but 129 x 129 seems to be optimal. If i have anything lower i get about a 10fps drop. Does that seem ok and is it sensible to have chunks of 129 x 129 with different LOD? Also is there any algorithm i can look into that might alter my index buffer at highest level of detail to maybe simplify the terrain, I.E. if everything on a plane has the same gradient use 4 verts instead of more? Cheers in Advance :S
Advertisement
Have you tried smaller chunk sizes combined with frustum culling? That is, cull entire chunks with one box/frustum test?

Quote:
My terrain is also wireframe no textures or colours or anything o.o


Try rendering it filled. I recall an experience where wireframe mode was slower than filled mode.

-----Quat
Quote:Original post by Quat
Have you tried smaller chunk sizes combined with frustum culling? That is, cull entire chunks with one box/frustum test?

Quote:
My terrain is also wireframe no textures or colours or anything o.o


Try rendering it filled. I recall an experience where wireframe mode was slower than filled mode.


Hi, i havent tried any kind of culling or occlusion yet since i didnt feel the terrain was big enough, maybe i was wrong.

I have the same problem rendering in solid mode only the FPS i wrote previously was wrong im actually getting about 14 FPS rendering as 257 x 257 size terrain with chunks of size 65 x 65 or 129 x 129
Hey!

What Graphics API are you using? What sort of draw calls are you making to draw the terrain? I wouldn't worry about culling just yet. With the performance numbers you're currently getting, it seems that something else needs to be changed first.

Jeremiah
Power User / Programmer / Game Player ( Not computer nerd :)
Quote:Original post by jerm007
Hey!

What Graphics API are you using? What sort of draw calls are you making to draw the terrain? I wouldn't worry about culling just yet. With the performance numbers you're currently getting, it seems that something else needs to be changed first.

Jeremiah


currently using directX and and im drawing with drawindexedprimitive
basically it just calls drawindexedprimitive for each chunk of size 129 x 129

i dont think there is anyway around this as 129 x 129 = 64k ish indices which is the index buffer limit so either way i would have to call this function more than once.

I think o.o :P
I have finished implementing almost the same thing few days ago so I guess I can help. make chunks smaller, because geomipmapping with 2x2 tiles would be pretty useless. I have fixed number of vertices per chunk(and fixed size of chunk), and then when creating new level I only decide how many of them I want. I think that grid is enough in this case, because if you have 30x30 tiles, then every frame you do only 900 frustum-box checks.

I haven`t done geomipmapping yet, but I think this approach is going to work. index buffers aren`t going to take lots of memory, max. few mbs and I doubt it would be that much. or, you don`t have to store indices in each tile at all. you need to take care of seams between tiles, somehow. I`m probably going to have some static function that generates index buffer from number of vertices in certain tile, LOD level and LOD levels of neighbouring tiles. thats possible because only height of vertices changes and that doesn`t change indices in any way. guess what that means. you can have some "global" index buffers and you don`t have to store them in each tile. that would be in 30x30 terrain 900 exactly the same index buffers. that would waste at least 2megs of memory, haha.

how are you going to handle textures? i`m using texture splatting. works great and helps to save tons of memory.

there is one more issue. if you have 30x30 grid, you have to make 900 draw calls each frame and with texture splatting each draw call set 7 textures. not exactly efficient, at least in directX. i use this for editor(which I have finished yesterday) because you can cheaply do ray-terrain intersection and cheaply change it and paint on it. however, in game, that would be impractical. so I`m going to use quadtree instead, with one vertex buffer for whole terrain and then in each quadtree node I`m going to have index buffer. then each frame I can simply get all index buffers visible(geomipmapped, I have multiple index buffers and I choose the right one. remember that static function?), merge them together and draw terrain in a single call. I`ll have to deal with texturing somehow, but I`m sure quadtree tiling, megatexturing or some other texture management scheme will do the job. not that easy but performance is going to be great. I think that with quadtree you can use even smaller tiles, maybe you from terrain 30x30 it would be fine to have 300x300.

hope that helps. btw what are you working on? an editor or a game?
Quote:Original post by MassacrerAL
I have finished implementing almost the same thing few days ago so I guess I can help. make chunks smaller, because geomipmapping with 2x2 tiles would be pretty useless. I have fixed number of vertices per chunk(and fixed size of chunk), and then when creating new level I only decide how many of them I want. I think that grid is enough in this case, because if you have 30x30 tiles, then every frame you do only 900 frustum-box checks.

I haven`t done geomipmapping yet, but I think this approach is going to work. index buffers aren`t going to take lots of memory, max. few mbs and I doubt it would be that much. or, you don`t have to store indices in each tile at all. you need to take care of seams between tiles, somehow. I`m probably going to have some static function that generates index buffer from number of vertices in certain tile, LOD level and LOD levels of neighbouring tiles. thats possible because only height of vertices changes and that doesn`t change indices in any way. guess what that means. you can have some "global" index buffers and you don`t have to store them in each tile. that would be in 30x30 terrain 900 exactly the same index buffers. that would waste at least 2megs of memory, haha.

how are you going to handle textures? i`m using texture splatting. works great and helps to save tons of memory.

there is one more issue. if you have 30x30 grid, you have to make 900 draw calls each frame and with texture splatting each draw call set 7 textures. not exactly efficient, at least in directX. i use this for editor(which I have finished yesterday) because you can cheaply do ray-terrain intersection and cheaply change it and paint on it. however, in game, that would be impractical. so I`m going to use quadtree instead, with one vertex buffer for whole terrain and then in each quadtree node I`m going to have index buffer. then each frame I can simply get all index buffers visible(geomipmapped, I have multiple index buffers and I choose the right one. remember that static function?), merge them together and draw terrain in a single call. I`ll have to deal with texturing somehow, but I`m sure quadtree tiling, megatexturing or some other texture management scheme will do the job. not that easy but performance is going to be great. I think that with quadtree you can use even smaller tiles, maybe you from terrain 30x30 it would be fine to have 300x300.

hope that helps. btw what are you working on? an editor or a game?


I'm working on a Terrain editor, its a university project.

It seems like your IB managment would be a lot more efficient than mine >.>
I have tried out texture splatting in an earlier build it looks very nice and works very well, the only problem being I have no idea how i will implement a texture managment system on top of my current system :S one thing at a time i guess lol.

I intend to have a quadtree after i've got my performance issues and texturing sorted out, as it will / should help with the general performance. Since i need to editor to display large terrains all at once.

I wasnt too sure about reducing the size of my chunks mainly because i read a paper suggesting a certain number of verts to be sent when rendering at once. I thought a 129 x 129 terrain chunk would satisfy the criteria i do intend to play around with the numbers once its working properly to see what gives the best performance.
Are you running your brute force test in debug or release mode? Frame rate figures mean next to zero in debug mode, profile in release. Another thing is v-sync, which if enabled will limit your frame rate to your monitors refresh rate.

Also, I've toyed around with geomipmaps before and gotten some nice results, however my next terrain pet-project will be toying around with geo clipmaps which I'm still yet to fully grasp the idea of, but you might be interested in taking a look.
Quote:Original post by instinKt
Are you running your brute force test in debug or release mode? Frame rate figures mean next to zero in debug mode, profile in release. Another thing is v-sync, which if enabled will limit your frame rate to your monitors refresh rate.

Also, I've toyed around with geomipmaps before and gotten some nice results, however my next terrain pet-project will be toying around with geo clipmaps which I'm still yet to fully grasp the idea of, but you might be interested in taking a look.


I will definetly have a look at geoclipmaps maybe if i get it i will have a go at implementing that instead :)

I have tried both release and debug with the control panel and in VS 2005 i only get a 5fps difference between the two 0.0

When i run the project without any terrain being rendered i get a fps of 1800 :S it could be something to do with my rendering which atm goes something like this

i have no management for VB and IB in place atm this is just me testing out my work

	d3ddev->SetFVF(D3DFVF_XYZ);	// Activate the VB and the FVF	for(int n = 0; n < exampleChunkedHeightData.iNumberOfChunks; n++)	{			d3ddev->SetStreamSource(0, pVertexBuffer[n].m_pVB, 0, sizeof(sVertexXYZ));			d3ddev->SetIndices(pVertexBuffer[n].m_pIB);			HRESULT HR = d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, exampleChunkedHeightData.hdHeightData[n].iNumberOfVertices, 0, exampleChunkedHeightData.hdHeightData[n].iNumberOfTriangles);	}
Quote:Original post by LordFallout
I'm working on a Terrain editor, its a university project.

It seems like your IB managment would be a lot more efficient than mine >.>
I have tried out texture splatting in an earlier build it looks very nice and works very well, the only problem being I have no idea how i will implement a texture managment system on top of my current system :S one thing at a time i guess lol.

I intend to have a quadtree after i've got my performance issues and texturing sorted out, as it will / should help with the general performance. Since i need to editor to display large terrains all at once.

I wasnt too sure about reducing the size of my chunks mainly because i read a paper suggesting a certain number of verts to be sent when rendering at once. I thought a 129 x 129 terrain chunk would satisfy the criteria i do intend to play around with the numbers once its working properly to see what gives the best performance.


for texture management:
http://www-evasion.imag.fr/Publications/2004/LDN04/
or http://home.comcast.net/~tom_forsyth/blog.wiki.html#%5B%5BKnowing%20which%20mipmap%20levels%20are%20needed%5D%5D

I think I`m going to use technique from the first paper. I`m just going to make it simpler and faster. their way to decide which LOD of some tile you need looks somehow expensive. I`m going to simply decide which LOD I need from some distance function. not that accurate and popping will certainly appear, but thats fine. you can change LOD algorithm anytime. in that texture cache I`m going to store textures already splatted. that should be fast enough.

quadtree in editor is pretty useless, because only benefit you could get from it is less frustum-box checks. if you had one VB for whole terrain, imagine when changing it sending 50mb vertex buffer from VRAM and then back. if you have 900 draw calls per frame, thats fine but will drain your CPU. in gothic 3 they had about 900 draw calls and 350 000 triangles per frame and it worked fine. but I`m sure they didn`t spend it just on terrain, you have to render other thing like trees and stuff and you need cpu to do physics and things. thats why you need to reduce draw calls of terrain in game.

yeah my IB management is better, but that wouldn`t be any performance hit in your case.

oh hell would love to talk to you some more but gotta go to school. have fun

This topic is closed to new replies.

Advertisement