| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 19/05/2008 at 17:24:42
| | Hello everyone.
I never actually went through Riemers tut's from start to finish, but they have been a constant and brilliant reference source for me.
I've been working on Dynamic LOD, so I'm wondering if Riemer or anyone else could provide me with some help with writing and drawing my Vertex and Index buffers. Currently I'm storing both in arrays and using DrawUserIndexedPrimatives(). This is obviously not optimal.
I have a single immutable Vertex array, and a dynamic Index array which is continually being updated from each segment of my terrain (I hope to optimise this process, but that's another story). What would be the ideal method to pass these to the graphics card and draw them?
In case anyone is interested... here's a screenshot: 
Thanks for your time,
Qu. | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 20/05/2008 at 03:08:01
| | Wow this is an incredible cool project..
I've spent some time on dynamic LOD algorithms but never had the chance to really produce something finished! So I'll be glad to be of any help.
First a simple question ... are you using DX or XNA ? | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 20/05/2008 at 16:28:48
| | Thanks for the quick reply!
I'm using XNA all the way... I've never used DirectX. Come to think of it, I hadn't really used XNA until about two months ago. Hmm...
I'm implementing the Terrain as a 'Terrain' Class, with it's own methods and variables so that I can re-use as much as I want. With the help I've been getting from the XNA community (and your brilliant tutorials, of course ;) ), it's been progressing rapidly, despite me only being able to work on it during my limited free time :).
It's got its problems: No edge stitching (yet), bad normal popup (which I'm going to fix using a method recommended to me on the creators club site), and performance issues like the one I mentioned above. When it's finished, though, I hope it'll be good enough for widespread use.
 | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 20/05/2008 at 16:36:54
| | Actually, there is one other problem which is by far the most frustrating for me, simply because I can't see any cause for it. It's fully documented over here:
http://www.riemers.net/Forum/index.php?var=1197&var2=0 | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 21/05/2008 at 03:04:53
| | I created a bmp file of 1024x1024 pixel and everything works nicely ... You will not be happy to hear that the graphics card in this laptop is based on an ATI9600, which is around 5 years old :)
What I DID had to do, is move my camera up to height 500 to completely view the terrain. When I did that, everything disappeared, because the far clipping plane of the camera was set to 300. This means that everyting farther away from the camera than 300 units is clipped away.
When I set my far clipping plane distance to 1000, everything works fine:
projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, device.Viewport.AspectRatio, 1.0f, 1000.0f);
|
| |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 21/05/2008 at 03:07:15
| | BTW I remember I found this a very useful article:
http://www.gamasutra.com/features/20000228/ulrich_01.htm | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 21/05/2008 at 19:33:04
| | I wish it were that simple. My clip plane is set at 20,000, I've got a FPS flying camera and it always starts at 0,0,0: the bottom right corner of the terrain. It works fine with 513x513 and anything smaller.
I'll see if any of the samples or tutorials I've got can render a 1025x1025 terrain, and get back to you.
I'll take a look at that article when I can... here's the one which got me started, in case you're interested:
http://www.terrain.dk/
:) | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 22/05/2008 at 13:36:36
| | Which graphics card are you using actually? Maybe I can find one to run some tests.
Anyway, from XNA you can check the limits of your graphics card. Try to run this code:
GraphicsDeviceCapabilities caps = device.GraphicsDeviceCapabilities;
int maxPrimitives = caps.MaxPrimitiveCount;
int maxIndices = caps.MaxVertexIndex;
ShaderProfile maxShader = caps.MaxVertexShaderProfile;
|
Maybe your card doesn't support that many indices, or doesn't render that many triangles in one call. When you render a 1024x1024 terrain, you're asking to render 2M triangles .. which actually means you should use a LOD algortigm to cut this number by factor 1k ;) | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 22/05/2008 at 16:30:57
| | My graphics card is a 768MB NVIDIA GeForce 8800 GTX... [eye twitching]...
I'll try running that code: it should determine if it really is my graphics card. Don't see how it could be, as I've been playing UT3, Stalker and Fear at Max graphics. :)
And your comment about LOD: LOL. By that, though, it should already work: my LOD already reduces the number of indices by huge amounts!
I did a few tests and found the 'threshhold' value: Any heightmap larger than 725x725 (even 725x726) will not render at all on the Generated Geometry Sample. The sky renders, but not the terrain. A terrain with a smaller width but larger height (or vice versa) such as 72x1450 will display.
Also, I created the stitching and applied it to all the node edges. Next job is to apply it to only the relevant node edges. I won't post the images (I'm cluttering the thread)... but here's the URL's. :)
http://bp2.blogger.com/_gwpGfI-b7q8/SDXgimi1zoI/AAAAAAAAACo/qD27XfLKp-I/s400/22.5.2008%25201%2520Stitching%5B1%5D.jpg
http://bp3.blogger.com/_gwpGfI-b7q8/SDXgy2i1zpI/AAAAAAAAACw/3_viVtSzSfc/s400/22.5.2008%25202%2520Stitching%5B1%5D.jpg
http://bp1.blogger.com/_gwpGfI-b7q8/SDXisWi1zqI/AAAAAAAAAC4/VxPygPIvZVw/s400/22.5.2008%25203%2520Stitching%5B1%5D.jpg | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 22/05/2008 at 16:36:27
| | Hmmm... just had a thought. My LOD clears the indices array, making every value 0, and then adds the indices to that. This means that there is a massive surplus of indices all equal to 0 on the end of the array... and the array size is left at the maximum number of indices possible if every Quad Node was at highest LOD.
Should I do something to 'trim' these off, or will the hardware take care of that? | |
|
|
| |
| |
| Poster | : Nemo Krad | | Posts | : 61 | | Country | : England | | City | : Leicester |
| | | | Posted by Nemo Krad on 23/05/2008 at 03:18:37
| | Can't you just dynamically set the array size and populate what you need. Effectively creating a new array each time and putting that in the index buffer.
Also, (not looked at your code) if you aren't already use DynamicIndexBuffer rather than IndexBuffer. | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 24/05/2008 at 05:23:02
| | Well it won't be easy to find that card lying somewhere around ;)
But you should remove the indices you're not using... and DEFINATELY not render any triangles from these indices. This will result in a huge number of triangles rendered, which will probably exceed the maximum number of primitives drawn in a single call.
As a test, you can find this maximum number using the code above, and specify this number as number of triangles to render from your indices. If this works, specify the same number +1. If this fails to work, you know this is your problem. | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 25/05/2008 at 17:11:15
| | Thank you Riemer, your card testing code was perfect, and allowed me to identify my problem!
Max primitives and Max Vertices both return a little over 1 million. As it turns out (I did a lot of testing), going above max vertices will drop your computer back to software vertex processing (Laaaaggg), and going above max primitives will make the terrain not render. This is what was causing my problem... I was rendering a good 8 million indices, most of which were 0,0,0. :)
Now this means I have two problems to fix. The first is indices: I'll take Nemo Crad's suggestion and make a new array each update. I'll also look into dynamicIndexBuffers... might be helpful.
Not able to contain a 1024x1024 vertex array in the graphics card, though (would you believe it goes over the limit by a single vertex?)... that's annoying. I'm not sure how to implement multiple vertex arrays, and not really sure I want to. On the other hand, if I don't, I'm going to be hit with massive performance issues... Ow.
Anyhoo, on to cooler stuff.
I think this speaks for itself:
http://myfreefilehosting.com/f/3c33afd0f2_0.18MB
W,A,S,D and Mouse to move, Tab to toggle fill mode and Q,E to change the LOD level.
There are still a few problems: can't go above 512x512 for reasons given above, moveing the camera too far away from the terrain will cause an exception, almost-unnoticable single-polygon stitching artifacts can be seen occasionally and it has no frustrum culling... but it works!

