Shader Workshop
void main(){
    vec3 col = vec3(0);
    vec2 r = r;

    float a = angle(r);
    r += normalize(r) * a * 0.4;
    
    float len = length(r);
    
    if(length(r) < .5){
        col = vec3(uv + vec2(sin(time), cos(time))*.25, sin(time + a)*.5 + .5) * pow((.5 - length(r))*2., 1./7.);
    }
    
	gl_FragColor = vec4(col, 1.0);
}

Shader Cheatsheet

(just the important bits)

This is a quick reference for the most used bits of GLSL. Not everything is here so to learn more I recommend these links:

Contents


TL;DR

  • Shader code is run on each pixel separately
  • The entry point is the functioned named main
    void main(){
    	//code starts here
    }
    							
  • Pixels are colored by setting the value of the vector gl_FragColor
  • You can set vector properties with dot syntax: col.r = 4.2;
  • Colors values range from 0 to 1; gl_FragColor.r = 1.0; sets the red element to full
  • Vectors have properties .x, .y, .z, .w but you can also use .r, .g, .b, .a
  • Vectors are constructed with the following syntax
    vec2 point = vec2(1.3, 4.2); //vec2(x, y)
    where the number after 'vec' sets the number of properties
  • Most math functions are available (sin, cos, floor etc)
  • GLSL is very dumb with data-types:
    1.0 + 2;   // Error: wrong operand types
    1.0 + 2.0; // 3.0
    						
    The error is because 1.0 is a float and 2 is an int

Language Guide

GLSL is a very simple language, it supports only a subset of the features normally available in a programming language - most notably, in this version of GLSL there are no arrays, strings, switch statements, classes, console logging or while loops. However, GLSL does have powerful vector and matrix types. Below is an overview of the most commonly used features (but there are others not touched upon).

Variables

Variables must be defined with a type. The type comes before the variable name

float someVar = 42.0;
int anotherVar = 18;
					

Types with properties (like vectors and matricies) require constructing. This is done by calling the type's name as a function and passing the properties as arguments

vec3 color = vec3(0.1, 0.2, 0.3); //vec3(x, y, z)
					

The individual properties of the object can then be accessed

color.x = 1.0
color.y = 0.5
color.z = 0.0
					

Instead of using x, y, z, w, you can access the same properties with r, g, b, a.

You can access sub-vectors by using a string of properties (in any order)

vec4 fourVector = vec4(1.0, 2.0, 3.0, 4.0);
vec2 twoVector = fourVector.xy;    //vec2(1.0, 2.0)
vec3 threeVector = fourVector.zzw; //vec3(3.0, 3.0, 4.0)
					

This also works for assignment

fourVector.xy = vec2(11.0, 12.0);
//fourVector is now vec4(11.0, 12.0, 3.0, 4.0)
					

Basic Operations

GLSL supports the standard binary operators *, /, +, -. When performing binary operations, the types must be compatible - GLSL cannot add an int to a float, nor can it automatically convert between them

1.0 + 2;   // Error: wrong operand types
1.0 + 2.0; // 3.0
					

However, a vector can be multiplied by a float - each element of the vector is multiplied independently

vec2(3.0, 4.0) * 4.0; //vec2(12.0, 16.0);

This works similarly for matricies

Other operators include comparisons ==, !=, <=, >=, >, < and assignment operators *=, /=, +=, -=, used like so

someVar += 10.0;
					

Functions

Function definitions require a return type and a type for each argument

float lengthSquared(vec2 v){
	return pow(length(v), 2.0);
}
					

or

void doThing(float value1, vec4 value2){
	//does the thing
}
					

Multiple function definitions can have the same name but different parameters (function overloading)

float angle();
float angle(vec2 r);
float angle(vec2 r, vec2 o);
					

Functions can only be called after they've been defined. Unless function prototypes are used, only functions defined above the point of execution can be called. A function prototype is just the function header without the code

float lengthSquared(vec2 v);
					

Flow Control Statements

GLSL supports basic control statements if and for loops - in WebGL while and do while are forbidden. Additionally, the for loop can only contain constants in the condition.

The syntax of a if statement is

if(a < b){
	//a is less than b
}else if(a == b){
	//a is the same as b
}else{
	//a is greater than b
}
					

A for loop is

for(int i = 0; i < 10; i++){
	//this run 10 times
}
					

Custom Types

You can define custom data types with struct

struct NewType{
	float someProp;
	vec2 otherProp;
};
					

Your custom type is constructed in the same way as other types

NewType instance = NewType(3.1, vec2(10.0, 0.0));
instance.someProp; //3.1
instance.otherProp;	//vec2(10.0, 0.0)
					

Extra Variables and Functions

