GeoMipMap Implementation

Started by
30 comments, last by Quinnie 16 years, 11 months ago
Quote:Original post by Quinnie
Quote:Original post by i_luv_cplusplus
Tell me how you figured out these indices, and I shall be your sex slave :) I can't figure it out

... Note that there may still be some issues regarding the CW and CCW thing

It may not be the most elegant solution, but here is a simple algorithm for generating the indexes while maintaining CW/CCW.

Using you example grid above...

First, generate the indexes as if you are stripping a standard grid:
         0,  9,  1, 10,  2, 11,  3, 12,  4, 13,  5, 14,  6, 15,  7, 16,  8, 17, 17,     9,  9, 18, 10, 19, 11, 20, 12, 21, 13, 22, 14, 23, 15, 24, 16, 25, 17, 26, 26,    18, 18, 27, 19, 28, ... 
Next, instead of removing vertexes, you move them. According to the diagram, the following vertexes are moved like this:
    From    To      1      2      3      4      5      6      7      8      9     18     17     26     27     36 
Finally, replace the indexes of the moved vertexes with the indexes of the vertexes they are moved to:
         0, 18,  2, 10,  2, 11,  4, 12,  4, 13,  6, 14,  6, 15,  8, 16,  8, 26, 26,    18, 18, 18, 10, 19, 11, 20, 12, 21, 13, 22, 14, 23, 15, 24, 16, 25, 26, 26, 26,    18, 18, 36, 19, 28, ... 
The removed triangles are still in the strip, but are not drawn because they are now degenerate. It results in the same number of triangles, but that is not an issue.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Advertisement
Hey,

thanks for the reply JohnBolton that is actually the same way I implemented my algorithms above and your right that it does indeed not cause any problems with the CW and CCW thing. :D

I implemented my code in my engine and got some screenshots for you guys to look at. I did not yet create a system to calculate the correct mipmaplevel but I'll do so as quickly as possible.

The terrain patches all got the same heightmap data, the heightmap itself is just a plane with a cricle in the middle thats a bit bumpy, its a bit ugly because a friend of mine had to create in a couple of seconds.

The screenshots shows the entire terrain in LOD level 2 and one patch in LOD level 0. You can see the stitching in progress and it seems to work nicely.



I did not yet implement any splatting so its plain white and black :P

Thanks for all the help again :D
I would like to point out something here.

See the problem? I'm still trying to figure out what causes this. I noticed it in my own code at one point, but I'm not sure it's there after later tweaks. I haven't really looked.

[Edited by - Promit on May 11, 2007 5:40:13 PM]
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Quote:Original post by JohnBolton
It may not be the most elegant solution, but here is a simple algorithm for generating the indexes while maintaining CW/CCW.

Does your solution work with triangle strips or normal triangles only?

+rated
OpenGL fanboy.
Quote:Original post by Promit
I would like to point out something here.

See the problem? I'm still trying to figure out what causes this. I noticed it in my own code at one point, but I'm not sure it's there after later tweaks. I haven't really looked.


Hmm I didn't noticed that, however when I enable splatting it still covers the entire area so I'm not sure if it'll be a problem?

Besides that I'm having some difficulties calculating the errors for each patch. I'm trying to follow de Boers equations but I'm having some difficulties implementing them, I would be very greatfull if anyone could help me with the following questions.

First of all the equations as give my de Boer:
Quote:
Dn = |d| · C
Equation 1: Use this equation to calculate Dn for d. C is
a constant which can be calculated using the
equation found in Equation 1a)

C = A / T
Equation 1a), used to calculate C. A and T are constants
which can be calculated using the equations found in 1b)
and 1c) respectively.

A = n / |t|
Equation 1b), used to calculate A. n is the near clippingplane,
and t is the top coordinate of the near clippingplane,
as in (l, r, b, t, n, f).

T = (2 * Treshold) / Vres
Equation 1c), used to calculate T. vres is the vertical
screen resolution in pixels.


And these are the settings I'm using:
Quote:
FoV = PI / 4
Aspect Ratio = 1.0f
Near Clipping Plane = 0.1f
Far Clipping Plane = 2000.0f
Vertical Resolution = 1280.0f
Treshold = 5