My biggest problem is the single/multiple vertex array thing... I have no idea where to start, or how to divide the vertex arrays. | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 27/05/2008 at 13:59:04
| | Glad you found what caused your problem!
About the buffers. This discussion is true whether you're using indices or not. First, there are 2 ways to render triangles: from an array or from a buffer. If you render them from an array, you're sending vertices and indices from system RAM to your graphics card each frame. If you're not changing vertices and indices too often, it's better to store them in the RAM on your graphics card by storing them in a VertexBuffer and IndexBuffer. This is explained in the last chapter of Series1, have a look at it. However, if you're frequently changing your indices or vertices, it is better to use a DynamicVertexBuffer. It's the same as a normal VertexBuffer, with a slightly different syntax:
dynVertBuffer = new DynamicVertexBuffer(device, VertexPositionTexture.SizeInBytes * vertices.Length, BufferUsage.WriteOnly);
dynVertBuffer.SetData(vertices, 0, vertices.Length, SetDataOptions.NoOverwrite);
dynVertBuffer.ContentLost +=new EventHandler(dynVertBuffer_ContentLost);
private void dynVertBuffer_ContentLost(object sender, EventArgs e)
{
dynVertBuffer.SetData(vertices, 0, vertices.Length, SetDataOptions.NoOverwrite);
}
|
For all details about normal and dynamix buffers, you can read Recipes 5-4 and 5-5.
When you're creating a big terrain, it's necessary to split up the vertex buffers into a few buffers. This is quite easy to do: create multiple buffers, and render from them with multiple DrawPrimitive calls.
The question is how and where to split up... You could just divide a big terrain into 4 terrains. However, sometimes it's better to have one low-detail buffer for the whole terrain, for when the camera is far away. Then have 4 buffers with some higher detail, for in case the camera is a bit closer to the terrain. Then again, each buffer can be split into 4 smaller, but more detailed buffers...
This approach would work fine with a quadtree, where you only render those parts of the terrain that are in sight of the camera.
I've explained a quadtree implementation in Recipe 2-10.
I tried to run your code, but my 5-year old graphics card in this laptop made it crash ;) I could just see the red cross on the white background, which indicates software mode, I think...
However, I would be glad to host your project on my site! I was thinking about a new section, Community Projects, where visitors can upload their projects so they can discuss them. Given my current schedule, I think I can only get this working in mid-July, though. | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 27/05/2008 at 23:05:16
| | OK, I think I'm beginning to understand. Buffers for static objects, Dynamic Buffers for objects which change fairly often, and arrays for objects which change every frame?
I'm going to need to buy your book. :)
As for splitting my Vertex Buffer, I've come to think the easiest way is to use a seperate VB for every 513x513 square, as well as a seperate 'full terrain' one for quadnodes larger than this.
I think I'll create a jagged array for them...
I'm going to post a new version with a much smaller index array size implemented tommorrow. If your problem was indices>maxIndices, then this should fix it, and it should not crash. *crossed fingers*
If your problem was to do with something else, (int[] index buffer, maybe?) then at least I'll know there's a problem there, and can try to fix it.
As for hosting my project on your site: I'd be honored! No rush though: If anyone understands being too busy to do the important stuff in life, it's me. :D
Oh, one last thing: I did a comparison between rendering each quadnode with a seperate Draw call, and compiling them into a single array and using one draw call. The results were... strange:
The easy one first: Seperate-draw-calls. At LOD 5 we get a steady 60FPS. By the time we hit LOD 7, we're down to 40FPS. It keeps dropping in this fashion: 30FPS @ LOD 9 and 20FPS @ LOD 12.
Now the strange one: Compile-into-single-array. Like the previous one, it's 60FPS at LOD 5, and drops to 40FPS at around LOD 7. Then, it does something strange: at LOD 9 it's gone back up to 60FPS. What's even stranger: it hovers at 60FPS until you get to a massive LOD of 25! O_O
I'll upload the second one tomorrow so you can see if that works more betterly. :)
Thanks for taking an interest, byt the way: it helps keep me motivated. ^_^
Cheers!
Qu. | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 28/05/2008 at 15:33:52
| | Well it's nice too see your motivated posts!
The tests you've done are indeed a bit strange .. in the separate-draw-call way, how many DrawPrimitive calls do you have per frame at lod 9?
Otherwise, you can try putting this code in your Initialize method:
graphics.SynchronizeWithVerticalRetrace = false;
graphics.ApplyChanges();
IsFixedTimeStep = false;
|
This will make XNA stop limiting your program to 60fps.
Also, are you re-creating the contents of your arrays each frame, or are you creating them only once at startup? | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 28/05/2008 at 16:34:48
| | I was wondering how I could stop the 60FPS limit: thanks for that.
Each QuadNode instance has it's own set of index arrays: one index array for each stitching combination. These are all created at startup.
My Vertex array is also created at startup.
However, when I compile to a single array, I recreate that 'master array' each frame from the smaller arrays (using Array.Copy to get the data from each of the small ones to the large one).
I'm not sure how many draw calls I'm using, but it's sure to be alot. My square size in the tests has been 17, on a 513x513 terrain, which means a rediculously massive number of QuadNodes.
As promised:
http://myfreefilehosting.com/f/772bc8c633_0.18MB
WASD and mouse to move, Tab to toggle FillMode, hold Space to fly and use Q&E to increase/decrease LOD. Let me know if it works. :) | |
|
|
| |
| |
| Poster | : lordikon | | Posts | : 57 | | Country | : USA | | City | : Denver |
| | | | Posted by lordikon on 29/05/2008 at 00:01:06
| | A quad-tree size of anything less than 128x128 is usually not worth it. The graphics card can render than many polys with less overhead than checking so many more quad-tree nodes.
My tests have shown the highest framerate on most cards is with quad-tree sizes of around 256x256.
The draw calls aren't the expensive part, the bounding frustum intersection check against the bounding box for each quad-tree node is what gets expensive, and the recursion.
So for a terrain of size 1024x1024, and a quad-tree node size of 256x256 you end up with 16 leaf nodes, 4 512x512 nodes, and the root node of 1024x1024, giving you a total of 21 possible bounding box checks, and a max of 16 draw calls, which isn't too bad as that only occurs if ALL the terrain is in your frustum, which shouldn't happen with scaling and a decent far plane (which isn't 20,000).
For a terrain of size 1024x1024, and a quad-tree node size of 128x128, you end up with 64 leaf nodes, 16 256x256 nodes, 4 512x512 nodes, and 1 root node, for a total of 85 possible bounding box checks and 64 draw calls. This is quite a bit more expensive for intersection checks and draw calls. As you can see, anything smaller than 128x128 is just asking for trouble, unless you are using a small terrain, like 256x256. However, with anything smaller than 1024x1024, unless you have NO LOD or scaling, then it is simply as waste to use quad-tree at all. | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 29/05/2008 at 00:45:47
| | Good points, Lord Ikon.
I'm only using small QNodes for the moment because it helps the testing process: it makes stitching artifacts more frequent, LOD levels and the overall Quadtree structure easier to see, and (importantly) makes sure I'm making the quadtree as versatile as possible.
If I'd made it with a node size of 129, the main QuadTree would have only had a depth of 3, and I might have ended up with an algorithm which didn't work for anything much deeper. A depth of 6 ensures that my algorithm will work with any quadtree depth. Be thankful I'm not still using a quadNode size of 3 (I was forced to increase the minimum node size to 9 when I applied stitching). ;)
The other point is that it's dynamic: the user sets the Node Size when they create the terrain. This means that a game with a high graphics load could decrease the Node Size (decreasing the load on the Graphics Card), while a CPU intensive game could increase it (decreasing the load on the CPU).
I'm designing this stuff with a massive far plane because I want to be able to stand on top of a high mountain and look off to the horison, Oblivion-esque. | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 29/05/2008 at 00:58:15
| | Bugger. Clicked reply before I was finished writing my post. :)
As I was saying, I want to use a massive farplane for at least one of my games, so I'm designing this terrain LOD accordingly.
The other point is this: frustrum checks are only necessary if the distance LOD checks pass, and vice versa. This means that I can stop many Frustrum checks if the much simpler distance checks don't pass. This should take a small load off of the CPU.
In reality, though, I'm just trying to make the thing as versatile as possible. I can optimise it once it's set up. ;)
First, though... finishing my Frustrum checks (I'm getting some weird effects, hope to fix them tonight) and implementing Multiple Vertex Buffers. Should be fun!
Thanks,
Qu. | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 29/05/2008 at 13:31:26
| | About the frustum checks: if you know a node is totally contained inside the viewing frustum, there should be no need to perform other checks. Also, in XNA these checks are VERY easy to do as you have the BoundingFrustum and BoundingBox classes ;)
Also, watch out with huge far planes, as you can have some strange artifacts. If any objects you render pretty close to the camera appear to have jagged edges, remember that this will probably be the cause. | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 29/05/2008 at 16:36:26
| | It's funny, I seem to have got hung up on something that should be very simple: Frustrum checks.
I've set them up, creating bounding boxes and a bounding frustrum, and then telling the array compiler to not add them to the master array if they're outside the view frustrum.
And I keep seeing quads not being rendered out of the corner of the screen.
*
I've just had a thought that this might be caused by my recursive algorithm: maybe the parent quads aren't being rendered because the child ones don't tick off against the frustrum. It's an easy thought to check... I'll let you know how it goes. Don't let that stop you from posting If you've seen this problem before :).
*
Also: The weird thing I mentioned with framrate and LOD previously. I further defined it: The framrate drops steadily as you add primitives, down to about 30FPS. Then, when you hit 88000 primitives (no matter the LOD), it suddenly jumps all the way back to 160 FPS.
If you have any idea what might be causing this, please let me know.
Also, on advice from Lord Ikon elsewhere, I'm going to implement timers throughout my setup (around various functions) and add them to my debug text. This should help me work out what's causing this framerate stuff. :P | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 29/05/2008 at 16:55:51
| | Oh yeah, RE: Huge far planes.
I'm going to have a larger than average near clipplane to compensate.
And if all else fails, and my Z-buffer simply can't handle it, I could even create a second camera, position it exactly in the location of the first, set its near clip plane to the same value as the far clip plane of the original, and draw what it displays before I draw what closer stuff displays.
I'd need to take this into account with my frustrum checks, though... :) | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 02/06/2008 at 13:40:21
| | Using a quadtree-like structure, you should start checking from top to bottom. If you do it like this, I don't see how you can the child nodes can determine whether their parent nodes should be drawn or not?
Also, about the huge far plane, keep in mind that you can adjust the depth value of a pixel in the pixel shader. To do this, simply write to the DEPTH semantic (next to the COLOR semantic you're already writing to). This allows you to implement your own depth algortihm. | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 02/06/2008 at 16:20:06
| | Whoops.
You're right, there's no way for the child nodes to affect the status of the parents. I mustn't have been thinking right when I wrote that... No matter. I found my frustrum problem: It turns out I was defining the Quadnode bounding boxes as min(0,1,0)max(1,0,1) as opposed to min(0,0,0)max(1,1,1). Stupid me. ;)
I used Stopwatch objects as timers to work out my various performance stats: here's the approximate results (quoting from memory here for reasons given at the bottom of this post, so bear with me... )
Re-Initialise all QuadNodes: ~10-12
LOD Distance Checks: 3-4. (recursive)
Frustrum Culling: 30-40. (currently not recursive, but only act on Nodes selected by the distance checks)
Apply Stitching: 3-4 (only acts on nodes selected by distance checks and frustrum culling)
Reinitialise and Compile Master Array: 50-150.
The Draw Call: Anywhere from 200 - 4000 depending on number of polygons.
You know that strange thing I mentioned before: >88000 primitives = massive framerate jump? Well, it turns out that that jump is entirely contained within the Draw call: it goes from 3000 to 500 at 88000 primitives, changing FPS from 30 to 160. None of the other timer values change. Does anyone know why?
Finally, the reason I'm forced to quote from memory: halfway finished multiple vertex buffers. Like everything else, I'm making these dynamic: the user can set the Vertex Buffer Size when they make the terrain. I've finished the vertex creation stuff: vertices are added to the correct array depending on their position (buffer edge vertices are added to more than one array). Now I need to incorporate this into the indices... which means adding a usedBuffer value to each Quadnode and somehow getting the creation, stitching and selecting of indices to use this value.
It's going to be a lot of work... :| | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 04/06/2008 at 14:18:26
| | Well I think the issue you had with the BoundingBox is not that stupid at all.. I found myself struggling with it too ;) Obviously they couldn't add min-max checking in the constructor of the struct, but in the same line of thinking they should have dropped the constructor that expects the (min,max) positions. Otherwise the whole Contains functionality doesn't work.
Since its 2.0 update, Series 2 is now loaded with BoundingBoxes and BoundingSpheres. When I create one, even from 2 points, I use this code:
Vector3[] buildingPoints = new Vector3[2];
buildingPoints[0] = new Vector3(x, 0, -z);
buildingPoints[1] = new Vector3(x + 1, buildingHeight, -z - 1);
BoundingBox buildingBox = BoundingBox.CreateFromPoints(buildingPoints);
|
There's not too much I can add to your discussion on the framerate, I'm affraid. If you put only the DrawPrimitives call in the timer and this seems to be the determinant codeline, it really has something to do with the (specific?) graphics card. | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 05/06/2008 at 17:41:29
| | Glad to hear I wasn't being stupid with the whole bounding boxes thing. :) The CreateFromPoints method seems cleaner than what I'm using: I might change my code to take it into account.
The timer containing the draw call consists entirely of "DrawUserIndexedPrimitives".
Therefore, I've decided to adopt the "Ignore it and it'll go away" approach to dealing with the framerate thing. :D
BTW, I'm still using DrawUuseIndexedPrimitives because I update the rendered array every frame due to having to change bounding frustrums every time I move the camera. It seems more efficient to just give the graphics card the array every frame rather than transfering the array to a seperate buffer object and giving the buffer object to the graphics card.
And I'm still working on multiple VB's, although I've slowed up a bit. Once those are finished, I'll release the source code: by that stage the entire geometry setup will be fully working, and with luck it'll be easily usable. | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 09/06/2008 at 17:46:43
| | Nothing is ever easy.
I finished setting up multiple vertex buffers in the form of a jagged array, and surprise surprise: it doesn't work properly.
I get some really weird looking geometry: I'll post a screenshot tomorrow, if I can't work out what's going wrong.
I know there's nothing wrong with the buffer arrays themselves, and I've done extensive testing on the way each node selects the buffer it's going to use, so it has to be something with the way the index arrays are being compiled.
I just realised I'm rambling. I'll post a screenshot tomorrow.
Cheers. | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 10/06/2008 at 12:14:14
| | Yes, a screenshot will help us to see the problem.
But if can't you trace down your problem by rendering from your vertex sources one by one? | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 11/06/2008 at 19:39:52
| | Quick post:
Sorry I don't have the screenshot, but I haven't had any spare time over the last few days. During a few free minutes, I started up the program in debug mode to take a screenshot, and got a bit of a shock.
The screen blacked out for about 1 second, came back on for the same amount of time, blacked out again, came back on, and I hit Alt-F4. I got a little Vista message saying a Video driver had done something horrible, but had recovered.
So, stupidly enough, I tried it again, this time letting the off/on/off/on thing continue. It blinked about 5 times, and then gave me the Blue Screen of Death [Dramatic Evil Music] and tried to restart.
I fled the horror, and haven't got back to it since.
You're right that I should be able to test each Vertex buffer seperately, and I fully intend to do this the moment I find enough courage to approach the evil thing. I'm typing this from my hiding place under the sink. :D | |
|
|
| |
| |
| Poster | : Archenon | | Posts | : 397 | | Country | : Romania | | City | : Oradea |
| | | | Posted by Archenon on 11/06/2008 at 23:34:07
| | LOL ... once i managed to totaly disable my graphicscard. It was my starting days with MDX and suddenly i blue screen appeared (on WinXP) i restarted and the screen resolution was the smallest possible. And i had to reinstall the driver. (From under the sink).
And LOL and the number i had to specify to post this thread was (6666) so it is something evil behind this. | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 12/06/2008 at 03:49:46
| | whoops I have a RivaTNT2 card lying around here which you can borrow for a few days ;)
I've had quite a few times that my graphics card totally flipped and that I had to reboot the pc. But then it usually went back to normal.
Try again when you feel lucky. Maybe today the electricity is of better quality ;) | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 12/06/2008 at 20:32:12
| | Archenon is reporting creepy happenings on the forum, Riemer is threatening me with a RivaTNT2 graphics card and my computer is trying to bluescreen me to death.
It must be Friday the 13th.
 | |
