GeoMipMap Implementation

Started by
30 comments, last by Quinnie 16 years, 11 months ago
This is my updated code to calculate the C constant:

// Calculate Cfloat T = (2.0f * TRESHOLD) / VRES;float A = 1.0f / (float)tan(FOV / 2.0f);float C = A / T;

The only thing I'm unsure about is wether the FoV needs to be converted into radians as Promit's implementation does.

Another problem I'm facing is how to calculate the distance between de camera and the patch. Should I use the patch center or use the closest of the 4 edges of the patch? And should I consider the diference between the camera's height and the patch's height or is it sufficient if I only use the 2d coördinates?

Kind regards,

Quinnie
Advertisement
Quote:Original post by Quinnie
The only thing I'm unsure about is wether the FoV needs to be converted into radians as Promit's implementation does.
The tan function takes radians.
Quote:Another problem I'm facing is how to calculate the distance between de camera and the patch. Should I use the patch center or use the closest of the 4 edges of the patch?
Trust me, you don't want to use the patch center. What happens if you do is that for many patches, some of the distances for the LoD changes will be crossed while you're standing on that patch. Geomipmap changes aren't supposed to be significant visually, but they certainly will be if they happen right in front of you and under your feet.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Hey,

I just made some screenshots of my terrain engine in it's current stage. Its using a 1024x1024 16 Bit heightmap, somehow my error calculations aren't working probably. I had to set my Teshold to 40 px before getting some decent results. The screenshots also show some glitches with the texturing I'm not sure why that happens but I'll try to look into that later. Additionally a quadtree culling system is not yet implemented.

My FPS is really low, it might be becuase I'm making 256 DrawIndexedPrimtive per frame (On a Geforce 7600 GS) but I suspect it's my CPU. My algorithm computes the index buffer again for each frame. Should I create some sort of a cache system for that?

I'm real sorry about the very poor splatting done on this screenshots it's kind of confusing but I'm working on a system using blendmaps.




Quote:Original post by Quinnie
My FPS is really low, it might be becuase I'm making 256 DrawIndexedPrimtive per frame (On a Geforce 7600 GS) but I suspect it's my CPU. My algorithm computes the index buffer again for each frame. Should I create some sort of a cache system for that?
You should, yes. The index patching is a fairly brutal amount to run for 6 million indices or whatever it comes out to for strips.

After implementing caching and setting a restriction on how fast the level of detail can change (ie if a patch changed detail less than .25 seconds ago, it can't change again yet), I was running the index patching stuff for maybe 10-16 patches per second. Compare to 256 * 60 = 15360 at full frame rate.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Quote:Original post by Quinnie
My FPS is really low, it might be becuase I'm making 256 DrawIndexedPrimtive per frame (On a Geforce 7600 GS) but I suspect it's my CPU. My algorithm computes the index buffer again for each frame. Should I create some sort of a cache system for that?


Something to think about...

If your patches are 65x65, then you have 6 LODs. There are 2275 possible index buffers. If you precomputed every possible one, they would take up 65x65x2x2275 = 18 MB. That's not a lot of memory on a PC. If you restrict LODs so that adjacent patches never differ by more than 1 LOD, then there are only 16 possible index buffers. Those would only take up only 65x65x2x16 = 132 kB.

The space requirements for 33x33 patches would be 2 MB and 34 kB respectively.

Edit: These values are incorrect. See the corrected values below.


[Edited by - JohnBolton on May 16, 2007 5:00:16 PM]
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Hmm,

defenitly an interesting idea but I'm not really following your maths.

LOD 0 -> 64*64*2 Triangles * 2 indices per triangle * 2 Bytes per index * 4 Sides ^ 6 variations on each side = 128mb (Edit: should be around 38mb)

And that's only the index buffers for LOD 0, adding the size of the index buffers for LOD 1-6 I'm guessing it wil result in something like 200mb.

Maybe my math is wrong, if you are correct and I only need 18mb then I'll probably just precompute every index buffer possible.

Kind regards,

Quinnie

Edit: These calculations are also wrong :P

[Edited by - Quinnie on May 17, 2007 8:59:31 AM]
You are correct, I did not compute the sizes correctly. Second try...

An NxN grid has approximately N2*2 indexes (I think the number is actually (N-1)*(N+1)*2). Each index requires 2 bytes. Each patch has 4 sides, each of which has to be stitched to a LOD of equal or lower value, so there are (log2N + 1)4 possible index buffers for an NxN patch. So the amount of memory required for all the index buffers for an NxN patch requires 4N2(log2N + 1)4 bytes.

LOD 0, 65x65: 4*652*74 = 38.7 MB
LOD 1, 33x33: 4*332*64 = 5.4 MB
LOD 2, 17x17: 4*172*54 = 0.69 MB
LOD 3, 9x9: 4*92*44 = 0.08 MB
LOD 4, 5x5: 4*52*34 = 0.01 MB
LOD 5, 3x3: 4*32*24 = 0.00 MB
LOD 6, 2x2: 4*22*14 = 0.00 MB

The total is 46 MB.

Restricting adjacent patches to be within 1 LOD means each side has to be stitched to 1 of 2 possible patches. So, each LOD requires 4N224 bytes.

LOD 0, 65x65: 4*652*16 = 264.1 kB
LOD 1, 33x33: 4*332*16 = 68.1 kB
LOD 2, 17x17: 4*172*16 = 18.1 kB
LOD 3, 9x9: 4*92*16 = 5.1 kB
LOD 4, 5x5: 4*52*16 = 1.6 kB
LOD 5, 3x3: 4*32*16 = 0.6 kB
LOD 6, 2x2: 4*22*1 = 0.0 kB

The total is 358 kB.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Thanks a lot,

I would think the best solution would be somewhere in between those values. 46MB is to much but I could spare some more than 358KB.

Calculating the amount of memory needed for a terrain system that limits the LOD difference to 3, results in this amount of memory,

LOD 0, 65x65: 4 * 65^2 * 4^4 = 4,1 MB
LOD 1, 33x33: 4 * 33^2 * 4^4 = 1,2 MB
LOD 2, 17x17: 4 * 17^2 * 4^4 = 0,04 MB
LOD 3, 9x9: 4 * 9^2 * 4^4 = +- 0 MB
LOD 4, 5x5: 4 * 5^2 * 3^4 = +- 0 MB
LOD 5, 3x3: 4 * 3^2 * 2^4 = +- 0 MB
LOD 6, 2x2: 4 * 2^2 * 1^4 = +- 0 MB

5,5MB total. I could probably also use 4 LOD differences.

Kind regards,

Quinnie
Restricting the LOD difference worked nicely, although precomputing all of the index buffers still doesn't give me the framerate I'm aiming for.

I'll post some screenshots below, most of time my fps is around 50-60 with a Geforce 7600GS.

A friend of mine took this screenshot and he's getting eaven worse results with his Geforce 5400.


Is there a way to optimize the code better, maybe reduce the 256 DrawIndexedPrimtive calls that are neccesary? Or should I just stick with a smaller heightmap then 1024x1024?

Any feedback would be greatly appreciated.

Kind regards,

Quinnie
Quote:Original post by Quinnie
Is there a way to optimize the code better, maybe reduce the 256 DrawIndexedPrimtive calls that are neccesary?
Uhm...frustum culling?
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.

This topic is closed to new replies.

Advertisement