When working on my game, I wanted a way for players to quickly make a crosshair they like. That also works with showing spread. So I started by looking how Overwatch did theirs, but I noticed they had a lot of flaws they could improve upon.
All images used are up-scaled to four times size using nearest neighbour, and saved using a lossless format. So all the images are shown exactly how they are shown in-game.
Overwatch’s crosshair has color bleed, which I’m gonna guess is because they used a texture then just scaled it to the right size. And let the engine figure it out
What they have done is taken a texture and just scale it down to the right width and height, which works okay when you are just doing it with a solid color. But when you want outlines and you do that, then pixels start bleeding over to each other, and what you end up with a blurry crosshair.
Take a real close look at the line, its color is a bit everywhere and also colors a bit outside itself also.
What they should have done instead, is to split up the fill color and outline color and having each as a separate sprite and color. What you end up with then is a solid crosshair and as a plus side, you can change outline thickness and color really easy.
But my way have its own downsides as you can see. While my dot sticks out more and is more visible, it can look pixelated when using bigger dots. To fix that we change the fill texture to a dot that fades out at the edge, so we get a more smooth dot while still having a solid outline.
In Overwatch, each “part” of the crosshair is rendered as one object, with the outline and the main part being part of the same object. While that makes it quick and easy to move around part of the crosshair, the problem becomes when the parts overlap. Since the draw order mixes the white and black colors, which ends up looking really bad as you can see below.
(Note the artefacts you see in these images are actually how they are rendered in-game)
How Overwatch render the crosshair.
What they should have done instead is first render the outline then render the fill part on top of it. Which results in a better-looking crosshair.
How they should render the crosshair.
It allows enables you to set outline thickness and color separate from the fill color. Below is a example of what kind of crosshair you can make with that.
Half pixel gap
In Overwatch when you set the center gap to an uneven number, it doesn’t actually move the crosshair. Because you can’t move half a pixel, so what they do instead is trying to fake that the gap got bigger when in reality it didn’t. They do that by making each line one pixel longer and apply fading at both ends of the line. The fading also overlaps unto the outline. So what you end up with is a slightly blurred version of the crosshair.
Scales with resolution
So you might say that is a good thing, but the way Overwatch scales its crosshair makes the end result look bad. It just seems to have a sprite then set the scale to what they want it to be. And when it doesn’t fit exactly right, then it starts to make the crosshair a bit transparent.
The image below has same crosshair settings as the image above, but having the game in 1024*768 resolution. The crosshair now nearly blend into the background. The colors it should have is white (255, 255, 255) and black (0, 0, 0), instead they are (198, 188, 161) and the outline is hard to even say it’s color, since it’s different all around. If you want the same crosshair colors at 1920*1080 resolution (not that I think anyone would want to) then you need to set crosshair opacity to around 50. So playing at lower resolution basically forces you to play with 50% transparent crosshairs.
This is something pretty much everyone knows but I’m including it anyways.
- Allow setting crosshair color to any color, not just some preset colors.
- Allow setting crosshair outine color.
- Having a separate color option for the crosshair and the dot part.
- Outline thickness.
- Choose which parts of the crosshair to render, so you can, for example, make a T crosshair.
- Hitmarker color, size, and offset from the middle.
But the biggest thing of all, because no matter how many crosshair options you add there will always be someone that can’t get the crosshair he wants. So supporting loading in a png file for a crosshair, would be huge.
So what you can see below is how my version ended up being, you can play around with the slider and colors to test it. My game also has support for loading any png, but it’s not included in the demo.
You can find the code for my crosshair here.
I wrote this system for my aim training game.