Friday, 6 April 2007

Fish!

***Update 2*****

Thanks to Ziggy for spotting (and more importantly, solving!) the graphical artifact problem he was seeing. Source code and the installer has been updated with the new version, although it should be noted the changing renderstate (the solution involves turning the depthbuffer off during the water pass, then re-enabling it) within the draw loop may cause a minor performance hit, but not worth worrying about for now.

On a side note, I personally own 5 PC's of different ages/configurations. With close friends, I have easy access to maybe a dozen more.

And not one of them has an ATI graphics card. Could constitute a blind spot in my testing plan :)


*** Update ***

I've since wrapped all this up into an installer - FishInstaller.zip. It will install the .NET 2.0 Framework (if you don't already have it) and the XNA runtime, but you will still need a very recent version of directX 9.0c (December 2006 or later), as it has updated libraries that XNA requires. So if you can't get the demo to work, try updating your directX version - that's the likely problem. Apologies for that, no real way around it for now. Rumour has it that MS are currently working on a distribution technology to make this all a bit easier.

Here's the latest version of DirectX if required.
The latest DirectX 9.0c release. (45Mb)

***************

This is a little demo I wrote using Microsoft's recently release XNA framework. XNA is the spiritual successor to managed DirectX, essentially wrapping up directX and hiding some of the nastier elements from the novice coder, as well as providing a lot of useful functionality that's common to most games.

To run the demo, you'll need:

- A PC that meets the XNA framework requirements (the pertinent one being a graphics card that supports DirectX 9.0c and shader model 2.0 , which is pretty much everything from a Geforce 6 onwards).


Instructions
  • The demo begins with a simple splash screen, after the fish have demonstrated their literary skills you can proceed by pressing the Space bar.
  • The main demo is a simple enough sandbox, demonstrating real-time flocking behaviour based on Craig Reynold's classic flocking model. You have three constituent behaviours - cohesion (the force that attracts fish to each other), separation (the opposite), and alignment (the force that keeps them pointing in a similiar direction).
  • All the behaviours begin toggled off. The water effect begins toggled on.
  • Left mouse button spawns fish, right mouse button spawns obstacles (I know they're not particularly nautical, but I'm no artist as we can all see - pause it and zoom in on the fish if you don't believe me...)
  • You can change the strength of the constituent behaviours and observe the effects.
  • Arrow keys move the camera (top down, RTS-style), mouse scroll to zoom in and out.

Things to note

  • Classic flocking is computationally expensive (On^2), but there's a few tricks to get that down. A cell-space partitioning system is used here, so each fish only flocks with the fish in the surrounding few grid cells. Without such optimisation, this algorithm brings even a very powerful CPU to its knees very quickly - at around 130 fish on a E6600 dual core. With cell-space partitioning we can raise that several fold (depending on your CPU speed).
  • There's no actual collision penetration constraint here, only collision avoidance by the fish themselves. So you will see cornered fish clip through obstacles occasionally if the combined forces compel them to.
  • The water refraction effect is achieved by drawing the scene to a render target, applying this to a texture, and then perturbing and displaying this texture on a disc model that is placed between the scene and the viewer. Based on the 'refraction' effect found in Rendermonkey, if you're interested.

Finally, if you want the full source and all the trimmings - RainbowFishSource. The whole thing is really an offshoot of a simple game engine a friend and I are writing together. Hopefully should have some more to show in the coming weeks and months. Oh, and thanks to Gary Kacmarcik for his XNAExtras bitmap font code, a big time saver.

13 comments:

Zygote said...

Looks like the shadows are drawn on top of the fish for me.

Thanks,
Ziggy
Ziggyware XNA News and Tutorials

Dissimilitude said...

You've certainly got your finger on the pulse! I barely posted this an hour ago :)

I'm not using any shadows at all - the fish do have a black edge, but that's just the model texture. Some of them end up swimming along on their sides or back, is that what you're seeing?

Zygote said...

It appears the fish have a black square on top of them like the alpha is incorrect on the edge shadow. I am at work right now otherwise i would show a screenshot. :)

Ziggy
Ziggyware XNA News and tutorials

Dissimilitude said...

That's odd. It's been fine on the 5 PCs I've tried it on so far.

Anything unusual in your work setup? Again, I'm not using shadows or shadow maps of any kind, so whatever you're seeing, it's not a shadow.

If you could post a screenshot when/if you get a chance, I'd be tremendously grateful. I didn't quite think it was ready for showing yet, so I deliberately didn't advertise its presence. I didn't calculate on sneaky XNA-sniffing RSS feeders, however!

Dissimilitude said...

What graphics card does the PC you're viewing on use?

Zygote said...

I have an ATI Radeon 1600. The problem might be due to using non pow-2 textures. I'll check out the code when i get home and see whats going on as well as send you a screenshot. If its happening to me then it will surely happen to someone else.

Thanks,
Ziggy
Ziggyware XNA News and Tutorials

Dissimilitude said...

I'd really appreciate that - every other PC I've tested it on has had an NVIDIA graphics card, come to think of it...

Most of the pertinent code is in the VehicleManager component, in the Managers folder.

Zygote said...

It works fine on my pc here at work using some intel Piece of junk :) I'd bet money that the issue is from using non pow-2 textures. For some reason ATI is too lazy to add support for this.

Thanks,
Ziggy
Ziggyware XNA News and Tutorials

Dissimilitude said...

I just double checked - all my textures are definitely power of 2. Hmm. Confusion reigns :)

Zygote said...

i found the problem.

Within VehicleManager.cs you need to add the following:

if (waterToggle == true)
{
GraphicsDevice.RenderState.DepthBufferEnable = false;


...


GraphicsDevice.RenderState.DepthBufferEnable = true;
}


This resolves the black from appearing.

Thanks,
Ziggy

Ziggyware XNA News and Tutorials

Dissimilitude said...

Thanks Ziggy, well spotted! Very much appreciated.

Data said...

still need an ATI card for testing ?
i have several available... from X1900 to 9600, also some Mobility radeons ... so if you'd like to test it, drop me a, i can test it for you (or my friends can)

Miguel said...

Hi Nick,

I would like to take a look at the source of this Fish sample to learn some of the techniques that you have mastered. (The original links are broken). Can you post it somewhere else or email it to me?

Thank you in advance.