|
|
| |
| |
| Poster | : Archenon | | Posts | : 397 | | Country | : Romania | | City | : Oradea |
| | | | Posted by Archenon on 12/06/2008 at 23:25:48
| | It is bad. Try checking those hex errorcodes. It might give you a clue.
Try reinstalling windows. Or try it with a new graphicscard. | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 15/06/2008 at 17:21:41
| | Nah, that's not my computer. That's just a generic bluescreen I got off of the googleweb. I just like to post it around to promote Windows Vista. :D
But progress has been made!
It took a large number of BS's and restarts, but I found I could prevent the bluescreen by drawing each quadnode seperately. And from there I could keep messing about to find out what was going on.
Eventually, it turned out that I was still using "Terrain.Width" where I should have been using "VertexArray.Width"... a legacy from the single Vertex Buffer days. This was resulting in wierd looking "skewed" indices for each quadnode.
I fixed that and halleluyah! Multiple Vertex Buffers!
This was saturday. On sunday I refined the stuff, spending a while getting the 'root vertex buffer' working, and fixing all the resultant bugs, as well as others I discovered along the way...
And here's the result: a 1025x1025 terrain with dynamic LOD and a 20000 farclip plane!
http://myfreefilehosting.com/f/0f86ca07d0_0.4MB
It uses 5 Vertex buffers (and thus 5 draw calls), and only renders what's needed based on distance and Frustrum calls.
WARNING: I only get 45FPS on my 756MB Graphics card. Obviously, this is far from ideal. I suspect my shader is partly to blame: it's an autogenerated mental mill shader... but I still need to optimise the code.
Cheers!
Qu. | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 16/06/2008 at 14:56:03
| | This starts to become incredibly awesome!
Do you have a idea of the number of triangles you're rendering at any given moment? I think you're still rendering equidistant grids, from grids composed out of quads that have the same size. Is that correct?
A way to cut the number of triangles you're actually rendering, is to use non-equidistant grids. In such a case, you start with the max number of triangles you want to draw. For example: you say that you want to render max 10k triangles. Next, you search for each vertex its surrounding vertices. You transform each of these vertices to screen space. If any of the neighbouring vertices is closer than 2 screen pixels, you remove the vertex.
The idea is to dramatically reduce the number of vertices to render from, while not changing the final result.
Some of these techniques you'll need are described here:
http://www.gamasutra.com/features/20000403/turner_01.htm
Once I found an incredibly learnful movie about this, but I cannot seem to find it. | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 16/06/2008 at 17:16:57
| | "Do you have a idea of the number of triangles you're rendering at any given moment?"
Yep. I added a "renderedIndices" variable, which counts the leaf nodes every update and multiplies the result by the number of indices in a quadNode.
On average, I get about 200,000 indices for a 1025x1025 terrain. (I really wish this computer could run XNA stuff, as then I'd be able to check a 512 terrain...).
"I think you're still rendering equidistant grids, from grids composed out of quads that have the same size. Is that correct?"
Correct, and it's something that's been bugging me. The sample has a lot of absolutely flat ground which is rendered as thousands of tiny polygons, when a few squares would suffice.
The major problem with this is the act of 'modifying' the index buffers once they've been created.
But first, I think I'll clean up my code and call it something official sounding like "Terrain Quadtree LOD Version 1.00 Beta"... and see what you guys think of it! :D | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 17/06/2008 at 19:52:50
| | Oohhh-Kaaayyyy...
Turns out I have a short attention span ("Oh look, something shiny!"). Rather than cleaning up my code, fixing public variables that shouldn't be public, etc, I decided to go straight to the "do-flat-area's-with-fewer-polygons" algorithm without a pause.
But I'm still sharing the source code!
http://myfreefilehosting.com/f/e26f5856b4_0.87MB
This will at least allow you to mess about with different heightmaps, quad sizes and vertex buffer sizes. And for those brave enough to venture into the QuadTerrain class itself, I've mostly commented it, although even *I* don't understand how some parts of it work... | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 19/06/2008 at 15:10:14
| | lol!
Let us know about your progress. You might want to search for ROAM, as this is what you'll actually be implementing then in some form. | |
|
|
| |
| |
| Poster | : Anonymous | | Posts | : | | Country | : | | City | : |
| | | | Posted by Anonymous on 19/06/2008 at 19:18:04
| | Hmmm... based on what I know about ROAM, I thought it was an alternative to quadtrees, rather than something you would implement in conjunction with them...
...although, on further reading, it becomes apparent that the double implementation is exactly what they did over here: http://www.terrain.dk/terrain.pdf
I think I confused us both: the 'flat area's' algorithm I'm working on currently is a static function: it only happens once, and removes unecessary indices from the index buffer (I'm not sure whether it's possible or even useful to remove vertices from the vertex buffer. Any idea?).
Here's a preliminary screenshot, to give you an idea of what I'm doing:

I'm not sure whether I should bother with adding ROAM on top of the quadtree structure... it really depends on whether I'm CPU bound or GPU bound, how versatile changing quadnode sizes is and how much a vertex by vertex search is going to impact performance. And also how much effort it would involve on my part to code it. ;) | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 21/06/2008 at 03:09:05
| | You're adapted triagles already look quite nice!
You're correct about your buffer usage, the most important is that you reduce the number of indices, as this reduces the number of triangles drawn. Since the size of your index buffer is small compared to the size of your vertex buffer, you can adjust the full contents of your index buffer quite frequently and overwrite the old index buffer on your graphics card.
However, if you want real flexibility in adjusting the detail of your terrain, you'll have to step away from your quad-rendered grid, and move over to the diamond shaped grid. Much like this image at gamasutra shows
This allows you to drop and add triangles in a much more dynamic way.
The image above actually shows one of the most elaborate cases: say you want to increase the detail of triangle T. This requires you to add all the red edges of the image on the right! | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 22/06/2008 at 18:50:57
| | I had a *slight* breakthrough.
I changed from DrawUserIndexedPrimitives to using static VertexBuffer's and DynamicIndexBuffer's. It took a bit to modify my code (never having used buffer objects before), but in my humble opinion it was worth it:
OVER TENFOLD PERFORMANCE INCREASE!!!!!

