Counter-Strike Style Scope
Emulates how the sniper scopes in counter strike works all in a shader.
Shader code
shader_type canvas_item;
uniform vec2 scope_screen_position = vec2(0.0);
uniform float scope_focus : hint_range(0.0, 1.0, 0.01) = 1.0;
uniform vec3 crosshair_screen_transform = vec3(0.0);
uniform float crosshair_focus: hint_range(0.0, 1.0, 0.01) = 1.0;
uniform sampler2D screen_sampler : hint_screen_texture;
void fragment() {
vec2 aspect_ratio = vec2(1.0, SCREEN_PIXEL_SIZE.x / SCREEN_PIXEL_SIZE.y);
vec2 centered_screen_uv = (((SCREEN_UV - 0.5) * 2.0) * aspect_ratio);
float uv_distance_from_center = clamp(distance(scope_screen_position, centered_screen_uv), 0.0, 1.0);
vec2 uv_direction_from_center = normalize(scope_screen_position - centered_screen_uv);
vec2 distortion = ((pow(max(uv_distance_from_center - 0.275, 0.0), 2.0) * 20.0) * (-uv_direction_from_center));
vec3 screen_texture = texture(screen_sampler, SCREEN_UV + distortion).rgb;
vec3 cache_color = COLOR.rgb;
float scope_blend = pow(
uv_distance_from_center * 3.0,
20.0 * scope_focus
);
float new_crosshair_focus = crosshair_focus * crosshair_focus;
float sin_scale_1 = (crosshair_screen_transform.y - centered_screen_uv.y) * sin(crosshair_screen_transform.z);
float cos_scale_1 = (crosshair_screen_transform.x - centered_screen_uv.x) * cos(crosshair_screen_transform.z);
float sin_scale_2 = (crosshair_screen_transform.x - centered_screen_uv.x) * sin(-crosshair_screen_transform.z);
float cos_scale_2 = (crosshair_screen_transform.y - centered_screen_uv.y) * cos(-crosshair_screen_transform.z);
float rotated_scale_1 = distance(
vec2(sin_scale_1, cos_scale_1),
vec2(cos_scale_1, sin_scale_1)
);
float rotated_scale_2 = distance(
vec2(sin_scale_2, cos_scale_2),
vec2(cos_scale_2, sin_scale_2)
);
float crosshair_blend_1 = clamp(1.0 - (rotated_scale_1 * 300.0 * new_crosshair_focus), 0.0, 1.0) * crosshair_focus;
float crosshair_blend_2 = clamp(1.0 - (rotated_scale_2 * 300.0 * new_crosshair_focus), 0.0, 1.0) * crosshair_focus;
float crosshair_blend = clamp(crosshair_blend_1 + crosshair_blend_2, 0.0, 1.0);
COLOR.rgb = mix(screen_texture, cache_color, scope_blend + crosshair_blend);
}