These are variables and functions I've setup for this editor, they are not available by default in GLSL

Variables

r vec2Distance from center. Ranges from -0.5 to 0.5 along the shortest axis of the viewport. The other axis is scaled to account for aspect ratio.
uv vec2Pixel position where (0, 0) is bottom left and (1, 1) is top right
time floatTime in seconds since the demo started
mouse vec3Coordinate of mouse where (0, 0) is bottom left and (1, 1) is top right. mouse.z is 1.0 when mouse is down and 0.0 otherwise
resolution vec2Width and height of canvas in pixels

Constants

PI float3.14159265359

Functions

angle() floatAngle of pixel about center from 0 to 2π
rand() floatRandom number from 0 to 1

Built-in Types

boolEither true or false
intWhole number (eg: 42)
floatNumber with decimal point (eg: 6.283)
vec2Vector with 2 elements (x, y)
vec3Vector with 3 elements (x, y, z)
vec4Vector with 4 elements (x, y, z, w)
mat22x2 Matrix
mat33x3 Matrix
mat44x4 Matrix
voidUsed when there's no return type or to explicitly define empty parameters

The vecn and matn types have float elements, for int elements, prefix i and for boolean, prefix b:

bvec2 switches = bvec2(true, false);


Built-in Functions

radians(degrees)Converts degrees to radians. The input parameter can ... more
degrees(radians)Converts radians to degrees. The input parameter can ... more
sin(angle)Returns the sine of an angle in radians. The input ... more
cos(angle)Returns the cosine of an angle in radians. The input ... more
tan(angle)Returns the tangent of an angle in radians. The input ... more
asin(x)Returns the arcsine of an angle in radians. It is the ... more
acos(x)Returns the arccosine of an angle in radians. It is ... more
atan(y_over_x)Returns the arctangent of an angle in radians. It is ... more
pow(x, y)Returns x raised to the power of y. The input parameters ... more
exp(x)Returns the constant e raised to the power of x. The ... more
log(x)Returns the power to which the constant e has to be ... more
exp2(x)Returns 2 raised to the power of x. The input parameter ... more
log2(x)Returns the power to which 2 has to be raised to produce ... more
sqrt(x)Returns the square root of x. The input parameter can ... more
inversesqrt(x)Returns the inverse square root of x, i.e. the reciprocal ... more
abs(x)Returns the absolute value of x, i.e. x when x is positive ... more
sign(x)Returns 1.0 when x is positive, 0.0 when x is zero ... more
floor(x)Returns the largest integer number that is smaller ... more
ceil(x)Returns the smallest number that is larger or equal ... more
fract(x)Returns the fractional part of x, i.e. x minus floor(x). ... more
mod(x, y)Returns x minus the product of y and floor(x/y). The ... more
min(x, y)Returns the smaller of the two arguments. The input ... more
max(x, y)Returns the larger of the two arguments. The input ... more
clamp(x, minVal, maxVal)Returns x if it is larger than minVal and smaller than ... more
mix(x, y, a)Returns the linear blend of x and y, i.e. the product ... more
step(edge, x)Returns 0.0 if x is smaller then edge and otherwise ... more
smoothstep(edge0, edge1, x)Returns 0.0 if x is smaller then edge0 and 1.0 if x ... more
length(x)Returns the length of a vector defined by the Euclidean ... more
distance(p0, p1)Returns the distance between two points. The distance ... more
dot(x, y)Returns the dot product of the two input parameters, ... more
cross(x, y)Returns the cross product of the two input parameters, ... more
normalize(x)Returns a vector with length 1.0 that is parallel to ... more
faceforward(N, I, Nref)Returns a vector that points in the same direction ... more
reflect(I, N)Returns a vector that points in the direction of reflection. ... more
refract(I, N, eta)Returns a vector that points in the direction of refraction. ... more
matrixCompMult(x, y)Returns a matrix resulting from a component-wise multiplication. ... more
lessThan(x, y)Returns a boolean vector as result of a component-wise ... more
lessThanEqual(x, y)Returns a boolean vector as result of a component-wise ... more
greaterThan(x, y)Returns a boolean vector as result of a component-wise ... more
greaterThanEqual(x, y)Returns a boolean vector as result of a component-wise ... more
equal(x, y)Returns a boolean vector as result of a component-wise ... more
notEqual(x, y)Returns a boolean vector as result of a component-wise ... more
any(x)Returns a boolean value as result of the evaluation ... more
all(x)Returns a boolean value as result of the evaluation ... more
texture2D(sampler, coord)Returns a texel, i.e. the (color) value of the texture ... more
textureCube(sampler, coord)Returns a texel, i.e. the (color) value of the texture ... more