5
\$\begingroup\$

Right, I've tried searching for this but as you might be able to tell from the title, I didn't really know how to word it anyway...

In some games such as rts games, when a unit is hidden or half hidden behind another object, such as a tree of building, the player will be able to see a translucent coloured version of that unit where it is hidden.

I was wondering how it would be possible to figure out which parts of the units sprite have actually been covered, and how to then use this information to then draw the translucent coloured version of the sprite.

If possible could the answers given relate to c++ and sfml? If not other answers will still be appreciated.

Sorry if my language is unclear its the first time I've asked a question on this site.

\$\endgroup\$
2
\$\begingroup\$

You can use the stencil buffer.

A good approach for drawing outlines generally is using the stencil buffer, as described on flipcode.

To draw obscured objects using the stencil buffer, here is a recipe I've used:

  • draw all units normally, setting z-buffer.

  • draw the scenery and set the stencil buffer as well as the z-buffer.

  • clear the z-buffer.

  • draw all units a second time, setting the z-buffer, but only where the stencil buffer is set, this time with a shader that draws outlines or glows or whatever affect is desired.

This has limitations in that you'll have difficulty drawing units that are obscured by other units properly with this approach. You can however class enemy units as 'scenery' for this, so enemy units behind rocks are not highlighted but your own units behind enemy units are.

\$\endgroup\$
  • \$\begingroup\$ +1: This seems better than the second approach I outlined. \$\endgroup\$ – Sean Middleditch Sep 11 '13 at 21:52
  • \$\begingroup\$ This looks like what i was looking for, Thanks for your help :) \$\endgroup\$ – Jamie Pennell Sep 12 '13 at 10:47
9
\$\begingroup\$

You can use depth buffering for this, just as you would for rendering. Just flip the depth comparison operator between lessorequal and greater.

First, draw the whole scene as normal, filling in the depth buffer as you go. Now flip your depth comparison. Then redraw the desired object(s) using a highlight shader.

This will cause the occluded parts of an object to be be drawn in the highlighted color. If you want to draw partially-occluded objects with a highlight on the whole object, the technique may be more complex.

One approach there is to render all static geometry. Then do an occlusion query render pass for all the dynamic objects, recording whether any object was occluded more than ~20% or some heuristic. Then do a rendering pass the draw all the non-occluded objects with Z buffer testing/writing on and no special effect. Finally do a pass to render all the occluded objects with their own depth buffer in the highlight effect. This process can be optimized with some cleverness, but I assume you want the basics working before you worry about optimizing something that might not even need it for your game.

\$\endgroup\$
  • \$\begingroup\$ I don't think this method quite works. When you flip the depth func this causes the back faces of the highlight model to be drawn on top of the main model. This would require depth testing for the faces of the object itself, distinct from the objects depth testing. Am I missing something? \$\endgroup\$ – Justin Meiners Jun 16 '16 at 22:24
  • \$\begingroup\$ You would still have backface culling enabled so backfaces would not be drawn. You can end up with self-occluded parts (e.g. a character's arm) rendering over, though, so it only really works reliably with convex objects. \$\endgroup\$ – Sean Middleditch Jun 16 '16 at 23:45
  • 1
    \$\begingroup\$ I just accomplished it by changing the draw order. I first draw the highlight with no depth write and GL_GREATER, and then draw the normal model with depth write and GL_LESS. This solves the problem by drawing the highlight over top obstacles, but not interfering with the normal model. \$\endgroup\$ – Justin Meiners Jun 17 '16 at 0:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.