I'm not kidding: before this I could render a 1025 terrain at an average of 45fps. Now, I get an average of roughly 470FPS!
Oh yeah.
OK, second point... converting to a diamond grid shape: while I agree this would be a better LOD system, and I've seen it used in Blitz3D's terrain system (and it works brilliantly), I think it's not really worth it in this case: on top of the quadtree it would just add too much CPU load.
I probably should have started out using it, but now that I've fully got the Quadtree set up, it's not going to work.
Aaand third point: the flat area's thing. After spending all weekend on it, I finally managed to fix the gap artifacts I was getting because of it. Then, I realised that in some cases, making larger polygons by extending the 'flatstrips' sideways would actually increase the number of total polygons by seperating some of the flatstrips down the centre.
That realisation, combined with how much work it would take to make the flatstrips take into account sideways extension (and then fix all the new gap artifacts), has decided it: I'm going to stick with the flatstrip method you can see in the above screenshot.
Forth point: I'm ready to start work on a shader! Most of the geometry is done (although I'm sure a bit of optimisation wouldn't hurt), so I added a method to generate a global normal map during construction. I stole this idea from jwatte on the XNA CC forums: use a global normal map rather than per vertex normals, thus taking away the visible normal popping on the terrain.

I'm going to back up the current *geo only* version, and start work on the version with the shader. I'm hoping to combine detail normal mapping, multi-texturing and the above 'global normals' texture (which means 1 global blend texture, 4 ground textures, 1 detail normal texture and 1 global normal texture: 7 textures).
Which means I'll actually need to learn HLSL and stop being cheap with Mental Mill. Reading Series 3! :D
Here's the current source code:
http://myfreefilehosting.com/f/9eec83713d_0.24MB | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 23/06/2008 at 00:57:59
| | Oh, one other thing: Nick Gravelyn pointed out elsewhere that FPS isn't a linear scale, so it might not be an *actual* tenfold increase.
He's right: I shouldn't have used FPS as my performance marker. But responding to him, I checked out the actual FrameTime value, and guess what I found?
1000ms/sec / 45FPS = 22.22.. ms per frame
1000ms/sec / 450FPS = 2.222.. ms per frame
It's still a tenfold performance increase! The universe loves me!
Nonetheless I learned you shouldn't use FPS as a performance marker. :D | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 23/06/2008 at 17:46:03
| | I've started on the terrain shader. I understand that some people will want to use their own terrain shaders, so I'm still making the class versatile enough to quickly change shaders (nothing is 'built-in'), but I'm adding some features to my shader that make it look nice.
One feature, which I thank jwatte on the Creators Club for, is the idea of using a global normal map (see above) to set the normals, rather than a per-vertex system. This means that the distance LOD only affects the shape of the terrain, and not the lighting. I implemented this last night, which I think is quite impressive given that I had never used HLSL before 2 days ago. My compliments on the work you've put into Series 3, Riemer!
Anyway, here's the result:
http://bp3.blogger.com/_gwpGfI-b7q8/SGAe_mTrh4I/AAAAAAAAAFY/Ni8NCBbrKP4/s1600-h/23.6.08+3+Shader+Compare.JPG
The image on the left is 'before': using vertex normals. The image on the right is 'now': using textured normals and shader trickery. Note that the actual geometry in both images is identical. (Well, almost identical. The viewpoint is a bit off, so the frustrum is culling an extra quadNode on the second image (hense the different 'rendered indices' counts). The *visible* geometry in both images is identical, anyway.) | |
|
|
| |
| |
| Poster | : m_Maky | | Posts | : 67 | | Country | : france | | City | : Nice |
| | | | Posted by m_Maky on 23/06/2008 at 17:51:28
| | interesting topic!
keep up the good work! | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 25/06/2008 at 21:26:27
| | Still working out HLSL, but I managed to implement detail normal mapping on top of my global normal mapping, as well as fix a few really strange effects caused by getting the global normals directly from a texture.

