Unreal Engine Tutorial: Creating a Crosshair Material Using the Screen Position Node

Following the vignette effect from the previous post, the next experiment explores creating a crosshair material entirely in screen space without relying on textures.

The basic idea is to create two infinite crossing lines in screen space, then progressively mask them to achieve the final crosshair shape.

The Screen Position node provides normalized coordinates across the screen, where (0,0) is the top left and (1,1) is the bottom right. To work with distance from center, we subtract 0.5 from both components to recenter the origin at (0,0).

We then take the absolute value of both axes since we only need distance from center.

Aspect Ratio Correction

Before creating the crosshair geometry, we need to account for aspect ratio. On a 1920x1080 display, the horizontal resolution is higher than the vertical resolution. This means the same normalized distance covers more pixels horizontally than vertically, which would make the crosshair uneven.

We correct this by multiplying the X axis by the aspect ratio. The ViewSize node gives us screen width and height, and dividing width by height produces the aspect ratio. Multiplying the absolute X value by this ratio ensures both axes measure distance using the same pixel scale.

This correction affects all three parts of the crosshair. Without it, the vertical bar would be physically wider than the horizontal bar, the horizontal arms would be longer, and the center gap would become an ellipse instead of a circle. With correction, both bars have equal pixel width, both arms have equal pixel length, and the gap remains circular.

Setting Up Parameters

Before creating the crosshair masks, we first set up scalar parameters for Thickness, GapSize, and ArmLength, along with a vector parameter for CrosshairColor. These let us adjust the crosshair properties without editing the material graph.

Creating the Horizontal/Vertical Bars

The horizontal bar is created using a Step node. We feed the absolute Y value into the Step node with a thickness parameter. The Step returns 1 where the vertical distance from center is less than the thickness, creating a horizontal line through the center.

The vertical bar uses the same logic, but operates on the corrected absolute X value. This ensures the vertical bar has the same pixel width as the horizontal bar.

Combining into a Cross

We add both bar masks together and run the result through Saturate. This gives us two infinite lines crossing at the center. The Saturate clamps the overlapping center pixels back to 1.

Creating the Center Gap

To create the center gap, we calculate the radial distance from center using the Length node. Before feeding the X component into Length, we multiply it by the aspect ratio to prevent the circular gap from becoming an ellipse.

The Length output is fed into a Step node with a gap size parameter. The Step returns 1 outside the gap radius and 0 inside it. Multiplying this with our cross mask removes a circular area from the center.

Controlling the Arm Length

To prevent the crosshair arms from extending infinitely across the screen, each arm is limited by checking if the distance along its axis exceeds the arm length parameter. For the horizontal arms, we use a Step node on the corrected absolute X. For the vertical arms, we use a Step node on the absolute Y.

We add both Step outputs together, then saturate to clamp values to the 0-1 range.

Multiplying the cross with gap by this length mask gives us the final crosshair shape.

Material Output

The final mask is multiplied with a crosshair color parameter and connected to Emissive Color. The mask itself is connected to Opacity Mask. The material domain is set to Surface, blend mode to Masked, and shading model to Unlit.

Displaying on Screen

To display the crosshair, we use DrawMaterial in a HUD blueprint. The DrawHUD event calculates the screen center position and draws the material within a defined pixel box.


With the masks combined and displayed through the HUD, the crosshair renders at screen center as shown in the screenshot below.

The project files for this and other Screen Position experiments are available on Github: https://github.com/RohitKotiveetil/UnrealEngine--ScreenPositionExperiments

Comments