Showing posts with label xna. Show all posts
Showing posts with label xna. Show all posts

Tuesday, 6 October 2009

Tweakables

I've been busy recently with XNA stuff, trying to get a nice physics model of a vehicle going. You soon discover that you accumulate a huge number of "settings" - constants that affect the behavior of your model. Tweaking these to get the best values you can (or maybe different styles of behavior for different "makes" of vehicle), can be a bit of a pain, restarting every time you want to make a tiny change and test it.

Imagine my delight then when I read this article by awesome XNA blogger Sean Hargreaves about "Tweakables" - the idea that you set up these constants so that you can adjust them on the fly, while the game is running. I knew I had to implement this - it's just too useful not too! (See Sean's next article for other potential uses).

I looked at Sean's suggestions for how to implement this in XNA ... but of course, I thought I had a better idea.

So I created a custom attribute, "Tweakable" (of course!), which I added to some of my static properties (which were simple, lazily coded public member variables until then). Then I created a form which iterates through all the types in my game's assembly, and for any "Tweakable" properties it finds, it adds corresponding controls onto the form (some work here to give them nice labels, organise into a tab per type, etc etc). Finally, an event handler is dynamically added to the controls so that the property is updated when the control is "left".

Et voila - when my game loads I also get a form for adjusting all the "tweakable" properties I like!

I intend to implement the ability to save all the current settings to file, and load them again, plus to start with an initial set. This way, I can save settings I like or which are useful for debugging, and I can exchange settings the rest of my "team" (there are three of us working on something together). I also need to expand the types of variables supported (admittedly just floats so far - will certainly need Vector3's which may require a custom control ...).

Wednesday, 22 July 2009

Bloom









I tried adding bloom ... it didn't entirely work. Not sure what was going wrong ...









Then I added Lens Flare (which doesn't work on my laptop anyway because it doesn't support "occlusion queries"!) ... and the bloom started working! I'd prefer to understand why this happened, but hey, it looks real purdy now!

Sunday, 12 July 2009

Suspect Sphere


The sphere terrain is mostly done, and it looks, well, ok ...:



This looks better in motion! But the normals aren't quite right, and it's a bit jagged, frankly:



Other problems - holes:



The pic's a bit small, but there's not supposed to be a hole up there! Also a big tear at one location:



All slightly depressing. This, coupled with thoughts about how we'll determine the "height" at a given location of the surface (measured in polar coords?) has given me a headache, and I'm considering throwing _this_ away too, and going back to basics - a common-or-garden, flat height-map. I think I'll still join it at the sides and top-to-bottom (so it's topologically a torus, geometry-fans!), because I don't want invisible walls and it's a reasonable way to avoid this.

But sphere would have been cooler ...!

Oh well, it emphasises that for a first project, the mantra "Keep It Simple, Stupid!" is worth sticking to.

Monday, 6 July 2009

Triangles galore

I got the lower-level-of-detail patches working. The scheme is something like this:





A bit hard to read (sorry!), but this was me working out how to navigate round all those triangles in an ordered fashion, to create a sensible triangle strip. Part-way through implementation looked like this:


Quite pretty in it's own right! Eventually I'd done it - it now looks like this:


You can see the "high-detail" joins. I'm also losing some of the rear-facing patches (though I don't do this right at the edges - we'll want to see any high "mountains" on those just-over-the-horizon bits).

Next steps - get it to dynamically choose either the high or low level of detail for each patch, and cull off-screen ones. Then I need to apply a height-map ... no idea how I'm going to get that to wrap properly yet ...!

Friday, 3 July 2009

Terrain ... ONNA SPHERE!!!111

So, lots of work on a clever algorithm which reconstructs a triangle strip for every frame, cleverly including / excluding vertices on an individual basis, clever clever clever. I did an awfully clever implementation of this (well, ignoring the view fustrum culling bit), and the whole thing was looking jolly clever.

Possibly too clever.

