Skip to main content
GameDev.net gamedev.net

Mouse and Touch Input

by GameDev.net · GLSL ES 3.00 (WebGL2) · 25 Aug 2026

Use in your engine

What it demonstrates

This project turns mouse or touch position into shader input. A bright marker follows an active pointer while a wider halo visualizes influence around it. When no pointer is held, the example falls back to the center so the composition remains useful and the difference between active and idle state is explicit.

Source Revision 1

Author notes are linked to specific lines.

Shader inputs

void mainImage(out vec4 fragColor, in vec2 fragCoord)

Called once per pixel. Write the colour to fragColor.

iResolution vec3
Viewport size in pixels (z is the pixel aspect ratio).
iTime float
Seconds since the shader started.
iTimeDelta float
Seconds since the previous frame.
iFrameRate float
Frames per second, smoothed.
iFrame int
Frames rendered since the start.
iMouse vec4
Mouse position: xy while held, zw of the last click.
iDate vec4
Year, month, day, and seconds within the day.
iChannel0 sampler2D
Texture bound to channel 0.
iChannel1 sampler2D
Texture bound to channel 1.
iChannel2 sampler2D
Texture bound to channel 2.
iChannel3 sampler2D
Texture bound to channel 3.
iChannelResolution vec3[4]
Pixel size of each bound channel texture.
iChannelTime float[4]
Playback time of each channel, in seconds.
iSampleRate float
Audio sample rate, always 44100.
Main Image5
1 void mainImage(out vec4 fragColor, in vec2 fragCoord) {
2 vec2 uv = fragCoord / iResolution.xy;
3 bool pointerHeld = iMouse.z > 0.0;
4 vec2 pointer = pointerHeld ? iMouse.xy / iResolution.xy : vec2(0.5);
5 float distanceToPointer = distance(uv, pointer);
6 float halo = exp(-18.0 * distanceToPointer);
7 float marker = 1.0 - smoothstep(0.025, 0.035, distanceToPointer);
8 vec3 color = vec3(0.03, 0.05, 0.10) + halo * vec3(0.08, 0.35, 0.70);
9 color = mix(color, vec3(1.0, 0.72, 0.22), marker);
10 fragColor = vec4(color, 1.0);
11 }
12

Learn from this shader

How it works

ShaderLab supplies iMouse in pixel coordinates. Its xy components hold pointer position, while a positive z component indicates an active press. The shader normalizes pointer pixels by viewport resolution so they share the fragment UV coordinate space. It then measures the distance from every fragment to the pointer. An exponential function turns that distance into a broad, smoothly fading halo. A separate smoothstep threshold creates the compact marker, demonstrating that one distance field can drive multiple visual layers with different falloffs.

Try changing

Press or drag across the preview and watch both layers move without storing state. In a fork, change the idle fallback, increase the exponential coefficient to tighten the halo, or replace distance with abs(uv - pointer) and combine the components with max to create a square influence. Use iMouse.zw to investigate the last click data documented by ShaderLab.

Using it in a game

Pointer fields can drive hover highlights, brush cursors, radial reveals, and touch-responsive backgrounds. Convert input into the same coordinate space as the effect before comparing positions. Engines differ in coordinate origin, touch handling, and whether pointer data is automatically available to materials, so application code may need to provide a uniform.

Explore the techniques

Continue with curated explanations and progressively related examples.

LicenseMIT
Views0
Forks0

Discussion

Loading comments...