So after extensive searching, it seems I’m either unable to guess the right keywords to find what I’m looking for, or it’s possibly something simple I’m overlooking. There really doesn’t seem to be much information available on the technique, so maybe it’s something simple. Question: Given the following screenshot from Civilization 5, how would you accomplish the same effect of outlining the border of a civilization’s territory?
I’m not very versed in shader programming, so I’m unsure if it would be the best tool for the job. I guessed shader, but the more I look at it, maybe a projector? Did some projector testing with my prototype, as seen here:
I’m using individual meshes for the hex tiles, instead of a single mesh like Civ5 uses, so the projector idea may work better. Any ideas? Could really use any advice to help point me in the right direction. If it’s a shader I’ll end up needing, could definitely use some pointers on how to set it up, and even a general rundown would work.
Normally I would use a projector or a stencil object.
But since there are many hexagons, this means many draw calls. When looking at that civ 5 screenshot, I’d recommend doing it in a post process step. This step would read in the world position from the deferred buffer and overlay the hexagon pattern. Of course this is only possible with deferred rendering.
It seems more like the actual bordering territory vertices are kept track of, and lerped between, to make nice bezier curves. No idea how to accomplish that in a shader, but splines are simple enough if it comes down to it. I can get the bordering hexes easily enough outside of a shader, and probably the bordering edges/vertices as well (bordering vertices are shared by no more than 2 hexes, 3 = inside, 1 or 2 = border).
Thought of several options, not sure which would be more performant/ideal:
Some kind of shader/projection magic (that doesn’t somehow eat me alive in draw calls)
Bezier spline closed loop with line renderer (maybe Vectrosity?)
At runtime, create a separate single “territory” mesh based on tiles within borders (only changed when border expands/contracts), with a mostly transparent material except on outer border, rendered on top of existing individual tiles…
Is there some kind of line magic I can do with a shader and just the vertices of a mesh?
Personally I would use marching squares algorithm for the territory mesh (and maybe a subdivision alg to get it smoother) and a simple outline shader. I didn’t try it, but I’m really interested so If you find the solution, please share
If I look at the circular markings, it doesn’t seem all that complex. Just put a circle inside the hexagon and split it into 6 parts. Then based on whether neighbouring tiles are included or not, decide which parts to draw and which parts not to draw.
Splines or bezier curves can offer a more generic solution, but when it just comes to hexagons, the solution can be pretty simple I think.
This is possible even with a combined chunk mesh. I overlay a texture in the shader, using vertex colors to differentiate border colors. Now, getting them to link together is possible, but requires a little more logic and a texture sheet. But that logic gets a little fancy. You can even get it down to one draw call!
(I just finished doing all this for my CivGrid terrain framework. It’s not too bad, but not fun.)
Vertex colors, of course! So maybe a two pass shader that paints terrain texture first, and then overlays a colored outer edge line between vertices of the same color. Which means that when my cities are settled and borders are updated, I just set the vertex colors and let the shader handle it. Thanks, that sounds much cleaner, I’ll explore it more.
Btw, Vectrosity turned out to not be appropriate, and would’ve required either some messy workaround cameras or editing the source. Vectrosity’s lines are rendered facing camera, instead of being able to set an arbitrary vector, like Vector3.up in my case (to match my terrain normals), so drawing 3D lines caused them to look odd and intersect my tiles in odd places.