getbetterat.work
Topic: Graphics

How to Talk to Your GPU.

GLSL stands for OpenGL Shading Language. It is the code you write to tell your graphics card how to draw shapes and colors on your screen.

Most code runs on your computer's main brain (the CPU). But drawing millions of pixels very fast is hard. So, we send that job to the graphics card (the GPU). GLSL is the language the GPU understands.

Why do we need a new language?

The CPU (Main Brain)

Your CPU is very smart. It handles game logic, physics, and input. But it does tasks one by one. If you ask it to paint 2 million pixels, it paints them one at a time. This is too slow for video games.

The GPU (Graphics Card)

Your GPU is not as smart, but it has thousands of tiny workers. It can do the exact same simple math on millions of pixels all at once. GLSL gives the instructions to these thousands of workers.

The Graphics Pipeline (The Factory Line)

Drawing a 3D object on a flat screen takes steps. The GPU moves data through a factory line called the pipeline. You write GLSL code to control two major stops on this line.

1. 3D Data
(Points & Math)
YOU WRITE THIS

Vertex Shader

Places the corners of the object on your screen.

YOU WRITE THIS

Fragment Shader

Colors in the pixels between the corners.

4. Your Screen
(The final picture)

The Vertex Shader (Moving Shapes)

A "vertex" is just a fancy word for a corner point. A triangle has 3 vertices. A square has 4. A 3D game character might have 50,000 vertices. The Vertex Shader runs one time for every single corner point.

The Fragment Shader (Painting Pixels)

After the Vertex Shader places the corners, the GPU figures out which screen pixels fall inside those corners. A "fragment" is basically a pixel. The Fragment Shader runs one time for every single pixel inside the shape.

How to write it: Types of Data

GLSL looks a lot like the "C" programming language. It is very strict about math. You cannot mix whole numbers and decimals easily. Here are the most common blocks of data you will use.

float

A Number with a Decimal

You must always use a dot.
float speed = 1.5;

vec2

Two Numbers Together

Used for flat 2D positions (X and Y).
vec2 point = vec2(10.0, 5.0);

vec3

Three Numbers

Used for 3D positions (X, Y, Z) or basic colors (Red, Green, Blue).

vec4

Four Numbers

Used for Colors with Transparency (Red, Green, Blue, Alpha).

How Data Moves (Inputs and Outputs)

uniform

The Global Remote Control

A uniform is a piece of data sent from your main game code (CPU) to the GPU. It stays the exact same for every single pixel. Examples: Game Time, Mouse Position, Screen Size.

in / attribute

The Setup Data

Data that changes for every corner point. This is how the Vertex Shader gets the 3D model data from the game.

out / varying

Passing Notes

This is how the Vertex Shader passes a message down the factory line to the Fragment Shader. Example: Passing the color from a corner down to the pixels.

The GPU Loves Math

You do not need to write complex math from scratch. GLSL comes with built-in math tools that run incredibly fast. Here are some of the most popular tools:

sin() & cos()

Great for making things wave back and forth over time. Used for water effects or breathing animations.

mix(a, b, % )

Blends two values together based on a percentage. Great for mixing two colors.

step(edge, x)

Returns 0.0 or 1.0. It makes sharp, hard edges. Good for blocky, retro, or cartoon shadows.

length()

Finds the distance between two points. Very useful for making circular shapes or glowing lights.

Your First Fragment Shader

Let's write a simple Fragment Shader. This code will color every pixel on the screen solid red.

solid_red.frag
void main() {
    // We create a vec4 for the color. (Red, Green, Blue, Alpha)
    vec4 myColor = vec4(1.0, 0.0, 0.0, 1.0); 

    // We tell the GPU to use this color for the pixel
    gl_FragColor = myColor;
}

Notice: We use 1.0 instead of 1. In GLSL, colors go from 0.0 (none) to 1.0 (full). Because they are floats, you must write the decimal!

Where is GLSL used?

Video Games

Every modern game uses shaders to draw water, fire, shadows, and metal reflections.

Web Design (WebGL)

Cool, interactive 3D websites run GLSL directly inside your internet browser.

Movie Tools

Animation and 3D modeling software use GLSL so artists can preview materials instantly.

Common Beginner Mistakes

Missing the Semicolon

Like the C language, every single command must end with a semicolon ;. If you forget it, the screen will just go black.