First I assumed Vres is the screen resolution and not the backbuffers width, in my test case this would be 1280.

For the Treshold I'm using 5 px so T results in (2 * 5) / 1280 = 0,0078125

Calculating A gives me more trouble, especially because I'm not sure what the variables represent. is n the distance from the camera to the near clipping plane or is it a vector describing the near clipping plane?

Also I'm not sure how to calculate the top coordinate of the near clippingplane. I assume you need the FOV for that?

Should the resulting Dn be a float or some sort of an integer? In promit's code it's typecasted to a short but I'm not sure why that is neccesary.

Thanks in advance and Kind Regards,

Quinnie

p.s.
i_luv_cplusplus: The algorithm I posted above is using triangle strips, JohnBolton's explanation is also using triangle strips since it's actually the same thing I was doing in my code.
Quinnie
Just small hint.
Use (1 << AdjustingMipMapLevel) instead of pow(2, AdjustingMipMapLevel).
And & ((1 << AdjustingMipMapLevel) - 1) instead of % (int)(pow(2, AdjustingMipMapLevel)).
It's much faster.
Thanks for the tip,

I was actually planning to make some sort of look up table kind of thing for the pow() functions but this bit shifting seems to be a better solution. I'll adjust my code right away.

Quinnie
With regards to your C, A and T calculations, this is the way I have always interpreted them.

Vres is the height of my backbuffer. So if I was using an 800x600 backbuffer, it would be 600.

n is the zNear, so in your case 0.01f

I calculate |t| as the tan of half the camera's fov ... e.g. tan(fov / 2.0)

If those are wrong then I have some problems with my own error metrics [smile]

As for the problem Promit has pointed out, I had seen this myself in my own implementation and it arose from the way I was shifting indices.



Basically what you are doing is when a vertex is deemed invalid (the blue dots) you modify the index so that it indexes the last valid vertex (the black dot being the last valid index and the blue arrows showing the direction you shift your indices). What this actually results in is an overhang. It is hard to describe, but that arrowhead shaped concave polygon is not rendered as a concave polygon, but instead like taking a square piece of paper and folding it along the diagonal (you could see it for yourself by freezing your lod updates and navigating your camera down to where that corner is) [smile]

Anyway, the solution is to not always index the last valid vertex, but instead index the nearest valid vertex. So in the case of at least one of those blue dots, you would actually index the red dot instead of the black one.

All the best,
ViLiO
Richard 'ViLiO' Thomasv.net | Twitter | YouTube
Quote:Original post by Quinnie
First I assumed Vres is the screen resolution and not the backbuffers width, in my test case this would be 1280.
1280's an odd value. It's vertical resolution, whereas 1280 is typically a horizontal resolution. (a typical LCD would be 1280 x 1024, so the Vres would be 1024.)
Quote:
Also I'm not sure how to calculate the top coordinate of the near clippingplane. I assume you need the FOV for that?
It's determined by using a right triangle with the hypotenuse going from the eye to the top center of the near plane. The base of that triangle is the near plane distance, and the angle contained by those two sides is half the FoV. It's straightforward trig to figure out the height of the last side, which is the value you need.
Quote:Should the resulting Dn be a float or some sort of an integer? In promit's code it's typecasted to a short but I'm not sure why that is neccesary.
I may have been messing with compressing the data involved at the time. Use whatever seems appropriate. (IIRC, the most recent implementation simply stores the world space errors, rather than the distance. This allows dynamic tweaking of the error value and camera parameters.)
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Hey,

thanks a whole lot for your valuable reply's. Sorry for the obvious mistake with the Vres thing. I did indeed use the horizontal instead of the vertical resolution. However I'm still not sure wheter to use 1024 or 600, 1024 seems to most logical to me.

Also thanks for enlightening the meaning of the other variables used in the equations I'll try to implement it tomorrow morning.

I took a second look at that problem with the corner and I beleive I understand the problem and the solution. Thanks for pointing it out.

Kind regards,

Quinnie

This topic is closed to new replies.

Advertisement