Sunday, October 21, 2012

Cascaded Variance Shadow Maps

Previously on Devblog.Drheinous.com...

Heh.  Anyway, previously I'd talked about cascaded shadow maps and how they worked.  As I said implementing them was easy as Neil Knight had done most of the hard work.  The quality still wasn't quite good enough for the voxel terrain my engine could push. I could easily draw a lot of terrain and have the far clip plane way out, but as it got bigger the quality of the shadows suffered.  CSM mostly fixed it, but still left some aliasing mostly due to self-shadowing.  Here's a good example from the GPU Gems chapter on the subject:

Another problem with percentage-closer filtering is that it inherits, and indeed exacerbates, the classic nuisances of shadow mapping: "shadow acne" and biasing. The most difficult to solve biasing issues are caused by shadow-map texels that cover large ranges of depths. This scenario often results from polygons that are almost parallel to the light direction, as shown in Figure 8-3.

08fig03.jpg
This would be Figure 8-3, GPU Gems 3 illustration of shadow mapping artifacts.

Cascaded Shadow Maps

So I've done quite a bit more work on shadowing. Clearly as the previous post illustrated, ordinary shadow maps weren't good enough for large terrain. After a bit of looking around, it seemed that Cascaded Shadow Maps were the ideal, and commonly used solution. Project Vanquish even had an implementation, and it worked right off the bat (well, there were a few minor changes I made, but very minor indeed).

Sunday, August 5, 2012

Shadows

Well, I got the Project Vanquish shadowing to work right with the instanced trees.  It'd had been more or less working with the terrain.  Turns out the problem, as I thought, was in the shadow map, or lack of resolution there of... 

On XNA and UIs

HTML UI using Awesomium in XNA
A couple of years ago, while working on my old 'Settler' project, I looked around at the state of user interfaces available in XNA, having little interest in writing the nuts and bolts of my own.

There really wasn't that much, a lot of half working and abandoned projects. Some nice things in C, but my preferred working environment was C#. 

Wanting something a bit more useful in a complicated RPG than a simple shooter style interface, I eventually downloaded a trial of the DigitalRune UI library and fiddled with that.  It worked ok... but come a year or two later when I go back to look at my project the trial key has expired, so now I can't run my old code without either getting a new key or hacking out all the UI stuff.

I decided I wasn't going down that road again, so now I was looking for a better way to do a UI.

Tuesday, July 31, 2012

Hardware Instancing with Texture Atlases

I don't know why this sprang to mind... Dr. Frank-N-Furter: "He carries the Charles Atlas seal of approval."

Atlas texture.... without atlasing!  This should be one tree.
I've accomplished one last thing with the trees and instancing (I just got back from a week long business trip, can't you tell I've had all these ideas pent up?).

Having only one sort of tree at a time was a bit limiting, so I decided to try my hand at adding a bit of texture atlas functionality to my instancing.  Never tried it before, but in theory it is pretty simple.

There was always a single texture passed in to the class that set up the instancing, now it can be an atlas instead of just an ordinary texture.

Well, it could have before, it just would have been silly as you can see above.


Yet More Trees!

So, I more or less ditched LTrees and bought a set of tree models off TurboSquid.  The models themselves aren't much, just three quads arranged in a star pattern.  But the textures are nice, so they look ok, and are very low poly, of course.

Meanwhile, I looked into a newer version of Project Vanquish, and noted I was doing depth calculations a hair different.  I changed the format of the GBuffer render targets to SurfaceFormat.Rgba64 from Color/Color/Single, to allow alpha blending (another thing I picked up from the newer versions of PV).    But, that caused what looked to be clipping in the depth output at very close ranges.  I was doing:

Output.Depth = Output.Position.z/Output.Position.w;

....in the vertex shader, and passing the depth as a float to the pixel shader.  In Project Vanquish it passed the location to the pixel shader, then did the division there, where it was then assigned to the output.  I think this must have resulted in increase precision.

That change seems to have improved the precision of the depth output.  As well as getting rid of the clipping, shadows look a bit better, as you can see above.  Though they still aren't quite right.

LTrees, Instanced

So, it wasn't terribly hard to get instancing working with LTrees, at least the trunks.  I basically used the instancing code I had before, but rather than passing it a Model object, I made it able to accept a VertexBuffer and IndexBuffer combo (which it would get anyway by extracting from the model).  I haven't fiddled with the leaf clouds yet.  I may not, I may move on to set tree models where I can fully control the level of detail, and have billboard imposters at low LOD.

At any rate, it works pretty well.    This is a 3x3 chunk of terrain (32x32x64 sized chunks), so this is drawing more than 9000 trees (simply set now to about 1 per cell), all at full detail and still managing ~ 30 fps.  That's without any real optimization.

The shadows aren't working quite correctly with instanced item though.  Dunno if I will worry about that for the time being.

I did pull some updates from the newer versions of Project Vanquish.  I need to sit down and figure out if I've done something to mess up the shadows...