XNA Masking Mayhem
- by TropicalFlesh
I'd like to start by mentioning that I'm just an amateur programmer of the past 2 years with no formal training and know very little about maximizing the potential of graphics hardware. I can write shaders and manipulate a multi-layered drawing environment, but I've basically stuck to minimalist pixel shaders.
I'm working on putting dynamic point light shadows in my 2d sidescroller, and have had it working to a reasonable degree. Just chucking it in without working on serious optimizations outside of basic culling, I can get 50 lights or so onscreen at once and still hover around 100 fps.
The only issue is that I'm on a very high end machine and would like to target the game at as many platforms I can, low and high end. The way I'm doing shadows involves a lot of masking before I can finally draw the light to my light layer.
Basically, my technique to achieveing such shadows is as follows.
See pics in this album
http://imgur.com/a/m2fWw#0
The dark gray represents the background tiles, the light gray represents the foreground tiles, and the yellow represents the shadow-emitting foreground tile.
I'll draw the light using a radial gradient and a color of choice
I'll then exclude light from the mask by drawing some geometry extending through the tile from my point light. I actually don't mask the light yet at this point, but I'm just illustrating the technique in this image
Finally, I'll re-include the foreground layer in my mask, as I only want shadows to collect on the background layer and finally multiply the light with it's mask to the light layer
My question is simple -
How can I go about reducing the amount of render target switches I need to do to achieve the following:
a. Draw mask to exclude shadows from the foreground to it's own target once per frame
b. For each light that emits shadows,
-Begin light mask as full white
-Render shadow geometry as transparent with an opaque blendmode to eliminate shadowed areas from the mask
-Render foreground mask back over the light mask to reintroduce light to the foreground
c. Multiply light texture with it's individual mask to the main light layer.