XNAInfo blogs
Ramblings about XNA, .NET and stuff

Foucault's Pendulum

January 26, 2011 07:07 by Rim

   
It's getting close to another year since my last blog post, so for anyone still out there I thought I'd put up this little video of a pet project I've been tinkering on. It simulates how Foucault's Pendulum behaves at various latitudes. In case you're wondering what on earth Foucault's Pendulum is -and if you'd actually want to know- you can find more information over here and this here book provides a well-written history on the subject. The short and sweet is that this Pendulum device demonstrates that the earth rotates, which is a pretty neat feat. To get on with the imagery, here's that video:

I'm still tinkering on XNA3.1 so I won't bother you with the hideous source. I'm really not up to speed on the more recent XNA developments, so I have no clue if there's any need out there for another rant on how hard spheres are to texture correctly, or some info on how to paint on your meshes like the pendulum is doing. If there is however, drop me a line and I'll try to put together a tutorial explaining the technique (could be a good reason to finally upgrade to XNA4). And it might be nice to have some fresh content on the site again :)


Stuff abound

March 11, 2010 02:40 by Rim

There seem to be a lot of exciting things happening at the moment. XNA 4.0 has been announced which adds Windows Mobile 7 phones to the list of supported platforms, but you already knew that of course. While Shawn is busy at GDC, I took the liberty of stealing his Fractals code. It doesn't improve anything upon his release in 2006, but I happened upon it and I thought I'd be nice to have this available as a ready-to-run sample. On that page you'll also find my take at handling input (inspired by this discussion) which seems to be all the rage these days.

Other than that, I've started tinkering on a little animation pipeline for XNA together with a 3D artist as a learning experience. I have no idea if this will be anywhere near finished any time soon, or if it'd even be useful for the community since there seem to be a lot of libraries out there already. Like any good software project I settled on an acronym for the name anyway before its anywhere near done, so I lay claim to Uxmal. It's a good fit since the artist is working in Maya and I'm on my third rewrite of the codebase already. Xna Model Animation Library also fits, but my development efforts are currently stumped by trying to come up with what the U should mean. Useful would be ideal, but it might also be Unnecessary or Useless.

Time will tell :)


Tags:
Categories: Frontpage | Ramblings | XNA
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Detour Ahead

February 24, 2010 10:01 by Rim

  
I really gotta stop doing things like this. What started out as a Soft Body Physics demo ended up in writing a barebones GPGPU library, which ended up in writing a stand-alone GPU-particle demo for release on XnaInfo (coming soon!), which ended up in a little black hole:


 

I hope to find some time for the write-ups and posting code soon, please bear with me :)


Tags:
Categories: Ramblings | XNA
Actions: E-mail | Permalink | Comments (3) | Comment RSSRSS comment feed

Soft body physics

February 21, 2010 09:35 by Rim


I've been working on a soft body physics demo (more details). I haven't had time to write up more about it to post here, but I wanted to try to see if posting YouTube videos works on this infernal blog software. Stay tuned for more on this :)


Tags:
Categories: Graphics | Ramblings | XNA
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Pet Project - StickFight

May 12, 2009 16:38 by Rim

I haven't gotten around to writing interesting samples or uncovering any deep XNA truths lately. Instead I've been tinkering on a little beat-em-up game with stylized stick men to do the fighting. These little actors are entirely procedural, so the game itself generates the geometry and animations rather than using models created by artists. Obviously nothing can replace a good artist and this proved painfully true when it came to the animations.

The animations are generated by a particle-based physics system (described here), which works by applying force to the attacking limb towards the victim, checking collisions and letting the simulation run its course. The base skeleton displayed below is set up easily enough, but without additional contraints the resulting movements are far from natural. As noted in the original article, a lot of tweaking can also be done using the mass of particles to get some control over how easily particles (i.e. joints) can move.

So if the skeleton and animations are that hard to tweak, you might be wondering what good this procedural technique is then. The beauty of this -admittedly simple- physics based rendering setup is that you essentially get inverse kinematics for free. If I want to hit my opponent with a hand, I just apply some force on the hand towards where I want to hit him. With sufficient tweaking, this produces convincing animations for accurately hitting the victim anywhere with any part of the attacking actor. Headbutts, kicks and more exotic attacks are just a matter of picking target and subject particles on either side.

Another nice benefit of this procedural approach is that the geometry is very accessibly to the program and thus can be altered in a variety of ways. With a few minutes of tinkering, style variations like those below are easily implemented.

The project is still a pretty long way off from becoming a playable game, but it's already made its way around the office for passive-aggressive stress relief   I'm afraid I can't put a playable build out anytime soon, but in the meantime here's a little movie (WMV, 7mb) showing some basic pummeling and the style so far. Since a lot of tweaking is involved and much of the style is still up in the air, comments and/or suggestions would be much appreciated.


