The Blog

[Progress Update] Shadows

The last progress I posted that included screenshots was when I added textures.  That was a few months ago.  While I have not had much to report since then, I have been no lazy bum.  There were many advancements, but I wanted to wait until I had shadows before I posted anything major.

I am pleased to present you with some eye candy.

So what are you seeing here?

  1. My own variant of percentage-closer soft shadows.
  2. Anisotropic mipmap filtering.
  3. Kaiser mipmap filters.
  4. Linear-space color blending.
  5. Sorted render queues.
  6. Normal mapping.
  7. Hemisphere lighting.
  8. Automatic offline conversion from bump maps to normal maps (the Spitfire’s normal mapping was originally a bump map).
  9. Fresnel translucency.  Notice how the glass becomes less see-through at steep angles away from the camera in the last image.
  10. Phong shading.
Now you can see why there was so much time since my last major update.  Things I also added, but that can’t be seen here are:
  1. Model instances.
  2. Concept of a game world and a scene manager.
  3. Input handlers (mouse and keyboard).
  4. A camera (was previously just some hard-coded matrices).
  5. Automatic resizing of textures that do not meet the requirements of the hardware (non-square, too big, etc.) using high-quality Kaiser filters.  I imagine most of my time was spent on the image filterer, which also supports many other kinds of filters.
  6. Resource sharing.  Duplicate textures not allowed!
  7. Frustum culling.

Although there was a lot of set-up, I only spent a day on the actual shadow-mapping algorithm, which is my own variant of PCSS.  Hard to tell from the pictures but they do get harder nearer to the source.  So there is still a lot of work to do to make them pretty, but I think they look good enough for an update post.

Once I get the default shadows looking nicer and faster, I will implement a new form of shadows that I have invented to handle multiple layers of colored shadows.  When that is complete I will release a white paper explaining how it works.  It isn’t much extra work on top of existing colored shadow-mapping algorithms, and it can be applied to all of them, so I am expecting to see it used widely in future game engines.

A word about my fresnel effect shown in all images, but most noticeable in the last image.  A correct fresnel implementation can be found here:

That is quite a long equation!  I created a simpler approximation that yields decent results (see last image) that is much more efficient.  My equation simply reduces to this:

_vOutColor.w *= (((1.0f / abs( dot(, vNormalizedNormal ) )) - 1.0f) * 0.25f) + 1.0f;
_vOutColor.w = min( _vOutColor.w, 1.0f );

0.25 is the fresnel term, which I temporarily hardcoded but will make it adjustable soon.  You can use this to create more efficient approximations of fresnel terms in your own code.


L. Spiro

About L. Spiro

L. Spiro is a professional actor, programmer, and artist, with a bit of dabbling in music. || [Senior Core Tech Engineer]/[Motion Capture] at Deep Silver Dambuster Studios on: * Homefront: The Revolution * UNANNOUNCED || [Senior Graphics Programmer]/[Motion Capture] at Square Enix on: * Luminous Studio engine * Final Fantasy XV || [R&D Programmer] at tri-Ace on: * Phantasy Star Nova * Star Ocean: Integrity and Faithlessness * Silent Scope: Bone Eater * Danball Senki W || [Programmer] on: * Leisure Suit Larry: Beach Volley * Ghost Recon 2 Online * HOT PXL * 187 Ride or Die * Ready Steady Cook * Tennis Elbow || L. Spiro is currently a GPU performance engineer at Apple Inc. || Hyper-realism (pencil & paper): || Music (live-played classical piano, remixes, and original compositions):

No comments yet.

Leave a Comment

Remember to play nicely folks, nobody likes a troll.