Jump to content

Prettified selection rings


Recommended Posts

Alright, so I'm working on the ticket to improve the unit selection rings to make them look prettier and not just a simple 1px aliased line. I'm now at the point where I have a proof of concept implementation working, but there are a few questions that I'd need answered to know in which direction to continue with it. This may involve the art people as well, so I figured I'd bring this discussion here to get as much input as I can. This may get a bit technical, but hey, this is the technical discussion forum after all :P.

So the goal is to have pretty unit selection rings, preferably using textures so that we can extend it later on to also add various fancy graphics and not only basic rectangles and circles. This graphic was cited as an example of what this system would ideally support:

QDBmk.jpg

Keeping that in mind, the plan was to use textured quads (rectangles in OpenGL-speak).

However, there are some issues with using textures:

  • If you apply the same texture to display a selection ring of larger sizes, then the texture will get stretched and a 1px white / 2px player color / 1px white outline might become a 4px / 8px / 4px outline. So, to achieve a consistent visual outline width, you'd ideally have to create a separate texture for each selection outline size. This is what the proof of concept currently does, and it comes down to a total of 126 textures. This is a large amount of textures, and in practice there are another 126 mask textures involved to indicate where the player color should be applied, totalling 252 textures to be loaded in the worst-case scenario. I imagine it's unlikely that you'd ever actually need to load this many textures at the same time to render a scene, but I have no data to see how many unique unit footprint sizes there are on average in a scene.
    To reduce this amount, a scheme was suggested where you'd use the same texture for footprint sizes that are very close, like circles of radius 0.75 and 1, and accept the (hopefully small) visual difference. The amount of textures that is eliminated depends on how much visual accuracy you're willing to sacrifice. I've yet to try out a full range of accuracies to determine roughly at which point things start becoming unacceptable, but some quick tests suggest a reduction to only maybe 90-ish unique footprints (not counting masks). That's still a lot of textures.
    The current implementation sorts the rendering by texture so as to reduce swapping, but there are still potentially many textures that need to be loaded to render a scene, and I have no idea how many textures of which sizes the game can typically handle. I'm also unsure how to best manage these in code; I've noticed that ingame there is usually this short black-flicker when the texture is first used, i.e. while it's being loaded. I've noticed that textures can be prefetched which might be useful for this, but again, I have this feeling that prefetching like 50+ textures is not a very good idea. I'd love some input on how to best deal with this.

  • Using this many textures may pose some issues for artists as well. The current implementation uses a python script to read out all possible footprint sizes and shapes from the templates and generate the textures accordingly. This is fine for basic geometric shapes like circles and rectangles, but if we ever want to apply fancy graphics like in the image above to units of various footprint sizes, then the same texture is gonna need to be replicated a bunch of times in various sizes, with the additional constraint that the texture canvas must be a power-of-two in width and height. To at least somewhat accomodate this, I've created a small python script that will resize an image to its next power of two dimensions and fill the excess space with transparent pixels.
    Naming conventions and resolution is another issue: the engine needs a way to identify which version of a texture matches a particular footprint size from the texture name, and also the exact dimensions of the actual texture within its canvas (ie. what part of the image is transparent filler to reach pow2 dimensions and what part is actual texture). The latter depends on the resolution with which world-space units are mapped to texture pixels, i.e. how many pixels you, the artist, would like to use to achieve a texture that looks decent for that particular footprint size.
    Currently it defines a resolution of 8px per world-space unit, so that a footprint that is defined in XML as having radius 1.5 will have a 12px radius and 24px diameter in the texture. The convention, then, is to name that texture circle_24x24.png, and the engine would use those dimensions to determine exactly where the actual texture is located within the surrounding canvas (in this case, 32x32). The problem with this is twofold:
    • First of all, it forces a resolution of 8px upon you, and this is hardcoded into the engine and hence unchangeable (and you'd have to redo all textures if you ever change it).
    • Second, you may want to use different resolutions for different footprint sizes, or for various textures. For instance, I've found that 8px is sufficient for large units, but it looks bad for small circles. Or maybe you're working on a fancy graphic like the one above but need a higher resolution to make it look decent.

    To illustrate, look at the two selection rings below. They're both for a hellene female citizen, which have a circular footprint with a radius of 1.0 world-space units. In the left image the resolution is 8px, in the right one it's 12px:

    k2rOH.pngKG0Ct.png

    Clearly, the 8px one looks bad, while the 12px one might tentatively be called acceptable. However, for larger units 8px is plenty, and it'd actually be preferable to not use anything higher for them since that may cause jumps to the next pow2 canvas sizes and further increase the texture load -- probably not a good idea if you have on the order of a hundred of them. All in all, I'm not sure how to best handle this in a manner that's friendly to artists (because whatever fancy rules you come up with, the artists and the naming convention will have to consistently apply them). I've seen some textures.xml files around; I don't know if those are intended for this kind of thing, but maybe a texture listing in XML would be a decent solution as those would easily allow you to specify things like the resolution and also allow for location independence of the actual texture files. But of course, the file would need to be kept synchronized.

    [*]The current implementation tries to be as efficient as possible about rendering the quads, primarily by two means:

    • It allocates a single VBO, and reuses this buffer each frame instead of constantly releasing and re-allocating buffers.
    • As mentioned, it sorts the selection overlays to be rendered by texture, so as to prevent excessive texture swapping.

    The vertex buffer that is allocated is of maximum size, so as to accomodate as many overlay quads as possible without the need for reallocations. This implies that it supports a maximum of 16K vertices. So the question is: is this enough? I was told on IRC that the maximum amount of units that can be simultaneously selected is capped at about 300, which means that this is probably enough, but it depends on whether the overlay for a single (large) unit can take up multiple quads or not, and if so by the way they are indexed. The reason why multiple quads for a single selection ring may be needed is that they serve to make the outline "stick" to the terrain better if the unit is large and its outline spans several tiles (which may not be at the same elevation).

    However, supporting multiple quads per overlay introduces substantial additional complexity. It implies that we must use a separate index buffer and also keep track of a lot of technical stuff like offsets and number of indices per overlay in the large, statically-allocated buffer. Actually computing these quad's vertex locations is very much non-trivial as well, since units may be arbitrarily rotated -- and keep in mind that these computations will have to be performed every frame (units can move) for every selectable unit, which quickly adds up.

    If each overlay were to be only a single quad, then we could get rid of all this extra complexity, and we'd also have a guarantee that the single buffer supports exactly 4K quads and hence 4K selection rings, which is guaranteed to be enough if the hardcoded selection limit is indeed 300. However, this will look bad if the terrain under a large unit or building is somewhat hilly. For instance, if a wide unit is walking through a ravine, then with a single quad the selection ring will disappear into the sides instead of "crawling up" the sides (although I personally would find that to be acceptable given the advantages it brings).

    Someone on IRC mentioned that the ground beneath buildings may need to be flattened when it gets built, in which case single quads should be no problem at all. Nobody I've asked could actually confirm whether this flattening of the ground under buildings is something that I can rely on though, so I'm hoping someone can confirm or deny this.

Whew, I think that's about it. Hope I made the choices that need to be made clear without getting too involved; if not, please let me know and I will try to explain more clearly. For reference, some screenshots of the current implementation (at 8px resolution, so circles may look a bit shoddy):

post-12941-0-24965900-1318198536_thumb.p post-12941-0-87332900-1318198595_thumb.p post-12941-0-78121100-1318198704_thumb.p

Edited by vts
Link to post
Share on other sites

This does look much nicer than the current selection rings, nice work.

For the single/multiple quad issue I think that single should be fine as well. Since all of the models will be designed to work on flat ground I think if they were large enough for the selection rings to look bad then the model probably would as well. Making the selection rings hover slightly might be an option as well, you would need to test to see what would look strange.

Link to post
Share on other sites

Looks very nice :) You have put a lot of thought into this. What would you suggest for an approach to non-round/square entities, such as chariots, elephants, and boats?