Diffuse Colour and Multitexturing next!
I've also been considering geomorphing, because my LOD popup still looks pretty awful (even with the normals using a global normal map). The major obstacle is that I'd have to implement a DynamicVertexBuffer (rather than the static one I've been using), and I'm not sure what effect this would have on performance. | |
|
|
| |
| |
| Poster | : Archenon | | Posts | : 397 | | Country | : Romania | | City | : Oradea |
| | | | Posted by Archenon on 25/06/2008 at 22:28:39
| | | Well that looks very nice | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 26/06/2008 at 16:32:05
| | OK let me see.. you're still figuring out HLSL but you managed to implement normal mapping???
You're talking about a DynamicvertexBuffer, but don't you rather need a DynamicIndexBuffer? Just keep your vertices stored on the graphics card, and change the indices?
| |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 29/06/2008 at 18:06:36
| | "OK let me see.. you're still figuring out HLSL but you managed to implement normal mapping???"
Yep... Sort of...
I'm not great with HLSL, but I do understand how the vertex and pixel shaders work. So with a bit of aid from the documentation, and your tutorials, all I'm really doing is applying a texture lookup to the normal rather than the colour.
Technically, my normal mapping isn't accurate. Rather than getting complex with tangents and bitangents, I simply added the detail normal to the global normal. This means that the detail normal 'pulls' on the global normal and the end result is that the displayed lighting is for a terrain which not as high as the actual terrain.
Despite this, it looks OK :) I'm considering adding an option to choose 'normal quality' for the terrain shader (and learning about tangents and bitangents), so the user can choose whether or not to add the extra strain on the pixel shader.
"You're talking about a DynamicvertexBuffer, but don't you rather need a DynamicIndexBuffer? Just keep your vertices stored on the graphics card, and change the indices?"
That's exactly what I'm doing at the moment. The reason I might need a Dynamic Vertex Buffer is Geomorphing: when the new quadnodes pop in, rather than instantly displaying the new geometry in the new position (resulting in a visible 'pop'), slowly move the geometry from the old position to the new, hiding the pop.
This would require a DynamicVertexBuffer, because the actual position of some of the vertices would be changing.
Oh... and I worked out multitexturing:
 | |
|
|
| |
| |
| Poster | : orgad | | Posts | : 78 | | Country | : israel | | City | : hadera |
| | | | Posted by orgad on 04/07/2008 at 14:31:27
| | woah this looks realy awesome!
| |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 05/07/2008 at 09:42:46
| | Very nice! This really makes me want to dive into that topic again.
Btw your bump mapping will work fine on your terrain, you'll only see some problems in patches with large inclinations. | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 07/07/2008 at 19:56:20
| | OK, stuff has happened since my last post in this thread.
I got a laptop, which should help me optimise my code: performance gains are much easier to spot when it won't run much faster than 60fps. It should also increase my productivity: I can actually *do* something on the train to work now.
I wrote a checklist of the things I need to do to finish off, fix, or otherwise work on. Here it is:
{
- Stitching/Frustrum gaps - Occasionally I've noticed gap artifacts along some of the stitching lines, but they disappear when you move the viewport. An example can be seen in the bottom left quadrant of the screenshot (I worked out how to get blogger links working, so the link should work). I think the bounding frustrums are messing with the stitching algorithms.I'll need to track this one down before release: gap artifacts are annoying.
http://bp3.blogger.com/_gwpGfI-b7q8/SGAcmrC39XI/AAAAAAAAAFI/MMe6TPjZt2w/s1600-h/23.6.08+1+Shader.jpg
- Unnecessary Vertex Normals - My vertex struct still contains a Normal element, even though the shader no longer needs it. This would normally be easy to fix, but I'm using this normal value to do the flatstripping. I'll need to do some modification to fix this before I can delete the Vertex Normal field.
- Combine Shader and Quadtree Class - The terrain shader is an essential part of this class, but at the moment I'm making the effect and setting all the parameters outside of the class. Usability dictates that I combine the two, so that users can set effect parameter values via public variables in the terrain class.
- Geomorphing - It's become doubtful I'll bother with geomorphing: converting to a DynamicVertexBuffer and resending the vertex data every frame seems like a performance issue, not to mention a lot of work.
- Garbage collection - I honestly don't know how much of a problem this is, but I am creating a new Index array every frame, then adding it to the dynamic buffer just before I call DrawIndexedPrimitives(). Since I don't have a Xbox 360, I have no way of testing the effects of Garbage Collecting. Is this likely to be a problem? (the new-array-every-frame part, not the lack-of-Xbox part)
- Optimise and Comment - And, of course, I need to go through and optimise the code both in XNA and the terrainShader, and then finish commenting for those people who want to try to understand how it works.
}
I used to have two others: sort Quadnodes based on distance (to render nearby objects first and distant objects last, saving Fill Time) and start using CullMode = CCW (I had been using Cullmode = None, because some of my triangles were defined the wrong way). But I crossed them off the list because I did them. :) | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 07/07/2008 at 19:58:11
| | | Oh yeah, and I fixed my normal mapping to be more accurate, too. It costs the pixel shader a little bit, but it looks better and allows me to have heavier normal mapping. | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 07/07/2008 at 22:02:37
| | Oh, and here's a full size screenshot of the current incarnation running on my laptop. Cheers!
http://bp0.blogger.com/_gwpGfI-b7q8/SHLXqghiJxI/AAAAAAAAAHI/O9Rstb9TigU/s1600-h/8.7.2008+goodDetailMapping.JPG | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 11/07/2008 at 00:44:33
| | Sorry I haven't been updating. It's been a bit hectic recently.
Heres my Checklist, with X's next to the Items I've finished:
Stitching/Frustrum Gaps - X
Unnecessary Vertex Normals - X
Cull Mode/Clockwise Indices - X
Sort Quadnodes - X
Garbage Collection - X
Combine Shader and Quadtree Class
?Geomorphing?
Optimise and Comment
As you can see, I've made a bit of progress.
I had to completely rewrite the Cull Mode, Sorting and Garbage Collection Fixes after a little "accident" on my laptop (I stupidly copied an old version of Terrain.sln over the top of a newer version).
I also found a few things to add to the checklist as I went along:
Cliff Feet - X
If a square has 1 vertex up high (on a cliff) and 3 on the ground, then there is two ways it can be rendered: the diagonal can go flat across the ground, or it can go up the cliff. If the diagonal goes up the cliff, it causes a 'foot', which sticks out from the smooth cliff face.

This doesn't look great when the foot of a cliff has lots of little 'feet' all the way along its length, and also creates a bad looking 'lots of squares' effect at the top of cliffs.
By testing the height difference between opposite vertices, I now work out which way to orientate the diagonal, which results in an improvement in the appearance of the edges of sharp cliffs and walls.

