After talking about scaling effort and pruning features some of you may be wondering how that should work. Many features seem to follow Boolean logic: either they are there or they are not. The counterpart to this binary logic is Fuzzy logic. According to this metaphor the availability of features is no longer black and white. They have endless shades of grey now.

This article shows how I've implemented drop shadows in Nordenfelt along the greyscale palette.

Black to Light Grey

During the last two weeks I've added drop shadows in Nordenfelt. Version 0.3 did not have them and therefore looked a little flat:

shadow_v0_small

Usually my initial vision of a new feature is tending straight up to the perfect solution. I just want to make it right. That's nice but also very, very dangerous if you can't control this desire.

According to this kink my first idea of the shadows were precise and semi-transparent shapes, blurred according to the flight height:

perfect_shadow_concept

The complexity of such highly detailed shadows was obvious. Therefore I decided to implement the absolute minimum I could come up with. Scaling back a perfect vision in your head is quite hard. None of those narrow solutions can prove itself worthy. You have to be strong here and cut it down.

The first draft had just simple shadow spots. Each of them had the same radius and offset:

shadow_v1_small

The implementation of this first step took eight hours. The main gain was a running "demo" with shadows. Even in this simple form they gave the playing field more depth.

The next step was shaping the shadows according to their sprite forms. The simplest solution here was rendering the physical boundary - consisting of circles - the same way as the former spots:

shadow_v2_small

Ugh! That looks ugly. The problem is that the boundary can have any shape independent from its sprite. The best example in the screenshot above is the player's shadow. The hit "box" is very small because it's reduced to the cockpit. That's a step back in quality. Six hours wasted.

The third and last version has exact drop shadows. They are merely the sprites itself, colored in black and rendered semi-transparent:

shadow_v3_small

After seven hours of work I ticked flying objects cast shadows off on the top sheet of my todo list stack. Now the shadows have acceptable quality. If there is time left polish may include blurring the shadows or calculating transparency using the flight heights.

For now I'm happy with it.

Lessons Learned

The lessons I've learned from this:

  • let features grow from usable over releasable to polished
  • in most cases there is a simpler solution for your idea (spots in this example)
  • not each step is an improvement

The last insight was surprising. Some improvement steps may prove themselves as bumps in the quality graph:

quality_over_time

Sometimes it gets worse before it gets better.

 

Cheers,
Thomas

 

Comments  

 
#1 2011-01-12 05:10
Looks like you have managed to solve to "shadows do not add" problem. I guess the smoke-trail of the kamikaze-drones is kind-of a particle system, and the particles overlap. A naive solution would lead to shadows that are too dark where the graphics overlap. So how did you do it? Do you use the alpha-channel or stencil buffer? A full-screen render-texture to "accumulate shadows" before rendering them to the back buffer all at once? A per-object render-texture?

I think the best solution in terms of visual quality would be a full screen render-texture. OTOH that might be overkill, since it will bump up your overdraw-factor +1 for the whole image :(
Quote
 
 
#2 2011-01-12 17:06
The exhaust fumes of the kamikaze planes are part of the sprites itself:



As mentioned above the shadows are the enemy sprites themselves, colored black and rendered semi-transparent onto the ground. This is why the fumes have shadows.

This version has a drawback with overlapping objects, as you already pointed out:


full size: www.blackgolem.com/.../shadow_multiplication.jpg

Render-textures came to my mind but my graphics engine does not support them. Their implementation will take some more time I don't want to invest at the moment.
Quote
 
 
#3 2011-01-12 18:44
this calls for an easter egg like a "shadow gun", which itself is invisible, only its shadow. also it shoots shadow bullets!
Quote
 
 
#4 2011-01-12 18:50
Quoting tehlexx:
this calls for an easter egg like a "shadow gun", which itself is invisible, only its shadow. also it shoots shadow bullets!


Nice one! Further ideas start creeping into my mind.
Quote
 

Add comment


Security code
Refresh