We’re in the process of creating an iPhone game using cocos2d. We’re trying to layer several sprites on top of each other and have them cast shadows.
Right now the shadows are rendered as sprites which works fine for the most part. But we only want the shadows to hit the closest layer.
I’ve made an image that hopefully explains what we’re trying to accomplish:

And here’s what we have at the moment:

Basically we want the sprite to only render the part of the shadow that is at the same depth as the z-buffer.
We’ve played around with glDepthFunc and GL_DEPTH_TEST but nothing seems to work.
Here’s how we’re rendering the shadow sprite (subclassed CCSprite):
- (void)draw {
glDisable( GL_BLEND );
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LESS );
glDepthMask( GL_FALSE );
[super draw];
glDepthMask( GL_TRUE );
glDisable( GL_DEPTH_TEST );
glEnable( GL_BLEND );
}
The GL_BLEND calls are only there so we can see the sprite at all times.
All sprites that aren’t shadows use glDepthMask( GL_TRUE ) and we’re clearing the depth buffer on each frame.
Any help would be much appreciated!
is actually the default value; it means “draw the pixel only if the thing currently in the depth buffer is further away”. If you wanted exactly equal you’d use glDepthFunc(GL_EQUAL), but in practice you’ll get all sorts of rounding oddities if you do that.
Assuming you’re able to use depth values for this purpose, if you have ten objects then I’d suggest you:
By the time you get to step 4, you’ll have correct depth information everywhere a sprite was drawn and you’ll have the closest possible value set wherever the background plane was. So normal depth testing will work on the intermediate shadows — they’ll draw on top of anything drawn in step 3 but not on top of anything drawn in step 2.
You’re sort of using the depth buffer as a surrogate stencil, which the older iPhones don’t support.
If you can’t afford to use the depth buffer for this task then all I can think of is projecting the shadows as textures in the second texture unit, using the first for a mask texture (or not if you’re actually drawing rectangles, but I guess you’re probably not) and doing one rendering pass per sprite per shadow that falls upon it. Is that a passable solution?