How I Saved 3ms By Unrolling A Loop

September 25, 2008 10:05 by MJP
Last night I decided to sit down and do some nitty gritty optimization on the 60 version of my game.  The PC version has been running great even when I crank up every setting I have (although that might have something to do with the 4870 I just bought), but as well all know by now things are never so easy on the Xbox.  For the past few weeks I'd been struggling to keep the framerate above 60Hz, with it slipping down to 55Hz during complex scenes.  Now 55fps wouldn't be so much of a problem if I weren't the kinda guy who hates screen tearing, but it just so happens I am.  Which means I want VSYNC to be enabled, which means the game drops to 30fps whenever it's below 60.  Definitely unacceptable.  For a while I avoided the problem by doing the unthinkable...I dropped the resolution from 1280 x 720 to 1024 x 600.  I even considered leaving it this way for the final release...I mean if Halo 3 and Metal Gear Solid 4 can do it, why can't I? 

But no, I'm too finicky to settle with the lowered resolution.  It just looks so much better in 720p!  So I cranked the res back up, and decided to see where I could squeeze out some extra performance.  Naturally, the first place I went to was my show mapping shader.  I already knew this particular shader was giving me trouble, since I'd discovered that decreasing the size of the buffer that I render the shadow occlusion to (since I do a deferred shadowing pass) resulted in significant performance gains.  I'd already reduced thigns to 4 PCF samples on the 360 (did I mention I ditched VSM for the 360?  Performance and precision ended up being so awful it wasn't worth it) so I couldn't squeeze that down anymore.  At this point my eyes drifted down to little loop I had for determining which split of shadow map cascade to use, when I remembered an excellent presentation on shader performance that I'd read a long time ago. One of the things mentioned in there was that unrolling loops can have a significant impact on general purpose register usage, ALU usage, and shader compiler optimization.  So I thought, "hey, let's try unrolling this loop and flattening this branch".  I then changed my code from this:

for (int i = 1; i < NUM_SPLITS; i++)
{
    if (vPositionVS.z <= g_vClipPlanes[i].x && vPositionVS.z > g_vClipPlanes[i].y)
    {
        matLightViewProj = g_matLightViewProj[i];
        fOffset = i / (float)NUM_SPLITS;           
    }
}  


to this:

[unroll(NUM_SPLITS)]
for (int i = 1; i < NUM_SPLITS; i++)
{
    [flatten]
    if (vPositionVS.z <= g_vClipPlanes[i].x && vPositionVS.z > g_vClipPlanes[i].y)
    {
        matLightViewProj = g_matLightViewProj[i];
        fOffset = i / (float)NUM_SPLITS;           
    }
}  
      

I ran the game again, and BAM:  I shot up from 55fps to 65fps!  Huge difference!  I was very impressed with myself.  Moral of the story:  experiement with stuff, and make sure you profile it!

Today I decided to read through some other presentations to see what other useful bits I could find. This one from Gamefest 2007 pointed out that vfetch's should be aligned to 32-bytes on the 360.  I did the math on the vertex declaration used for most of my models, and found out it's 48 bytes.  Later tonight I'll have to see if I can squeeze it down to 32, and see if it makes performance any better. 

I also came across this one from Gamefest 2008, which is all about how texture and surface formats are handled on the 360.  This gave me some insight into some problems I'd come across already.  For example, R32G32F (Vector2) isn't actually a format the GPU can render to!  Apparently it renders to R16G16F, and then just expands it upon resolve from eDRAM.  This explained why my VSM's with exponential warp were have such precision problems.  Another thing pointed out in there is that the 360's texture units filter fp16 at 1/4 the rate of INT8!  This would help explain why my VSM performance was so poor.  Definitely good things to keep in mind.

-MJP

XNA on the Xbox 360, Part 3: General Practices

August 28, 2008 08:55 by MJP

Over at gamedev.net someone had asked for some general performance pointers regarding using XNA on the 360.  After giving a bullet-point list of what I thought were the important issues I thought to myself "Hey, that was pretty good.  Let's milk it for all it's worth!"  And therefore I've copied and pasted them all here in glorious display of laziness.  Laughing

 

-The 360 has 512MB of unified memory, which means it's shared by both the CPU and the GPU. You don't have all of that available to you, since some of it is taken up by the console's "OS" and some will also be taken up by the .NET Compact Framework.  You'll also be working from the managed heap, rather than directly working with native memory.

-You can only execute pure managed code on the 360.  You can't, for example, P/Invoke into a non-managed DLL. 

