All guides

Aspect Ratio Correction in GLSL

Dividing fragCoord by resolution normalizes both axes to zero-to-one, but a unit on each axis may cover a different pixel count. Use one pixel scale for circles, such as dividing both axes by canvas height. Image lookup still uses UV normalized independently per axis.

Fix the problem and environment

Dividing fragCoord by resolution normalizes both axes to zero-to-one, but a unit on each axis may cover a different pixel count. Use one pixel scale for circles, such as dividing both axes by canvas height. Image lookup still uses UV normalized independently per axis.

The controlling code

vec2 uv=gl_FragCoord.xy/u_resolution;
vec2 p=(2.0*gl_FragCoord.xy-u_resolution)/u_resolution.y;
float circle=1.0-smoothstep(0.3,0.31,length(p));
float cellPixels=12.0;
vec2 blockUV=(floor(gl_FragCoord.xy/cellPixels)+0.5)*cellPixels/u_resolution;

Verify in order

Test square, wide and portrait canvases. The circle must remain circular and pixelation cells must have equal horizontal and vertical pixel lengths.

Scope and common mistakes

Keep CSS size and drawing-buffer size coordinated. Changing only element styling leaves shader pixel units inconsistent with displayed pixels.

Continue experimenting

Reference

Official documentation

Run the related examples