Mixing Numbers

You cannot easily add an integer (whole number) to a float (decimal). 1.0 + 1 will break. Always write 1.0 + 1.0.

Where Am I? (Screen Coordinates)

When the Fragment Shader runs, it needs to know which pixel it is currently painting. It gets this from a built-in variable called gl_FragCoord.

The Raw Pixel

If your screen is 1920 pixels wide, gl_FragCoord.x might be exactly 500.5. But working with huge numbers is messy in math.

The Percentage (UV)

We prefer numbers from 0.0 to 1.0. We divide the current pixel by the total screen width. Now, the left side is 0.0, the middle is 0.5, and the right is 1.0. This is called a UV Coordinate.

Mixing Colors Like Digital Paint

GLSL uses light to mix colors (Red, Green, Blue). Remember, 0.0 is dark, and 1.0 is fully bright. Mixing them gives you every color on your screen.

vec3(1.0, 0.0, 0.0)

Pure Red

vec3(0.0, 1.0, 0.0)

Pure Green

vec3(1.0, 1.0, 0.0)

Yellow (Red + Green)

The Magic of "Swizzling"

GLSL has a superpower called swizzling. It lets you shuffle, flip, and copy the parts of a vector (like a color or position) just by typing the letters in a different order.

// Setup a normal color

vec4 color = vec4(1.0, 0.5, 0.2, 1.0);

SWIZZLED

// Extract only the Red, Green, Blue

vec3 rgb_only = color.rgb;

// Flip the color backwards!

vec3 flipped = color.bgr;

// Copy Red three times (makes greyscale)

vec3 all_red = color.rrr;

Adding Time & Motion

Shaders are usually static pictures. To make them move, your main CPU code must send a uniform variable that tracks the clock. We usually call this u_time.

The Pulse Effect

If you pass u_time into the built-in math tool sin(u_time), the result will smoothly float up and down between -1.0 and 1.0 forever. This is how you make glowing lights or breathing animations!

Images as Wrapping Paper (Textures)

A texture is just a flat image file (like a PNG or JPG). In GLSL, you read this image using a tool called sampler2D.

How wrapping works:

  1. You give the GPU an image (the sampler2D).
  2. You look at your current UV coordinate percentage (e.g., exactly the middle of the screen: vec2(0.5, 0.5)).
  3. You use the built-in function texture(sampler, uv).
  4. The GPU grabs the exact pixel color from the exact middle of your image and returns it to you!

Why GPUs Hate "IF" Statements

In normal coding, you use if / else all the time. In GLSL, you should avoid it whenever possible. This is called "Branching".

The Problem

The thousands of tiny workers in your GPU are tied together in groups. If one worker takes the "if" path and another takes the "else" path, they both have to wait for the other to finish. It slows everything down.

The Solution

Instead of true/false logic, GLSL developers use math to blend things. They use tools like step() and mix() to smoothly transition between two choices without making the workers split up.

Faking Random Nature (Noise)

GPUs are strict math machines. They do not have an easy Math.random() command. If you want to draw a natural-looking cloud, dirt, or fire, you cannot rely on true randomness.

Instead, developers use complex mathematical equations called "Noise Functions". These math equations spit out values that look random and chaotic, but are actually completely predictable. If you put the exact same position into the math, you will always get the exact same "random" dot out.

How to Find Bugs (Debugging)

You cannot use console.log() or print text to the screen from a shader. If your math breaks, your screen just turns completely black.

Visual Debugging:

The only way to test a variable is to turn it into a color. If you want to know if your speed variable is working, you tell the shader:

"If speed is greater than 1.0, paint the screen pure red. Otherwise, paint it green."

Then you just look at your monitor to see what color it is!

speed > 1.0
speed < 1.0

The Rule Book (Versions)

Before writing any code, the very first line of a GLSL file must always declare which rule book (version) it is using. If you forget this, the GPU might not understand your newer commands.

version 300 es

* Note: es stands for Embedded Systems. It is heavily used in WebGL (web browsers) and mobile phones.

Your Next Steps

You now know the vocabulary. The next step is simply practicing how to combine these tools.

Start by drawing a circle using the length() tool. Then, make that circle move left and right using sin(u_time). Finally, try mixing its color from Red to Blue based on its screen coordinates.

Return to Topic List →