-As far as GPU shaders go, you're pretty unrestricted.  You can use SM3.0 HLSL, or you can also write portions of your shaders in the GPU's native microcode.  This is really very nice...it lets you do things like un-normalized texture addressing, full texturing capabilities in the vertex shader, or directly fetching an element from a vertex stream.  The microcode set is referred to as xvs_3_0 and xps_3_0. 

-The 360's GPU is different from your average PC GPU in that it has an eDRAM framebuffer.  The eDRAM is 10MB in size, and has tremendous bandwidth (256GB/s).  What this means is that writing out to the framebuffer or reading it back for blending is very very quick.  Multi-sampling is also very quick, since again you don't have the bandwidth problem.  In fact MSAA would be "free" if it weren't for tiled rendering...you see the downside of eDRAM is that if your render-target + z-buffer is too big to fit in eDRAM, you have to render to it in tiles.  This means you render one portion of the target, then another.  This isn't so bad, except for the fact that any geometry that's on the edges of 2 tiles has to be drawn twice.  If you're not doing scenes with hugely complex geometry you probably won't even notice tiling (it happens automatically).  To figure out whether you're going to tile you need to count the amount of bytes per pixel and then multiply by resolution.  So for example if you're rendering to the Color format which is 4 bytes per pixel and you're using Depth24Stencil8 which is also 4 bytes per pixel, you have 8 bytes per pixel total.  When multi-sampling, you multiply this amount by the number of samples (so 4xMSAA would by 32 bytes per pixel).  1280 x 720 with 4xMSAA would be ~28MB, so you'd need 3 tiles.

-Be prepared to get CPU-bound really quick if you're doing anything non-trivial.  DrawPrimitive calls are extremely expensive on the 360...I've seen my framerate go from about 70 to 30 just from going from 24 DP calls to 34.  Instancing is a must if you need to draw a lot of meshes...there's a good sample on the CC website.  By the same token if you're doing any really fancy logic on the CPU that's not graphics-related, you'll probably need to run it on another thread on a different core since your main thread can get bogged down pretty quick.

-Watch out for performance pitfalls with the .NET Compact Framework.  Things like Garbage Collection compaction and virtual function calls are much more expensive than they are on the PC.  I suggest reading this blog for tips.  Just remember to keep your live object count as low as possible, and you should be okay.

-Floating-point performance is not so great on the 360 CPU.  Most of the fp power is in the vector units, but you have no access to those through XNA. 

-Avoid the surface formats that are larger than 32bpp.  Mainly HalfVector4 and Vector2.  Their performance is generally pretty terrible, and I've run into all kinds of driver bugs with them.  This means you can't do HDR in straightforward way, but there are other options.  There's an entry on my XNA blog where I talk about how I got around it.

-Watch your texture sampling bandwidth.  Framebuffer access may be quick, but reads from textures are limited by the 22.1GB/s read bandwidth.  This may be quite a bit less than what you're used to, if you're prototyping on a higher-end card like an 8800.  This can be especially painful in scenarios where you want to take multiple samples per pixel, like PCF for shadow maps or SSAO. 

-Prototyping and developing on the PC is a good idea since you have access to PIX, but make sure you test pretty often on the 360.   You may need to optimize for quite few scenarios if you need to keep the framerate up.  


Tags:
Categories: XNA
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

XNA On The 360, Part 1: Shadows

August 8, 2008 14:57 by MJP

As get deeper into my current project, which happens to be 3D vehicle-based platformer/racer loosely based on the old DOS game Skyroads, I find myself spending more and more time grappling with various headaches that come up on the 360 version.  So I've decided I'm going to share some of trials and tribulations, so that maybe some people learn from them (and also so I can just plain vent about them!). 

One of the early goals I set for myself when starting the project was that I wanted to make some use of modern graphics techniques, and really try to squeeze some performance out of both the 360 and PC GPU's.  This meant some decent shaders, HDR, 4xMSAA 1280 x 720 @ 60fps, and of a good shadowing implementation.  Shadows are a topic that I keep near and dear to my heart, so I'm going to talk about them in my first entry.

When first planning out my renderer, I came up with the following choices for my shadow implementation:

  • Stencil shadows
    +Pixel-perfect shadows, no resolution issues
    -Requires multi-pass for any lights needing shadows
    -Hard edges are ugly!
    -Softening is very expensive
    -Tied to geometric complexity
    -Not really any active research on the subject...even Carmack ditched them
  • Shadow maps, with standard PCF
    +Very commonly used, lot's of known optimizations
    +Can soften edges and give good filtering when enough samples are used
    +Can be used with an R32F texture, which gives good precision
    -No hardware filtering
    -PCF samples are incredibly expensive on the 360, which has very limited bandwidth
    -Biasing artifacts are very common
  • Variance Shadow Maps
    +Can use hardware filtering
    +Can be used with multi-sampling, which is "free" on the 360
    +Can be pre-filtered, for example with seperable gaussian blur
    -Very precision-hungry, in most cases R32G32F is needed (which doubles bandwidth per read)
    -Light bleeding