Someone on IRC mentioned that the ground beneath buildings may need to be flattened when it gets built, in which case single quads should be no problem at all. Nobody I've asked could actually confirm whether this flattening of the ground under buildings is something that I can rely on though, so I'm hoping someone can confirm or deny this.

Yes, the plan (as far as I know) is to have the ground deform when constructing most "structures" in the game. This would basically be taking the Z height of the vertexes in the grid that are under the structure's envelop and averaging them.

Link to post
Share on other sites

So that works for any texture (like the hero star decals)?

I believe the hero stars are decals which are part of the model hierarchy, which weren't really designed to have tons of them simultaneously (or so I'm told). These selection overlays are different in that they're separate from the model hierarchy and don't necessarily stick to the terrain like the stars do, are more optimized for mass rendering, and of course are only displayed when you select the unit. But yes, you'd be able to achieve the same effect by using a star texture for the overlay. That's the reason for using textures instead of e.g. reusing the textured overlay lines to make small outlines around units, so you can use all kinds of fancy graphics instead of a standard outline.

Edited by vts
Link to post
Share on other sites

Looks very nice :) You have put a lot of thought into this. What would you suggest for an approach to non-round/square entities, such as chariots, elephants, and boats?

The second link has an example of a building outline using a square texture; not sure if that's what you're asking? In any case, you can apply any texture, so you can have whatever kind of fancy outline you'd like. In the current implementation all units with square footprints get a square selection texture and the circular ones get a circle, but you can use any texture you want instead. You'd just need a way to specify one, but I imagine that'd be just a matter of adding some XML to the template or something.

