Posts

Scaling Shapes in GLSL: Making Procedural Graphics Grow and Shrink

1 comments·0 reblogs
hey2d
25
·
0 views
·
min-read

If you've ever zoomed into a map, resized an image, or watched a button grow when you hover over it, you've seen scaling in action.

Scaling is simply changing the size of something.

In shaders, however, the idea is slightly different.

Just like translation and rotation, we don't scale the shape.

We scale the coordinate system before the shape is drawn.

Once this idea clicks, you'll realize that every procedural object can become larger or smaller without rewriting the drawing code.

Imagine Looking Through a Camera

Image from thread

Imagine pointing a camera at a drawing.

If you zoom in, did the drawing become bigger?

No.

Your view changed.

The drawing stayed exactly the same.

Scaling in GLSL works the same way.

The coordinates change.

The mathematics describing the shape does not.

Starting with Centered Coordinates

We'll continue using centered coordinates.

vec2 uv = vUv - 0.5; 

This places the origin in the middle of the screen.

Scaling is easiest when everything is centered.

Drawing Our Rectangle

We'll reuse the rectangle from the previous lesson.

float rect = 
 
step(-0.20, uv.x) * 
 
(1.0 - step(0.20, uv.x)) * 
 
step(-0.10, uv.y) * 
 
(1.0 - step(0.10, uv.y)); 

At the moment, the rectangle has a fixed size.

Let's change that.

Scaling the Coordinates

Suppose we divide the coordinates.

uv /= 2.0; 

Most beginners expect the rectangle to become smaller.

Instead, it becomes larger.

Why?

Because every pixel now appears closer to the center.

The coordinate space has expanded.

The rectangle occupies more of it.

Making the Shape Smaller

Now multiply the coordinates.

uv *= 2.0; 

This compresses the coordinate space.

As a result, the rectangle appears smaller.

Again, the shape itself never changes.

Only the coordinate system does.

Complete Shader

#ifdef GL_ES 
precision mediump float; 
#endif 
 
varying vec2 vUv; 
 
void main(){ 
 
    vec2 uv = vUv - 0.5; 
 
    uv /= 2.0; 
 
    float rect = 
 
        step(-0.20, uv.x) * 
 
        (1.0 - step(0.20, uv.x)) * 
 
        step(-0.10, uv.y) * 
 
        (1.0 - step(0.10, uv.y)); 
 
    gl_FragColor = vec4(vec3(rect),1.0); 
 
} 

Changing one line changes the size of the rectangle.

Everything else remains identical.

Scaling with One Variable

Instead of writing numbers directly, create a variable.

float scale = 1.5; 
 
uv /= scale; 

Now the size can be changed anywhere in the shader.

This also makes animation much easier.

Animating the Scale

Let's make the rectangle pulse.

float scale = 
 
1.2 + 
 
sin(uTime) * 0.4; 
 
uv /= scale; 

The rectangle smoothly grows and shrinks forever.

This simple animation is used everywhere in modern interfaces.

Scaling Only One Direction

Scaling doesn't have to affect both axes.

Stretch the X axis.

uv.x *= 2.0; 

The rectangle becomes thinner.

Stretch the Y axis.

uv.y *= 2.0; 

Now it becomes shorter.

Scaling each axis independently allows you to create many different shapes.

Combining Transformations

One of the biggest strengths of procedural graphics is combining transformations.

uv -= vec2(0.2,0.0); 
 
uv *= 1.5; 
 
uv = rotation * uv; 

Translate.

Scale.

Rotate.

Then draw the shape.

The rectangle automatically follows every transformation.

Notice that the drawing code never changes.

The Order Matters

Suppose we rotate first and translate afterward.

The result changes.

Changing the order of transformations changes the final animation.

This is one of the most important concepts in computer graphics.

As shaders become more advanced, understanding transformation order becomes essential.

Where Is Scaling Used?

Scaling appears in countless graphics.

  • Hover animations.
  • User interface buttons.
  • Pulsing effects.
  • Heartbeat animations.
  • Zoom effects.
  • Camera movement.
  • Particle systems.
  • Loading indicators.
  • Motion graphics.
  • Game effects.

Almost every animated interface uses scaling somewhere.

Try These Experiments

Make the rectangle twice as large.

Make it half its size.

Animate the scale.

Stretch only the X axis.

Stretch only the Y axis.

Combine scaling with rotation.

Combine scaling with translation.

Watch how each transformation changes the final result.

A Small Challenge

Can you create these effects?

  • A pulsing button.
  • A breathing square.
  • A growing loading icon.
  • A shrinking star.
  • A rotating shape that also changes size.

Each effect uses exactly the same drawing code.

Only the coordinate transformations change.

Posted Using INLEO