Changable Detail Map Strength - X
I've been meaning to implement this effect parameter in the shader for a while. It does what it says: changes the strength of the detail normal map.
Move stuff from Update to Draw
Not done yet: I need to move anything which doesn't need to be updated more than once per draw call into the DrawTerrain Call, as opposed to the UpdateTerrain Call where it currently resides.
I'm slowly getting there. See you after the weekend! :) | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 11/07/2008 at 00:46:58
| |  | |
|
|
| |
| |
| Poster | : Anonymous | | Posts | : | | Country | : | | City | : |
| | | | Posted by Anonymous on 13/07/2008 at 10:38:19
| | | Great work! Hope you dont forget to post up the app so we can see it! | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 13/07/2008 at 13:16:39
| | Yes man, this is starting to look really great!
The best thing is that you manage to come up with a solution to all the problems you find ;) | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 13/07/2008 at 17:38:46
| | I think... Yep... I think it's just about finished!
I've combined the shader and class, and shoved comments in throughout, and now I think it's ready for release.
I worked out that my biggest performance issue (on my laptop at least) is the texture lookups - which is actually a good thing, because it means I can save significantly on framerate by simply using lower detail textures. :)
So then... give me one more day to clean up the project file and change the accessors of those variables the user doesn't need access to, and I'll provide a download file for the full source code. :D | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 14/07/2008 at 12:40:13
| | Excellent!
I was planning to make an addition section to this site with "Community Projects", maybe I should hurry so I can get something ready? This looks like a perfect project to start with! ;)
I would give users ftp access so you can upload/modify your files to your liking, add some screenshots and stuff.
Let's see if I can find some time! Yesterday afternoon I coded the 2D game for the new beginners series, I just have to add explosions to it and then I'll start with you section. | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 14/07/2008 at 14:53:01
| | | Send me a mail with the name of your project to riemer dot grootjans at google point com, and I'll try to give you access as soon as possible! | |
|
|
| |
| |
| Poster | : Anonymous | | Posts | : | | Country | : | | City | : |
| | | | Posted by Anonymous on 14/07/2008 at 16:40:11
| | Cool! Can't wait to see the new section of the site!
I'm sending something from my work e-mail, with the subject name "Dynamic LOD".
Oh, by the way: Explosions == Awsome. | |
|
|
| |
| |
| Poster | : Anonymous | | Posts | : | | Country | : | | City | : |
| | | | Posted by Anonymous on 26/07/2008 at 22:47:30
| | | Any news on this?? | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 29/07/2008 at 16:13:33
| | Not really. Just waiting for the new section of the site so I can upload the files. It's pretty much done.
In fact, as a temporary solution, I'll upload the source code and the heightmap and textures I've been using to a file hosting site:
http://www.mediafire.com/?ou2dtj0gym3 | |
|
|
| |
| |
| Poster | : Anonymous | | Posts | : | | Country | : | | City | : |
| | | | Posted by Anonymous on 29/07/2008 at 20:58:21
| | | cool, great work! | |
|
|
| |
| |
| Poster | : Duallity | | Posts | : 289 | | Country | : | | City | : |
| | | | Posted by Duallity on 04/08/2008 at 08:07:52
| | Hi everyone,
at first, Quasar this is really awesome :)
I've run your code on my Laptop and there are a few gaps in the terrain textures espacially at the textures farer away, but there are no gaps at your last picture. So I wanted to ask whether it could be because of my quiet cheap graphics card in my Laptop :) or is there still something not working perfectly?
Greez
Duallity | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 05/08/2008 at 00:14:04
| | Hi Duallity!
What do you mean by gaps? Thin edge cut's, missing polygons, or something to do with the textures? I haven't encountered any artifacts on either of my home computers, but I'd expect a graphics card incapable of running it wouldn't produce specific artifacts: it'd just not run. | |
|
|
| |
| |
| Poster | : Duallity | | Posts | : 289 | | Country | : | | City | : |
| | | | Posted by Duallity on 05/08/2008 at 09:52:58
| | Here's a picture i think it's worth more than explaining what i mean :)
http://www.bilder-hochladen.net/files/7ope-1-jpg.html | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 05/08/2008 at 16:15:20
| | | Ah, I remember seeing something similar to this when I was debugging. From memory (don't quote me on this) it was created by not generating mipmaps. Select each of the textures in your solution explorer, and ensure that their mipmap property in the properties window is set correctly. | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 08/08/2008 at 09:14:45
| | | keep in mind that in order to mipmap an image, both its width and height should be a power of 2. | |
|
|
| |
| |
| Poster | : radulph | | Posts | : 214 | | Country | : germany | | City | : hamburg |
| | | | Posted by radulph on 09/08/2008 at 13:46:46
| | hey folks,
I programmed a LOD system on my own. Now to my problem :p
I use a static Vertex Buffer, which actually holds all vertices in the highest level of detail.
The vertex buffer isn't changed during the whole game. I rather update the dynamic index buffer.
But when I try to do this calling SetData my framerate drops to 0.
What do I do wrong?
Thanks for you help. | |
|
|
| |
| |
| Poster | : Zrgi | | Posts | : 14 | | Country | : Serbia | | City | : Belgrade |
| | | | Posted by Zrgi on 10/08/2008 at 07:13:32
| | | I like your project. It is very complicated, but it works. One thing i don't like is that it loads like 1 minute, the first time i started it i thought it is bugged and won't load at all. | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 10/08/2008 at 16:15:20
| | radulph:
I'm not quite sure what your problem is: I didn't encounter anything that would drop my FPS straight to 0. A code sample might help us work out what's wrong.
Zrgi:
Yeah, I know. There are two ways that you can improve the load time: halving the Heightmap Size (from 1025x1025 to 513x513) will result in a *massive* reduction in load time, and increasing the QuadNode Size will also lower the load time significantly. | |
|
|
| |
| |
| Poster | : radulph | | Posts | : 214 | | Country | : germany | | City | : hamburg |
| | | | Posted by radulph on 11/08/2008 at 07:21:50
| | thx for the reply!
I'm not sure, but I think I figured out, what the problem was.
I tried to call SetData on my IndexBuffer, before the gpu finished rendering. This resulted in an error message like ~"You may not modify this resource, since it is in use". Double Buffering might help in this case.
How do you update your terrain Quasar? Do you use dynamic index or static buffers? Do you use Double Buffering?
thx in advance. | |
|
|
| |
| |
| Poster | : radulph | | Posts | : 214 | | Country | : germany | | City | : hamburg |
| | | | Posted by radulph on 11/08/2008 at 07:23:14
| | sry, should be: "dynamic index or vertex buffers"
;) | |
|
|
| |
| |
| Poster | : Zrgi | | Posts | : 14 | | Country | : Serbia | | City | : Belgrade |
| | | | Posted by Zrgi on 11/08/2008 at 07:37:37
| | For my Terrain Editor (i am currently working on it) i just use a static index buffer and vertex buffers that contain closest squares of vertices, max number of those buffers is 9. Now because only the closest terrain parts are drawing i will add fog so it will look like you just can't see the rest. Here is a screen shot from the editor:
(The clear color is there because it is a small terrain i made just to try some things i added, not because its not drawing enough) | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 11/08/2008 at 15:13:02
| | Hey man that's not fair just to post a screenshot like that!
At LEAST tell us how you're doing the blending, and what exactly you can edit with that cool program! | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 11/08/2008 at 17:11:45
| | radulph: I use a static VertexBuffer for the entire terrain, which never gets updated or changed, and I use SetData to update a DynamicIndexBuffer every frame.
Zrgi: Cool program!
Allow me to demonstrate my awsome powers of prediction:
-- Autogenerated but changable vertex colours to determine how to blend multi-texturing
-- A maximum of 4 textures (RGBA)
-- Ability to save geometry to a heightmap
-- Ability to save vertex colours to a texture?
-- Ability to move squares of vertices up and down in editor (but not smoothly: they come up sharply).
Correct me if I'm wrong about any of it. ;) | |
|
|
| |
| |
| Poster | : radulph | | Posts | : 214 | | Country | : germany | | City | : hamburg |
| | | | Posted by radulph on 12/08/2008 at 05:19:28
| | Thanks Quasar!
And you use only one single Index Buffer? Could you please post a little code snippet, which shows the update part? Would be very helpful for me.
greets | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 13/08/2008 at 16:12:18
| | I originally used only one Vertex buffer, but was forced to add the ability to split the terrain into several when I found out that there is a limit to the number that can be contained and drawn efficiently in a single VB.
Did you download the sorce code when I uploaded it? It's all in the source code, and I've commented most of it.
http://www.mediafire.com/?ou2dtj0gym3
The relevant part of the update code looks like this:
This section compiles all the indices into a single array (one for each vertex buffer)
foreach (QuadNode q in qnl)
{
//Compile sorted leaf nodes into array
q.indices[q.stitchedSides].CopyTo(allIndices[q.VBuffer], renderedindices[q.VBuffer]);
//Add to indice count
renderedindices[q.VBuffer] += q.numberOfIndices;
} |
And this section updates the DynamicIndexBuffer itself.
//////////////////////////////////////////////////////////////////////
//Add the main index arrays to the various Index Buffers.
if (first != true)
{
for (int k = 0; k < allIBs.Length; k++)
{
if (renderedindices[k] > 0)
{
allIBs[k].SetData<int>(0, allIndices[k], 0, renderedindices[k], SetDataOptions.Discard);
}
}
} |
| |
|
|
| |
| |
| Poster | : Zrgi | | Posts | : 14 | | Country | : Serbia | | City | : Belgrade |
| | | | Posted by Zrgi on 19/08/2008 at 14:39:57
| | | I was on vacation, thats why i didn't replay earlier. Well Quasar, you are right about a lot of things but not all. You are right that currently only 4 textures are supported, but i have made a totally new algorithm for the blending that will work on as much textures as i like, but the thing about the auto generated vertex texture blend info and that it is changeable stays. Squares of vertices can be moved up and down, but in the sharp and the smooth way (i will add a tool that will smooth a selected square of vertices). Now i have a file format that the editor will support, and the function that saves in that format already exists, but isn't used yet (long story why... It will work very soon). I am not stopping when i finish everything with the heightmap, this editor will be able to do things like in 3D Max (Create world objects). Why am i doing all of this ? Well its really simple, i want to practice, and i want to make a Ninja Game ;). | |
|
|
| |
| |
| Poster | : Zrgi | | Posts | : 14 | | Country | : Serbia | | City | : Belgrade |
| | | | Posted by Zrgi on 19/08/2008 at 14:57:57
| | | Oh, and about the buffer thing. I use a index buffer that contains indices for a 32x32 (32f in world, number of vertices variates because of the terrain detail option). The 9 vertex buffers use that index buffer and contain squares that are in the camera view. Code does this: calculates the main vertex buffer using the camera target and fills it (if it isn't already the main buffer) and than fills the vertex buffers that are no longer needed with the ones that are. So just if you didn't understand the terrain is practically divided in to squares of 32x32. Hope that everything is clear now. | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 21/08/2008 at 20:08:21
| | Hey guys: I made a big (and I mean *big*) announcment thread on the XNA forums: here's the URL.
http://forums.xna.com/forums/t/15397.aspx
It goes through the whole thing from start to finish, explaining how it works, how I built it, how to use it, etc. as well as providing a download link.
Don't stop posting in this thread, though! That's just an announcment thread.
BTW: I'm working on a few new functions for it: GetLODHeight() (which takes into account the level of detail when gathering terrain height values) and a few GetNormal() functions. | |
|
|
| |
| |
| Poster | : vToMy | | Posts | : 37 | | Country | : Israel | | City | : NA |
| | | | Posted by vToMy on 22/08/2008 at 11:02:23
| | I downloaded your sample and it looks and runs great! I'm very impressed and considering using it in my game (can I?)
I noticed though that there are some holes or stitches or whatever you call them sometimes. You should fix that.
Other than that it's great and I'm looking forward to seeing more from you :) | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 22/08/2008 at 14:30:45
| | Great news!
Just think that you started with this project only a couple of months ago (3, actually). I must congratulate you on your progress and skill! | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 24/08/2008 at 16:25:20
| | Thanks for the compliments guys!
vToMy: Go ahead! I'd love to see what you end up doing with it. :)
I don't get why people keep seeing stitching issues, though: when I run it, I haven't been able to find them, search though I may.
Riemer: Thanks again!
Everyone: New version up! This version has the GetHeightLOD function (which takes LOD into account when it gets the height of the terrain), and two new functions: GetNormalSmooth (which uses bilinear interpolation on the terrain normals) and GetNormalSharp (which uses a cross product on the vertices). Both of these are untested, so if you find problems let me know.
http://www.mediafire.com/download.php?nnfl4klx4wh | |
|
|
| |
| |
| Poster | : radulph | | Posts | : 214 | | Country | : germany | | City | : hamburg |
| | | | Posted by radulph on 02/09/2008 at 11:06:10
| | Hi Quasar,
I made huge progress in my own LOD system, but am not satisfied with the level of detail itself. How you can see on the image below, it is scattered very unequaly