Edited by vts
Link to post
Share on other sites

Great work (y)

Someone on IRC mentioned that the ground beneath buildings may need to be flattened when it gets built, in which case single quads should be no problem at all. Nobody I've asked could actually confirm whether this flattening of the ground under buildings is something that I can rely on though, so I'm hoping someone can confirm or deny this.

I believe walls, wall towers, and gates will not flatten ground. I'm not sure how good/bad the single quads selection box will look when walls are placed over hills.

Link to post
Share on other sites

Could you show us one or two examples of the texture files?

Well I haven't actually gone around creating any fancy textures because all that seems to be needed at this point are basic rectangles and squares. But to give you an idea, I've attached some of the textures that are currently being used: a 42x42 circle and its mask, and a 36x72 rectangle and its mask. It's hard to see against a white background, but they consist of a 2px black outline of the shape, enclosed in a 1px white border. The black outline is where the player color is applied in-game, and is matched by the mask texture. You'll notice that, to achieve pow2 dimensions, the 42x42 circle is enclosed within a 64x64 image and the 36x72 rectangle is in a 64x128 image with transparent filler on either side. This is probably easier to see on the masks though, as all the filler is of course also masked out.

post-12941-0-82577900-1318264566_thumb.p post-12941-0-22979200-1318264575_thumb.p post-12941-0-50806100-1318264736_thumb.p post-12941-0-07376700-1318264746_thumb.p

Edited by vts
Link to post
Share on other sites

How would this be specified to the engine? Then maybe I can read that setting and take it into account.

I suspect flattening won't be implemented for a long time, especially since all new buildings now have a below ground level foundation, which was the main reason behind flattening AFAIR. That doesn't help you though :(

Link to post
Share on other sites
The reason why multiple quads for a single selection ring may be needed is that they serve to make the outline "stick" to the terrain better if the unit is large and its outline spans several tiles (which may not be at the same elevation).

I happened to be playing Dragon Age (for, uh, research) and noticed that its unit rings always get rendered in front of terrain (e.g. they're still visible if there's a hill or wall between the unit and the camera), though rendered normally relative to units (i.e. not always in front). That solves the problem of the rings sinking into bumpy terrain and disappearing - they're visible even when underground. It'd also be consistent with our silhouetting of units - units behind hills are still meant to be visible, so their selection rings should be too. I think we could find a way to implement that effect for the selection rings if it'd look good.

Also, as an attempt to record what I remember of a recent IRC discussion: it may be best to use this new single-quad-per-ring system for units (since they're small but there might be hundreds and they need to be reasonably efficient), and switch to the existing static line system (used for territory boundaries etc) for buildings (since they're large, and the rings ought to conform to terrain to look good (probably, unless the render-in-front-of-terrain effect would work here too), and there won't be many at once and they don't move every frame so they can focus on quality over performance).

Link to post
Share on other sites
  • 5 weeks later...

I don't know anything about graphic stuff, but i was wondering if there isn't some way to calculate how the circles should be positioned on the ground and just throw it on the screen at the correct (pixels?) location? Please don't pay much attention to this post, as i'm totally layman on this subject.

I'm not sure if I fully understand what you mean exactly, but I think that's basically the system we currently have, where we just have OpenGL draw a circle. The reason why we're changing it is because we want to be able to use textures for the selection outlines.

Link to post
Share on other sites
  • 3 months later...

Vectors are ugly if they don't have antialiasing (and antialiasing often hurts performance significantly, so we can't rely on it). They're also harder to implement in an artist-controllable way - we'd need a vector graphics editor, a vector file format, code for loading and rendering those vector files, etc, to support any shapes much more complex than plain circles. Textured quads will generally look prettier (assuming they're high enough resolution that you don't see the pixels, which should be possible), and perform better, and are much easier for artists to control (they can just paint a .png of whatever they want it to look like).

Link to post
Share on other sites

I understand. So the you'll need a full set of code to handle vector graphics witch does not exist right now. But then maybe a solution would be to implement some kind of smart stretch algorithm on the texture, instead of the normal bicubic (is it?).

Something like this, for example: http://research.microsoft.com/en-us/um/people/kopf/pixelart/

This way you can avoid having to load so many variation of the same texture into memory. (it's the memory against performance issue again)

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...