Ultimately I decide to go with VSM's first, and then try other approaches later.  VSM is capable of producing some tremendously good-looking shadows thanks when anisotropic filtering and a gaussian blur are used.  Plus being able to enable MSAA very cheaply on the 360 made it seem like a very good fit for the hardware, especially considering how expensive PCF can be.  I remember seeing Wolf mention that he was limited to 6 or so PCF taps on the consoles...IMO that's not enough to produce high-quality shadows in many situations.  Later on I confirmed this:  using higher numbers of samples (16, 25) was enough to bring my framerate crashing down on the 360.  VSM has not been without it's headaches though...the anti-aliasing may be cheap but the blurring sure isn't.  Even using a blur with just 9 taps is enough to cause quite a noticable framerate drop, which unfortunate considering the improvement in quality it brings. 

One trick I've found to be quite effective on the 360 is deferred shadow maps.  The technique is one I first saw mentioned by nAo over on the beyond3d forums, and it involves rendering the results of a shadow-map comparison to a texture in a seperate pass before doing the full lighting pass.  It basically works like this:

-Have all geometry render linear depth to a screen-sized texture
-Render the shadow-map
-In a full-screen pass: sample depth from the depth texture, reconstruct view space, convert to light-space, and compare depth with the shadow-map
-Use the shadow occlusion texture to attenuate lighting in the actual main pass

The reason it's a win performance-wise, is because when you perform a full-screen pass you ensure that every quad of pixels is fully utilized.  This isn't the case when you're rendering a bunch of 3D geometry, since the triangles often won't overlap all 4 pixels of a quad.  It's all very nice from a pure design standpoint:  your shadowing is completely decoupled from your lighting.  Your fancy normal-mapping or sub-surface scattering don't need to be aware at all of what shadowing method you're using, it just needs to sample the final attenuation value from a texture.  Plus you don't need to have two versions of those shaders:  if shadows are disabled, you can just feed the lighting shaders a 1x1 white texture.  Having a depth texture available also usually isn't a big deal, since pretty much every modern engine needs depth for just about every friggin' effect. 

As of now with this shadowing system in place, I have everything running at a little over 60 fps with a 1024 x 1024 shadow map being rendering with 4xMSAA.  In order to keep my framerate high enough to remain at a steady 60fps with vsync, I'm defintely going to need to find some more optimizations and the shadowing system is certainly somewhere I'm going to come back to.  However at the moment, I'm quite satisfied with the results.  Laughing




Tags:
Categories: Ramblings | XNA
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

DirectX FAQ

August 6, 2008 03:23 by Rim

 

Since the stuff I'm working on for XNAInfo is taking forever to finish, I thought I'd post a link to this little gem here in the meantime. On my forum rounds I find myself linking to Tom's Excellent DirectX Faq at least once a week. Obviously it's DirectX specific, but that easily translates to tons of useful information on XNA development on Windows. It's a great resource that should prove useful for just about anyone.

 


Tags:
Categories: Ramblings | XNA
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

WebBrowser control on XNA texture

July 28, 2008 22:19 by Rim

(Sorry if this pops up twice in your RSS reader, something was off with the publishing) 

Some time ago a topic popped up on GameDev on how to stick a WebBrowser control on a D3D surface, or rather an XNA texture level. After some tinkering we got it to work (obviously Windows only), so it can be used to render any webpage to an XNA texture. The next step was to try and make it interactive, paving the way for HTML and Flash based GUIs. Unfortunately we ran into a strange bug here, which I haven't been able to solve. So I figured I'd post this out here, hoping anyone comes across this who can help out.

Here are the (messy) demo projects:

The bug surfaces in the 2nd project. Basically it works fine until the user left-clicks anywhere on the control (doesn't have to be a link), after which WebBrowser.DrawToBitmap fails silently and only an empty white bitmap gets rendered. The strange thing is that the WebBrowser control does load the new webpage. By uncommenting line 241, mouse moves are posted to the control and the window title will show the HREF of links on the (loaded but invisible) page as you hover over them.

Anyway, perhaps someone better versed in window messages can check this out, see if the code for posting mouse presses/releases is correct. While researching this problem, I also came across this MSDN page which states DrawToBitmap isn't supported for the WebBrowser control anyway, so it seems a miracle it works in the first place. If anyone cares to comment on that, please let's hear it.