Could you throw some light on your algorithm? I mean, how do you decide whether to split a node or not.
thx.
| |
|
|
| |
| |
| Poster | : Berserker | | Posts | : 5 | | Country | : Sweden | | City | : Skövde |
| | | | Posted by Berserker on 04/09/2008 at 06:41:44
| | Hi everyone!
I have been lurking these forums for quite a while, but i am now about to post my first post.
First of all, a small introduction:
Introduction:
-------------
I am studying game development (programming) and have small to medium knowledge about most matters one might encounter.
As a major project in school i set out to create a platform in which heightmaps (and therefore also terrain) could be created using known techniques such as fBm, RidgedMultifractal etc...
I started of making a terrain class on my own. It was first later when i wanted to add some cool shaders that i came across Riemers tutorials (wich are great btw).
So i spaced of on playing with shaders (wich i love), i have done some work in RenderMonkey and bmrt.
Now when my primary goals are almost achieved i started thinking about LOD.
I the constructed a new class which i call Terrain, this has a multidimensional array. That array consists of what i had previously called terrain. Meaning my new Terrain-class is a container of small sections of terrain, together they sum up to be a big terrain.
Now i was wondering why my terrain was so laggy (it says 15FPS but feels like 30ish something), thats when i came across this forum thread.
Problem:
--------
I havent wreally got to the essential LOD-coding just yet. my problem is with the rendering of the smaller sections.
each section has its own buffers but the Draw()-function is called from the container (ie. Terrain-class).
I'll post some code in my next post so that this "intro" can stand for itself. | |
|
|
| |
| |
| Poster | : Berserker | | Posts | : 5 | | Country | : Sweden | | City | : Skövde |
| | | | Posted by Berserker on 04/09/2008 at 06:45:09
| | So the Terrain-class has a:
private TerrainSection[,] mSectionsMatrice;
|
It is a DrawableGameComponent, when its Draw()-function is called it does the following:
if (!this.Visible)
return;
if (!IsDoneGenerating())
return;
///Now this is the funny part.
///Will this increase FPS ??
///It certanly will decrease memory problems.
Game.GraphicsDevice.VertexDeclaration = mVertexDeclaration;
mEffect.CurrentTechnique = mEffect.Techniques["MultiTextured"];
mEffect.Parameters["xWorld"].SetValue(mMatrix_World);
mEffect.Parameters["xView"].SetValue(mMatrix_View);
mEffect.Parameters["xProjection"].SetValue(mMatrix_Projection);
mEffect.Parameters["xLightPosition"].SetValue(mLightPos);
mEffect.CommitChanges();
//mEffect.Begin();
//foreach (EffectPass pass in mEffect.CurrentTechnique.Passes)
//{
//pass.Begin();
for (int x = 0; x < mNrOfSections_X; x++)
{
for (int z = 0; z < mNrOfSections_Z; z++)
{
mEffect.Begin();
foreach (EffectPass pass in mEffect.CurrentTechnique.Passes)
{
pass.Begin();
//int VertexCollectionIndex = (x + (z * mNrOfSections_X));
mSectionsMatrice[x, z].Render(Game.GraphicsDevice, mEffect, mMatrix_World, mMatrix_View, mMatrix_Projection);
pass.End();
}
mEffect.End();
}
}
//pass.End();
//}
//mEffect.End();
//DrawWater(gameTime);
base.Draw(gameTime);
|
| |
|
|
| |
| |
| Poster | : Berserker | | Posts | : 5 | | Country | : Sweden | | City | : Skövde |
| | | | Posted by Berserker on 04/09/2008 at 06:53:46
| | awh, sorry posted before i was done.
Well you can see that i have tried different approaches (all work) for how to render the terrain.
Anyways the terrainsections Render()-function looks like this:
if (mDataIsSet)
{
if (inUsingEffect != null)
{
inToGraphics.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, mVertexes[inLODLevel], 0,
(int)(mWidth *mDepth),
mVertexIndex[inLODLevel], 0, (int)(mWidth) * (int)(mDepth) * 2);
BasicEffect(inToGraphics, null), inToGraphics);
}
}
|
I cant make it work with buffers. I have buffers but they wont render.
inToGraphics.Indices = mTerrainIndexBuffer;
inToGraphics.VertexDeclaration = new VertexDeclaration(inToGraphics, VertexMultitextured.VertexElements);
inToGraphics.Vertices[inVertexCollectionIndex].SetSource(mTerrainVertexBuffer[inLODLevel], 0, VertexMultitextured.SizeInBytes);
inToGraphics.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, (int)(mWidth * mDepth), 0, (int)(mWidth) * (int)(mDepth) * 2);
|
so... erm.. My problem is the rendering of the sections basicly.
i hope i havent made a mess out of your thread. And please excuse my english. | |
|
|
| |
| |
| Poster | : Berserker | | Posts | : 5 | | Country | : Sweden | | City | : Skövde |
| | | | Posted by Berserker on 04/09/2008 at 08:41:07
| | To: Quasar
I tested your application and i am amazed, good work!
Now i would like to make something similar =)
For me experimenting and learning is more important then actually completing something at the moment.
Anyways, i noticed something strange...
I have an average of 500FPS, but when looking directly at the sky it still says that it renders about 137k primitives (?). | |
|
|
| |
| |
| Poster | : Berserker | | Posts | : 5 | | Country | : Sweden | | City | : Skövde |
| | | | Posted by Berserker on 05/09/2008 at 11:13:02
| | No matter what i try it seems as if the DrawIndexedPrimitives-command has to have the full buffers. Because when i iterate through all of my sections from the container-class only one will be drawn.
So i have gone back to a working build were all sections is beeing drawn. Then i added a bitmask defining wich sections is visible.
This has given me one of the easiest LOD's possible. Though it always renders all sections in full complexity it will only render thoose visible.
It will have to due for the moment. | |
|
|
| |
| |
| Poster | : Anonymous | | Posts | : | | Country | : | | City | : |
| | | | Posted by Anonymous on 16/09/2008 at 20:50:45
| | My apologies to those who have been posting: I haven't been doing any recreational coding in a while, so I sort of forgot to visit the coding forums. I'm back now, though...
radulph: looks good! It looks like you're using a different method to what I did, though: some sort of ROAM algorithm? I only really know about quadtrees...
I used a distance check to decide whether to split a node: check a node, if the camera is inside the range (range determined by the size of the node: lower detail nodes have larger ranges), split it and check the four children nodes.
Berserker: The looking at the sky and still rendering primitives is because that count is for all primitives that are not culled by the bounding boxes or distance checks. When you are looking up, the bounding box sometimes still intersects the camera, so the node you are in is still added to the draw call (despite not being in camera sight) and thus to the Rendered Indices count.
I prefer to compile all my indices into a single array, then give that to a dynamic indexbuffer. See the post (above) on the 13/08/2008 at 16:12:18. | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 17/09/2008 at 13:11:31
| | | Hi there Quasar, nice to see you back ;) | |
|
|
| |
| |
| Poster | : radulph | | Posts | : 214 | | Country | : germany | | City | : hamburg |
| | | | Posted by radulph on 17/09/2008 at 13:33:29
| | Hi Quasar,
thank you for your answer and nice to hear something from you again :)
I managed to get a smoother scattering of the level of detail. (sry for my english)
But now I'm standing in front of another problem and hope you can help! (Hope Riemer has a look at this lines too :) )
I use double buffering. That means:
I have 1 static vertex buffer and 2 dynamic index buffers. While one buffer is in use, I recompute the LOD and assign the indices to the second, unused, buffer.
The next time rendering this buffer is being used and I update the other one and so on.
"The array is not the correct size for the amount of data requested"
This is the error I'm getting executing this line of code:
ib.SetData<uint>(0, inds, 0, (int)indexCount, SetDataOptions.Discard);
inds is an array containing the indices and indexCount == inds.Length.
Any ideas? thx in advance. | |
|
|
| |
| |
| Poster | : radulph | | Posts | : 214 | | Country | : germany | | City | : hamburg |
| | | | Posted by radulph on 17/09/2008 at 13:48:14
| | I switched to one buffer to make it more simple and found out the following:
The error occurs under this conditions:
ib.setData.... //first call everything ok
move the camera -> update the indices
ib.setDate... //second call, different count of indices = crash
it doesnt crash, when the number of indices stays the same. | |
|
|
| |
| |
| Poster | : riemer | | Posts | : 1388 | | Country | : Belgium | | City | : Antwerp |
| | | | Posted by riemer on 18/09/2008 at 12:19:34
| | The second time, did you update the value of indexCount? I think your update line should rather be
ib.SetData<uint>(0, inds, 0, inds, SetDataOptions.Discard);
|
Also, you need to make sure your array never becomes larger than the first array, or your data simply will not fit in the buffer. As a solution, it's far better to allocate a bit too much space than to re-allocate the buffer to a larger size. | |
|
|
| |
| |
| Poster | : radulph | | Posts | : 214 | | Country | : germany | | City | : hamburg |
| | | | Posted by radulph on 18/09/2008 at 13:20:56
| | Riemer!!!!!!! Thank you so much!
I didn't try it out yet, but that must have been the reason: Of course the number of primitves can grow as well as it can become less!
You know, I think this is the kind of information you cant get the normal way (checkin forums and google) - so thanks again! =)
As soon as I try it out I will post my proceeds. Next step is Multithreading, so the draw call doesn't have to wait for the computation of the level of detail.
It's just sad to hear, that now only one benefit remains of using a lod: Shorter rendering time rather then less memory (index buffer) consumption.
Greetings | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 18/09/2008 at 18:55:04
| | <b>radulph wrote:</b>
<i>"It's just sad to hear, that now only one benefit remains of using a lod: Shorter rendering time rather then less memory (index buffer) consumption."</i>
This is actually a much bigger benefit than it sounds. A normal terrain has far more polygons than an LOD'd one, and takes up more of the screen pixelwise than any other in-game object.
Even a simple shader can die horribly due to fill-rate if your terrain doesn't have LOD. Fancy stuff like detail mapping and multi-texturing is even more susceptable.
I should probably look into Multithreading; my implementation doesn't use it; but it looks complex, and for the moment I'm not to concerned. The "Bugger it, we're lazy" option currently seems more appealing. | |
|
|
| |
| |
| Poster | : radulph | | Posts | : 214 | | Country | : germany | | City | : hamburg |
| | | | Posted by radulph on 19/09/2008 at 06:16:04
| | SUCESS!!! =)
Hi guys, it works. Had some problems with multithreading but they are solved now.
My code is a little bit messy at the moment but I'm to lazy to clean it up right now.
Short description of my lod:
-Based on a quad tree.
-Uses kind of a diamond shaped grid (which makes creating index buffers very easy - requires adaptive level between neighbours)
-Multithreading: The lod is being computed continously by a background thread. This allows complex and slow functions (eg VF culling???) since they don't interrupt the draw call.
-Double buffering: 2 index buffers are used alternately to avoid draw call interruptions even further.
Next step is to write a better lod function (the one responsible for splitting nodes) and then comes texturing I think.
I won't go for multiple buffers yet, since I'm able to create 2k x 2k meshes.
Here's a screenshot:

