-
|
|
Re: QuadTerrain LOD: Finished
|
daileyml:
I want to instantiate multiple QuadTerrain classes to provide a "continuous" terrain capability in my game. As the player moves through the world I perform Frustum checks and load/render the appropriate QuadTerrain containing that particular section of the world. All of this works fine, with one exception.
I need to pass an offsetX and offsetY parameter to the QuadTerrain class so that the particular section of terrain is drawn at the proper coordinates in the world space. The problem is that once I do this the QuadNode function throws exceptions because it is expecting the x/y coordinates to fall within the height/width of the heightmap loaded. Can you provide some guidance as to where in the code I would need to apply the offsetX and offsetY values? When I apply them within the QuadNode class it throws exceptions, so apparently there is something in the code logic I am not seeing.
I have managed to this to some degree. Basically I just give it an offset in each direction, apply that to the world matrix, and then for the getHeight I just subtract the offset from your position to get the location within the terrain. Then for the bounding box check I add the offset to the bounding box min and max.
However, Quasar, did you know that there is a glitch with the terrain near the edge in the z direction. I have found this really apparent when working with more than one section next to each other. It only happens in the z direction, and I believe it has to do with not enough indices being added due to the lod, but I am not sure.
It seems to not render an entire strip, or sometimes part of a strip along the edge. Don't know if you knew about this, or don't know how to fix it, but I would appreciate it if you would look into it. As would daileyml here too, I assume
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
Hello.
Your sample not working on my machine.
If i hit F5, it compile sample ( w\o errors ) and starts application.
But application have no form. It's just process, that allocating memory.
GPU: 8800GTS, 2048 mb RAM.
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
I will need this for later, thanks!
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
I'm back, and I'll try hang around on a more regular basis in the future. I realise I'm a bit late to answer anyone's questions, but I'm going to try anyway.
JohnK: Sample not appearing when run. Because the sample uses a 1025x1025 terrain, and because I made it generate the vertices and indices at runtime (as opposed to using a content processor), it can take a long time to start-up. On some computers I tried it on it took as long as two/three minutes. Using a smaller heightmap is the absolute best way to optimise this: use a 513x513, and it'll go from minutes to seconds. Increasing the nodeSize will also help alleviate this problem.
I could have avoided this problem by using a content processor to generate the terrain, but I didn't for three reasons: I didn't know how to use them at the time, I didn't expect it to be an issue, and for the project this was built for I need to be able to generate it at runtime (remember how Age of Empires 2 could generate a map randomly?).
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
CSharp1024: Strip not being rendered along one edge of the terrain. I know about this one, but because I wasn't planning to have more than one QuadTerrain, I didn't bother fixing it at the time. A recent project (semi-commercial flight sim), if it goes ahead, may result in me delving back into this project and messing around with a few things. If I do end up tracking down what's cauing this one I promise I'll post a fix.
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
Thanks, I would appreciate that.
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
I use a small workaround in the mean time where I just move the terrain. I generate an Offset at run time, based off of the map coordinates of each terrain (0,0 would be the origin, 1,0 would be TerrainSize X, 0 Z, etc), and calculate all the vertices/other calculations with this offset taken into account. Instead of just multiplying the map coordinate by the Terrain Size (scaleHorizontal is TerrainSize / HeightMapSize) I do:
| foreach (GameLevel Level in Levels) |
| Level.Offset = new Vector2((Level.MapCoordinateX * TerrainSize) - (256 * xLocs.IndexOf(Level.MapCoordinateX)), (Level.MapCoordinateY * TerrainSize) - (512 * yLocs.IndexOf(Level.MapCoordinateY))); |
Note that the 256 and 512 I believe come from (VertexBufferSize - 1) and (VertexBufferSize - 1) * 2. I haven't really tested. The xLocs and yLocs are the index of this terrains map coordinates in a sorted list of map coordinates. So if you had maps at (-1, 0, 0, 0, and 1, 0), the xLocs,yLocs of the 0,0 map would be 1, 0.
The result is that the maps need stitching together, which is (only partially, I've been having some glitches with just seeing through certain parts or stitching being off at lower LOD) fixed by lerping the 5 farthest right pixels on each terrain to the farthest left at that Z coordinate, and vice-versa for the bottom 5 X to the top 1 on the terrain below to stitch the Z coordinates. The code is posted here. As you can see, it can certainly be optimized more and made cleaner, but it doesn't really matter since it wouldn't take long anyways and is done at load-time. Note that this must be before you generate the vertices for the terrain. The while loop is so that you don't end up lerping from the same starting height to the same ending height and encountering an ugly looking flat block. For the Y, you'll see a seemingly arbitrary looking +2 in the lerp calculation. This is because 2 pixels on the heightmap of the Z axis aren't being rendered due to not being a part of the Index Buffers, so we just add the 2 when lerping to ignore it. If you do something like this, you would probably want to make the corners of each terrain always use full level of detail. It's also far from a perfect fix, and is just a temporary workaround I use.
The actual problem is a result of the indices. The vertices contain the correct positions, but due to the way the indices are set up you will never reach the last two. I'm not sure where, as the calculation of the indices kind of frightens me.
EDIT: Seems like this doesn't work quite as good as I thought. I always tested with the same terrain size, which it works for, but as you get to higher terrain sizes (scaleHorizontal) it seems that it doesn't work too well, or at least would result in having to change the 256/512. And if you switch from one terrain to another with a different value for VertexBufferSize, the stitching would probably be off as well.
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
Count me intrigued. I'll have to read through your code to see what exactly you are doing.
Kapps:The actual problem is a result of the indices. The vertices contain the correct positions, but due to the way the indices are set up you will never reach the last two.
Hmmm... although I still don't know what's causing it, I have a few suspicions. I'll set up a test project and take a look at it this afternoon.
Unfortionately the flight-sim project is off, which is a shame: I would have had to extend this project as a matter of necessity for that, and had already started having ideas. I might as well share them in case anyone else can pull some inspiration from it.
One of the idea's I had was to give each vertex buffer it's own height map: rather than feeding it with a single map, you give it an array of them. Kind of a scary concept, but I/you would only have to change the vertex generation code. Of course, given that the system already takes so long to generate a 2049x2049 map at runtime, this could take a while...
Which brings me to my second idea: moving the QuadTerrain generation code into a custom content processor. Probably a good idea... at-runtime randomly-generated terrains are the exception to the rule, and loading time is an issue.
And finally, I was going to mess around severely with the texturing side of things. My artist had planned to use actual satellite imagery for the ground, which meant a large number of extremely highres textures in a grid pattern over the terrain. My plan was to link the vertex-buffer system to the texturing system, so each buffer was drawn with a different texture, which meant a single diffuse texture in the shader (no blending), as well as the global normal map and possibly a detail map of some sort.
The third might be a bit specific, but the other two are good, generic improvements to the system.
Kapps:I'm not sure where, as the calculation of the indices kind of frightens me.
Don't worry: it frightens me too... ;^_^
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
Okay, here's the results of this afternoons messing about:
Edge strips
Yay! A bug fix. The two edge strips in the Z direction are now rendered. I'd tell you what was causing it, but I'm afraid you'd hunt me down and beat me up for missing such an obvious bug. I mean seriously, it all but had "TODO" written in the comments above it. Suffice it to say: my bad.
LODHeightImpact
A new public variable! This is because I've added because of a new feature: the LOD now takes the height of the camera (from 0, not from the terrain itself) into account when computing LOD. You can increase or decrease this amount depending on your situation: if really tall mountains are LODing when you climb them, you can decrease it. I recommend having this variable as high as possible: because of the global normal map system, a really low poly terrain looks pretty much identical to a super high poly one from above, so you can use this variable really quite aggressively without ruining how good your landscape looks.
Obviously this system could be better (and more complex), but I've decided to keep it simple.
Gap artifacts
Okay, hands up if you've noticed that the Terrain system still has occasional gap artifacts? If you haven't, set the background colour to something reasonably bright and fly around for a few minutes, and you should be able to spot some occasionally on the edges of the camera. Well, I've worked out what's causing them, and am working on a fix. I should have that, as well as the other two features, uploaded by tomorrow.
Cheers!
Quasar
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
Done, done and done! You can download the new version here, or via the link on the first page.
If you're already using it, upgrading should be a simple matter: the only changes are to the QuadTerrain.cs file, so just replace that. :)
Cheers!
Qu.
|
|
-
-
- (0)
-
premium membership
-
Posts
2
|
Re: QuadTerrain LOD: Finished
|
The download link does not work on Media Fire.
|
|
-
-
- (0)
-
premium membership
-
Posts
2
|
Re: QuadTerrain LOD: Finished
|
Never mind, it seems to have been magically fixed now; lol.
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
Hey Qu, I just wanted to thank you for all of the information posted in this topic and the source code.
I am currently using my own terrain system, but I may end up switching to yours and modifying it since it has many features I have yet to implement. (No use re-inventing the wheel, right?)
Keep up the good work!
- syko
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
Hi Quasar!
Haven't taken a look at Riemers board for some time haven't you ;)
Anyway, I was wondering why the heiptmap's width and height have to be a size of type n²+1!? Why the +1 what happens with that?
I'm asking because my Laptop has one of the graphicscards that do not support textures with width and height that are not powers of 2.
Or is there some kind of workaround?
Greez
Duallity
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
Not sure if I speak for Quasar, as I haven't seen the source code, but I know the terrain engine I wrote (in my sig) creates an n^2+1 heightmap width and height based off of a power-of-two texture.
Picture it this way: Draw a 2x2 texture on some graphing paper, using squares of the graphing paper for the pixels. Now, put a dot at each corner of each pixel, you'll end up with a 3x3 grid of points (which is n^2+1).
:)
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
Well, that makes sence and would work perfectly fine for me, but unfortunately the textures have to be loaded with height/width of n²+1.
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
Well, that isn't good. You almost always want your textures to be a power of two. I wish I'd had the time to get a dynamic LOD working with my terrain stuff. I had planned to take a look at this source and see if I would want to use it instead, or just use it to learn some LOD techniques from, but I just had no time with my long hours at work. You may be able to convert his whole source to use power-of-two textures. It'll probably require changing lots of little things throughout the code though.
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
Sure I could do this, I just wanted to talk to Quasar first, because, as you mentioned, you almost always want your textures to be a power of two. So I guess Quasar might be interested in changing that and realises a new official version for that.
|
|
-
-
- (0)
-
premium membership
-
Posts
6
|
Re: QuadTerrain LOD: Finished
|
Qu:Done, done and done! You can download the new version here, or via the link on the first page.
If you're already using it, upgrading should be a simple matter: the only changes are to the QuadTerrain.cs file, so just replace that. :)
Hello Qu,
I have downloaded your latest (I think) sample and run that.On the line 290 from QuadTerrain.cs I have replaced the numLevel parameter from 0 to 1 because of some power of two running error.See below:
normalTexture =
new Texture2D(g, heightMap.Width, heightMap.Height, 1, TextureUsage.AutoGenerateMipMap, SurfaceFormat.Color);
The thing is that I can still see the gaps (some points and some lines) in the terrain.
So,can you point me an workarround for this or if you are that kind to make an update with this issue...I have tested this on 2 computers so far ,and it is the same thing.
Thank you in advance,
defenderd
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
As Quasar does not answer I tryed changing his class by myself so I can use textures with H/W that are powers of two.
It's not really a solution, but it works for the moment.
First seach all the usages of 'heightmap.Height' and 'heightmap.width' and add 1 to them.
One exception is this line:
| VBuffer = (int)(Math.Floor(((float)(xPosition + 1) / heightMap.Width) * sqrtNumberOfVBs) + (Math.Floor(((float)(yPosition + 1) / heightMap.Height) * sqrtNumberOfVBs) * sqrtNumberOfVBs)) + 1; |
| |
Just let is as it is.
As the terrainwidth/height variables now have the value of the height/width +1 you have to change it back in some cases.
| Color[] heightMapColors = new Color[(terrainWidth-1) * (terrainHeight-1)]; |
| |
| numberOfVBs = (int)Math.Pow((terrainHeight - 1) / (VBsize - 1), 2); |
| |
| for (int y = 0; y < terrainHeight-1; y++) |
| { |
| for (int x = 0; x < terrainWidth-1; x++) |
| { |
| //heightstore Array |
| heightStore[x, y] = heightMapColors[x + y * (terrainWidth-1)].R; |
| } |
| } |
| |
| //This one is inside of two for-loops. The comment above them is: "Generate Vertex Positions and normals" |
| if (x > 0 && y > 0 && x < terrainWidth - 1 && y < terrainHeight - 1) |
| |
These are lines where you have to decrease the terrainwidth/height. The lines above are allready the changed ones, so yours should look like them.
I can't give you any line numbers as I've allready changed a few things, but I guess you'll find the lines when you search for 'terrainwidth/height'.
I hope I didn't forget a line, if so and you get an error at a line containing terrainwidth/height just decrease it by 1.
Greez
Duallity
|
|
-
-
- (0)
-
premium membership
-
Posts
6
|
Re: QuadTerrain LOD: Finished
|
Thanks, Duality, for your reply.
I will try that ,but do you think that will resolve the gaps (there are some dots and sometimes some lines) which appear between textures ?
Anyway,thank you for your reply .I am new to XNA which I think is the greatest.This is why I ask probably noob questions...
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
Well I don't see any gaps anywhere. Check if you LOD (it's set as parameter in the Update method) is 3.5f or higher.
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
hey qu this is a bit irrelevant but aimed at getting your attention
could you check out my response in the "3d animation topic" that you were so helpful in?
+[)0663|2 
|
|
-
|
|
Re: QuadTerrain LOD: Finished
|
Hey guys.
First: sorry for vanishing. Again. :rolls eyes: What with other stuff going on I completely forgot to visit the XNA forums for a few days, which somehow became a few months. You may commence kicking me whenever you feel like it.
Soo....
Duallity: n^2+1 was a result of necessity. You see, in order to build a quad tree the way I did, each node of vertices needs to be splittable into 4 smaller nodes, each of which shares sides. A tiny 3x3 vertex grid (1^2+1), can be split into 4 2x2 squares. A 5x5 (2^2+1) can be split into 4 3x3. And so on.
I realise you've already found a solution to this problem, and it's probably better than what I would have suggested, but I'll suggest it anyway: a custom content processor which adds an extra row of pixels to both edges, thus adding the (+1) to n^2 (+1).
Your solution was harder but better.
Defendered: I have very occasionally noticed a gap or two in the terrain over here too, but it's a lot less common than it use to be. If you make the background below the horison black, or add some sort of horison plain with a texture colour similar to what you're using on the QuadTerrain, it's a lot harder to spot when it happens. And if I ever find out what's causing it, I will fix it. And as Duallity said, the higher you increase the LOD value, the less often you're likely to see it.
tdogger: Okay! :D
|
|
-
-
- (328)
-
premium membership
-
Posts
89
|
Re: QuadTerrain LOD: Finished
|
Has anyone got this working on the xbox 360? Any information would be great, I have the demo working on the 360 but can't get it working in my own game! Thanks.
TnT Gaming Trinity Wars - Episode 1 - 3D Console Style RPG - Fall 09! TWP Spine of the World - Action/RPG (Sidescroller) - Approved
|
|
|