Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I would like to know how to make this effect of merged circle selection. Here are images to illustrate:

enter image description here enter image description here

Basically I'm looking for this effect:

enter image description here

How the merge effect of the circles can be achieved ? I didn't found any explanation concerning this effect. I know that to project those texture I can develop a decal system but I don't know how to create the merging effect.

If possible, I'm looking for purely shaders solution.

share|improve this question
    
Could you explain what do you mean by "merge effect"? –  wondra Aug 11 '14 at 12:16
    
Of course, if you look at the top right characters of the screenshot, the decals are not crossing each other but the two on the left cross their blue circle and are merged. I added a new screenshot to show the effect. –  MaT Aug 11 '14 at 12:33
    
Do you insist on shader solution? If not, you just solved it in your last picture. –  wondra Aug 11 '14 at 13:54
    
The last screenshot only shows the effect I am targeting. The final result should look like the previous screenshots. –  MaT Aug 11 '14 at 14:02
1  
Yep, I agree, I think that they build dynamically a mesh circle with the texture and then cut the mesh to merge them. It's also a good solution but I think it's more limited in term of effect you can do. –  MaT Aug 21 '14 at 6:13

5 Answers 5

up vote 7 down vote accepted

There are a few tricks you can do:

Z-buffer

After you have rendered all other objects, for each unit render a transparent circle of smaller size with max Z value. Then render selection circles decals on the ground. Since they are below in Z-order, they will be discarded when under units.

Being fully transparent means that the circle gets written only to Z-buffer (max Z value). Now when you render decals, they are tested against Z buffer values, and if they are passing the test they get rendered (which happens only outside of the circles)

Stencil

Same as with previous approach, but this time use a stencil buffer. Render smaller circles for units with some stencil value, then render selection decals. Setup stencil to discard any elements with your stencil value.

share|improve this answer
    
The Z-Buffer technique is interesting but I don't get how the first transparent circle can clip the ground decals. –  MaT Aug 22 '14 at 7:47
    
Thank you for your precisions ! –  MaT Aug 22 '14 at 7:52

You could for example check in the decal rendering pixel shader if there is an intersection with any other decals and kill the pixel if so. It's quite efficient to do for this kind of circular decals.

share|improve this answer
1  
I assume you have skipped the part from your answer - to pass all the circles locations and radiuses to shader. –  Krom Stern Aug 21 '14 at 4:41
    
@Krom If OP expresses any interest in the solution, I'm happy to give more details. –  JarkkoL Aug 21 '14 at 12:42

Do you mean those blue circles on the ground?

There may be a smarter way to do this but consider my solution as an example how this can be done. Render your circles to a separate empty texture of the size of the screen. At this point you can blend them together, however you want. Depending on your needs you can write the full color or just the information that a circle is present at given pixel. However, you will definetely need a depth information for each pixel that you write if you want a Z-test effect.

When you render the terrain after the previous step, you can sample the previously created texture, using screen coordinates in pixel shader, as UVs. Now you know, that the circle should or shouldn't be projected at given pixel of the terrain. However, this way it will work as if the Z-test was disabled, so a terrain can't hide any circle. If you want a terrain to hide circles that are behind it, perform a depth test before blending a circle with terrain texture. You can use a small bias to enable rendering of circles that are just a little bit under the terrain but you would still like them to render.


Edit: Now in order to get the effect of merged circles what you need to do is: When rendering to the separate texture, you need to check if there is already a circle rendered where you are trying to render a new one. (Check if the texture has a value there) if so, erase this pixel. This should give the effect of "outline" when two or more circles overlap. For this to work correctly, however you will need to do this test only for the inside of the circle, not the border. So when rendering circles, write some specific value to the output texture, which indicates that it is a circle inside. Then you just need not to render anything on the circle inside and you should be good.

Edit2: For your simple red/green example: Before you render any pixel, check if this pixel is not already green. If it is, don't render. This will do the trick. In fact, while writing to the texture you can even use red/green for outside/inside of the circle, and then while rendering the terrain read those values and convert them to a desired color.

If my answer is too abstract by any chance, let me know.

share|improve this answer
    
I get the general idea but as you say, it's a bit to abstract for me concerning the merged circles :) –  MaT Aug 11 '14 at 14:33

There are a few options. As a general method, stencil buffers often come in very handy where certain drawing needs to be masked out, like the outline where the circles overlap in your example.

In this case, I think this can be done just as easily without a stencil buffer. You can use the depth buffer to eliminate the outline where the circles overlap. The idea is that you draw the interior of the circles into just the depth buffer (since we don't want to see the interior), and then draw the outline. This way, the part of the outline that overlaps with another circle will be eliminated by the depth test.

The only caveat is that you have to be careful about depth fighting. You can use a small offset to make sure that the outlines are in fact behind the interior, and get eliminated by the depth test. An alternative would be to use glPolygonOffset().

Let's say you have two circles that are parallel to the xy-plane, with centers at (x1, y1, z) and (x2, y2, z). And you have these draw functions:

// Draw interior part of circle, shown in green in the schematic in the question.
drawInterior(x, y, z);

// Draw outline of circle, shown in red in the schematic in the question.
drawOutline(x, y, z);

The sequence of drawing then looks like this, with delta being a small offset:

glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
drawInterior(x1, y1, z + delta);
drawInterior(x2, y2, z + delta);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
drawOutline(x1, y1, z);
drawOutline(x2, y2, z);
share|improve this answer

Off the top of my head, if these decals are drawn as discs, I would test each circle for intersection against each other circle, and put the intersection points into an array. Then draw arcs that are not inside an intersection. This is not a shader solution, though.

share|improve this answer
    
Yeah I thought about that too :) but as you said it's not a shader solution and it is not a very generic solution. But thanks ! –  MaT Aug 14 '14 at 14:08
    
That's pretty vague description –  Krom Stern Aug 21 '14 at 4:36

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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