Greetings
| |
|
|
| |
| |
| Poster | : radulph | | Posts | : 214 | | Country | : germany | | City | : hamburg |
| | | | Posted by radulph on 21/09/2008 at 12:08:32
| | Hi Quasar,
how did you actually avoid terrain popping? Did you implement geo morphing?
Although I do very small changes to the detail of my quad nodes each frame, the effects are haeviliy visible:
-at edges
-when textures are being stretched.
I've come to a very easy way of implementing geo morphing:
Generate a height map containing only the affected vertices (the ones that have been inserted this frame) and send it to the graphics card.
When processing the vertices you just look up, if the current vertex is contained in this height map (for example, if it has a valid color value at the vertex' position) and change its height as needed.
The downside on this is, that it requires a vertex texture fetch and therefore shader model 3.
Let me know your thoughts on this.
Greetings | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 21/09/2008 at 19:58:27
| | Hi Radulph.
The only way's I could work out to implement Geomorphing involved either Shader Model 3 (as you mentioned, and which I didn't want to do) or implementing a Dynamic Vertex buffer (which I also didn't want to do).
When I implemented the global normal map...
http://4.bp.blogspot.com/_gwpGfI-b7q8/SGAe_mTrh4I/AAAAAAAAAFY/Ni8NCBbrKP4/s1600/23.6.08%2B3%2BShader%2BCompare.JPG
... popup visibility became so minor that I didn't bother with geomorphing: it wasn't worth the extra work.
You'll have to decide for yourself if you want to do geomorphing: I'd recommend checking out the global normal map idea first. | |
|
|
| |
| |
| Poster | : Anonymous | | Posts | : | | Country | : | | City | : |
| | | | Posted by Anonymous on 18/10/2008 at 11:01:25
| | Hi there,
this is a very interisting thread.
Nice work Quasar.
I'm working at the moment at a terrain editor. Can anyone who have done a project like this post a link, to download it? I would be very thankful about this. | |
|
|
| |
| |
| Poster | : Ne0Que | | Posts | : 23 | | Country | : Borger | | City | : the Netherlands |
| | | | Posted by Ne0Que on 08/02/2009 at 00:57:11
| | Quasar,
Sorry for bumping this up..
i have a question.. how did u fix those jagged diagonals? (cliff feet) You show the wrong/right image but no solution :(
Thank you. | |
|
|
| |
| |
| Poster | : Quasar | | Posts | : 121 | | Country | : Australia | | City | : Brisbane |
| | | | Posted by Quasar on 25/05/2009 at 16:43:45
| | Nearly forgot to drop you guys a line:
I finally got around to fixing a few bugs in this LOD implementation (they were asked for on the XNA creators club). The details, and the download for the new implementation, can be found at the end of the thread here:
http://forums.xna.com/forums/t/15397.aspx
Ne0Que: sorry it took me so long to get back to you, I've been away for a while. If you're still around...
What I did to work out how to split the triangles was compare the vertical difference along the two diagonals. Whichever diagonal was less steep was the one I split the triangle along. For the picture shown, one diagonal will be flat, the other will be sloped. By splitting along the flat one, we avoid ending up with cliff feet. | |
|
|
| |
| |
| Poster | : Duallity | | Posts | : 289 | | Country | : | | City | : |
| | | | Posted by Duallity on 05/07/2009 at 11:53:32
| | Hi,
I'm trying to get your Quadterrain working in my engine, but it seems like the texture that should only be drawn near the camera is spread all over the terrain.
Any idea why this happens?
http://www.bilder-hochladen.net/files/7ope-a-jpg.html

Thx and Greez
Duallity | |
|
|