# thoughts and questions on geomipmapping/terrain rendering

This topic is 3726 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

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

##### Share on other sites
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.

##### Share on other sites
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

##### Share on other sites
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

##### Share on other sites
Quote:
 Original post by jerm007Hey!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

##### Share on other sites
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 havent done geomipmapping yet, but I think this approach is going to work. index buffers arent going to take lots of memory, max. few mbs and I doubt it would be that much. or, you dont have to store indices in each tile at all. you need to take care of seams between tiles, somehow. Im 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 doesnt change indices in any way. guess what that means. you can have some "global" index buffers and you dont 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? im 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 Im going to use quadtree instead, with one vertex buffer for whole terrain and then in each quadtree node Im 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. Ill have to deal with texturing somehow, but Im 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?

##### Share on other sites
Quote:
 Original post by MassacrerALI 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 havent done geomipmapping yet, but I think this approach is going to work. index buffers arent going to take lots of memory, max. few mbs and I doubt it would be that much. or, you dont have to store indices in each tile at all. you need to take care of seams between tiles, somehow. Im 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 doesnt change indices in any way. guess what that means. you can have some "global" index buffers and you dont 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? im 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 Im going to use quadtree instead, with one vertex buffer for whole terrain and then in each quadtree node Im 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. Ill have to deal with texturing somehow, but Im 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.

##### Share on other sites
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.

##### Share on other sites
Quote:
 Original post by instinKtAre 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);	}

##### Share on other sites
Quote:
 Original post by LordFalloutI'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 Im going to use technique from the first paper. Im just going to make it simpler and faster. their way to decide which LOD of some tile you need looks somehow expensive. Im 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 Im 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 Im sure they didnt 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 wouldnt be any performance hit in your case.

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

##### Share on other sites
I thought a quadtree would be something i definetly need since going to allow for frustum checking and occlusion surely this would be needed even in an editor?
Maybe im confused about quadtree but i thought it would be the quadtree that i would actually check against for culling?

Thanks for the Texture links will certainly have a look :)

##### Share on other sites

I would still recommend implementing quadtrees in your editor because it's a very easy way to optimize frustum culling. If will definitely reduce the CPU usage when your terrain grows larger or you reduce the size of your chunks. As I understand DirectX its very beneficial to reduce the number of drawPrimitive calls and frustum culling helps you achieve exactly that.

One thing I don't understand is that you talked about storing your index buffer with WORDS (32 bit) What you probably want to do is to use SHORTS (16 bit) for indices. Another thing that is strange is your low performance when rendering only around 130.000 triangles. With the hardware you describe you should be getting closer to ten times as many frames per second (around 500 fps).

kind regards,
Nicolai

Edited by ndhb

##### Share on other sites
Quote:
 Original post by ndhbI would still recommend implementing quadtrees in your editor because it's a very easy way to optimize frustum culling. If will definitely reduce the CPU usage when your terrain grows larger or you reduce the size of your chunks. As I understand DirectX its very beneficial to reduce the number of drawPrimitive calls and frustum culling helps you achieve exactly that.One thing I don't understand is that you talked about storing your index buffer with WORDS (32 bit) What you probably want to do is to use SHORTS (16 bit) for indices. Another thing that is strange is your low performance when rendering only around 130.000 triangles. With the hardware you describe you should be getting closer to ten times as many frames per second (around 500 fps).kind regards,Nicolai de Haan Brøgger

I dont exactly know what happened but running my app on my computer today im getting about 300 fps which is definetly and increase maybe its a bug in my system maybe not, but i guess i cant really tell unless it re produces itself.

A little strange i think.

I've been wondering about storing my terrain in VB's and IB as the terrain by should have the ability to be Large or Small, with LOD per each chunk it should make sense to have each chunk stored in its own VB rather than one large VB since the VB will have to be dynamic since i am changing the data to be rendered. Is that right or am i on the wrong track completely is the one VB approach a better fit.

Actually i've been thinking about what i just wrote and realised the VB will stay the same the index buffer should be the thing that changes and if these changes are calculated at load time, it should just be a simple matter of a memcpy to the indices for changing the LOD at run time?

Yes you i guess i should not be using WORD but since i experimented with 32 bit indices i forgot to change back to 16 bit indices. I need to change it back now from int as i was experimenting further >.>

##### Share on other sites
Quote:
 Original post by LordFalloutI've been wondering about storing my terrain in VB's and IB as the terrain by should have the ability to be Large or Small, with LOD per each chunk it should make sense to have each chunk stored in its own VB rather than one large VB since the VB will have to be dynamic since i am changing the data to be rendered. Is that right or am i on the wrong track completely is the one VB approach a better fit.

yep, you need to do this in editor, when you need to change your terrain. in game, however you probably wont change terrain, so you can have it in one VB.

Quote:
 Original post by LordFalloutActually i've been thinking about what i just wrote and realised the VB will stay the same the index buffer should be the thing that changes and if these changes are calculated at load time, it should just be a simple matter of a memcpy to the indices for changing the LOD at run time?

you are right again.

for that quadtree thing. I believe that having grid instead is enough(in the editor). in case you have decided to have a quadtree in the editor, you would need to store data in leaves, and that means only difference from grid would be faster frustum culling(less frustum-AABB checks, in case of 30x30 terrain maybe 30 instead of 900). but quadtree is more difficult to implement(grid is just an array and you loop through it), and I guess frustum culling is not going to be a bottleneck anytime soon. personally I have implementing quadtree to editor on the very end of my to do list. I have more pressing matters to do. like grass. I have found a paper about amazingly looking real time grass few weeks ago. mmmm.

##### Share on other sites
Thanks for the reply it helped me to clear things up a little in my head. OK now i have the theory down i just need to figure out a way to calculate the indices from previous indices, i will tomorrow my heads a bit funky atm :)

Any chance you could post me a link to the paper you where talking about :P

##### Share on other sites
OK, i got the geomipmapping working i feel great :P now i just need a distance management system with a quadtree and i can sort out the edges :)

Anyhoo it could just be me but when looking at my terrain in wireframe with less vertices the terrain seems a little smaller, like its shrunk even though its using the same vertices for all corners? Is this a common thing to see, apparant shrinkage?