I decided it was overkill for a game, taking up precious CPU every frame which would be better dedicated to AI or graphical effects or physics processing or whatever. So I've shelved it, probably for good.

Not one to make life simple for myself, however, I've turned instead to spherical terrain, or "planets" if you like, Super Mario Galaxy-style. I'm going for a geodesic dome-style division of a sphere. Turns out these are pretty simple to construct - you start with (say) an octagon, and then recursively divide each triangle into four smaller ones, pushing the new vertices out onto the surface of the sphere you're trying to approximate.

This is a really rough drawing ... but you can follow the subdivisions by colour, red then green then blue then pink:



I'm doing my subdivision in two stages - two or three iterations to get me a set of "patches". With two iterations, that's 8x4x4=128 patches. Then I further subdivide in each patch, creating perhaps 32 rows of triangles. This arrangement allows me to test distance / visibility etc against each patch, and then render the patch (or not) accordingly, so 128 checks instead of a brazillion (see below).


That framerate's not looking too good though (7 frames per second!). Let's count up how many triangles we're talking about (let's ignore the fact that we've got a count up there already - 38656. For boring reasons, this isn't what we're going to get to anyway).

Start with an octagon (so, 8 triangles).
Split each triangle into 4, twice (so 8*4*4=128).

So we'll have 128 patches.

Then for each patch, we'll have 32 triangles per side. That's 32*33/2=528 triangles per patch.

That's 128*528=67,584 triangles total.

BUT:

We don't need to see patches on the far side of the planet, in fact, we'll probably only be able to see about 32 patches maximum.

And, of those, we'll probably view roughly a third (let's say 12) at full resolution. The rest, we'll have at 8 triangles per side.

But we need the patches to join up nicely, and in general they won't. If we have a patch at 32 triangles per side next to one at 8 triangles per side, we're going to get gaps. So we "fill up" the edges of the low-res patches so that they're full resolution along each side. So each patch will have:

3 corners with 7 triangles = 21 triangles
18 edges with 4 triangles = 72 triangles
36-21=15 remaining triangles = 15 triangles

(this picture is with four triangles per side, but you get the idea!)



Total: 108 triangles

So the grand total once we've done all this is:

12*528 + 20*108 = 8496

That's not so much, is it?!

Now, is a 67k polygon planet going to be detailed enough? Some VERY rough sums: A planet with 0.5km radius (roughly what I'm aiming for), has a surface area of about 1.5km squared. That's 2.25 million square metres of territory. So our triangles will be about 33 square metres in size (say, 6m x 6m).

Hmm, not bad, but I'd like to get it better than that. Still, I've satisfied myself that a scheme along these lines will work - I can afford to have more than 8.5k polys in my terrain I reckon, plus I was conservative in a few places with this estimate. And I can consider (for example) three different levels of detail for each patch. With some tweaking, we should end up with a rather good environment to play in!

Thursday, 2 July 2009

Terrain part 1

... so, I'm fiddling with xna a bit. Trying to implement some good-looking terrain. I was inspired somewhat by Shamus Young's blog, which led me to this paper, and I set about implementing the algorithm described therein (I'm a sucka for this sort of thing - one day maybe I'll tell you about the time I implemented a lossy networks algorithm from a PhD thesis!).

I've got it sort of working. Here's a "naive" implementation with no clever algorithms (btw, the numbers at the top are frame-rate and number-of-triangles respectively):





Here's a couple of images at two different levels of detail. The algorithm is building a triangle strip dynamically (you can see the arrangement of the vertices is different to the picture above - that's because it's a quadtree in the algorithm, which leads to a different layout).









Now we get to the next point where the algorithm determines which vertices to include, and builds a (potentially complex) triangle strip:




Then I tried to implement the view fustrum culling part ... it isn't quite working:





I may pursue this further if I have some energy, but I think it's probably not the right route to go for a game anyway ... this algorithm runs every frame, regenerating a fresh triangle strip each time, which is probably overkill for a standard game. I'm going to explore some other options next, I think ... watch this space!