Notes on Simon Dev's Shader Course

Notes on Simon Dev's Shader Course

If you like Shader, and would want to learn more about shader, Simon devs course is great.

Here a link to the Course:

All the code in here will be in GLSL, But Hashonde doesn't support GLSL.

Notes from Simon dev Course

  • UV coordinates are texture coordinates

  • V(axis) => Vertical Axis U (axis) => horizontal Axis

Here a link to a video on Graphics pipeline :

Blending Textures

  • Multiplicative Blending Multiply two colors , color1 * color2; Multiplication is always component wise

  • Blending Two textures together Create two texture with sample2D, then use texture2D function which takes textureSampler and the uVu. Then multiple the two Sampler.

Addressing Mode

How are texture coordinates sides the range[0, 1] instead? - ClampToEdge - Repeat - MirroredRepeat

.wrapS - U .wrapT - V

Methods - MirroredRepeatWrapping - Texture whould be repeated. - RepeatWrapping - Repeats the whole texture. - ClampToEdgeWrapping - just repeat the last coordinate values, again and again

Texture here means the colors, Texture is just used for simplify the explaination. You should know what Texture is to understand this, better.

To invert the Image Vertically Just mutiptly by -1.0


Zoom in, Zoom out

Standard Options - Nearest Filtering - Linear Filtering

.magFilter = THREE.NearestFilter; => become pixellated, its Fast .magFilter = THREE.LinearFilter; =>


Handled by 3d Renderer.

  • Bilinear Filtering

  • Trilinear Filtering

Functions Build-in

  • step(edge, x) - generates a step function by comparing x to edge

  • mix(a,b, t) - linearly interpolates between a and b using t as percentage

  • lerp - same as mix

  • smoothstep(edge1, edge2, x) - returns a smooth hermite interpolation between 0 and 1 if x is in the range [edge1,edge2]


smoothstep(10.0, 20.0, 10.0) -> 0.0smoothstep(10.0, 20.0, 12.5) => 0.156smoothstep(10.0, 20.0, 15.0) -> 0.5;
  • min(x, y) - returns the minimum of the 2 parameter

  • max(x,y) - returns the larger of the two.

  • clamp(a, minValue, maxValue) - clamps a to the range [minValue, maxValue ]

clamp(-1, 0,1) -> 0clamp(0.2, 0, 1) -> 0.2
  • saturate(a) or sat(a) - clamps a to the default value of range[0.0, 1.0] [NOT Build-in]

  • abs - asbolute value

  • floor - floor to int

  • ceil - ceil(2.9) -> 3, ceil(2.1) -> 3, ceil( 1.9) -> 2

  • round -

  • fract(a) - fractional part of ‘a’, fract(2.9) -> 0.9

  • mod(x,y) -> mod(5.2, 2.5) -> 0.2

Not Built-in functions, But common in some libraries (unity)

  • InverseLerp(currentValue, minValue, maxValue) -> same as smoothstep

  • Remap(currentValue, inMin, inMax, outMin, outMax)

    Remapping a value from one range to another range

remap(50.0, 0.0, 100.0, 0.0, 1.0) -> .5remap(50.0, 0.0, 100.0, 5.0, 10.0) -> 7.5
  • dFdx(x), dFdy(x) [ only for fragment shader] [Avaiable in threejs with extension: true]

    return screen-space derivative with respect to x/y;

Vector Operations & Maths

  • sin(radians)

  • cos(radians)

  • sqrt(x,y)

  • exp(x)

  • inversesqrt(x)

  • pow(x,y)

  • log(x)

  • log2(x)


Quick and easy way to access elements from a vector.

vec4 example = vec4(1.0, 2.0, 3.0, 4.0);  // xyzwvec2 v1 = example.xx;


vec4 example = vec4(1.0, 2.0, 3.0, 4.0);  // xyzwexample.x = 0.0 // example => vec4(0.0, 2.0,3.0, 4.0);// Not validexample.xx = vec2(1.0, 1.0);

Common Vector Functions

  • length()

  • normalize()

  • cross(someVector, normal);

  • dot(someVector, normal);

  • reflect(someVector, normal);

  • refract(someVector, normal)

Lighting Methods

Ambient Lighting - Cheap to add - Directionless lighting

Hemisphere lighting - 2 ambient lighight - ground and top

// localSpace to globaSpace
  vNormal = (modelMatrix * vec4(normal, 0.0)).xyz;

Lambertian Lighting

Diffuse lighting

light direction, light color, dot product of lightDir and normal, then get the max.

Color Spac


perpetual Color Spac

Do lighting in linear color Space.

If not convert to lineart to vector

Converting from ‘linear’ to ‘sRGB’:

  1. Linear -> Gamma;

  2. Gamma -> sRGB;

vec3 linearTosRGB(vec3 value){  vec3 lt=vec3(lessThanEqual(value.rgb,vec3(.0031308)));  vec3 v1=value*12.92;  vec3 v2=pow(,vec3(.41666))*1.055-vec3(.055);  return mix(v2,v1,lt);}

Phong Specular

Diffuse reflection and Phone reflection

It changes with CameraPosition

Specular IBL

Environment mapping

Image based lighting

IBL = Image Based Lighting

Concept => Capture the environment into a texture Sample from that texture, Adding it to you lighting equation

Spherical Environment

Cube Mapping -> 6 Textures

uniform samplerCube ourCubeMap;//.. bunch of mapvec4 sample = textureCube(ourCubeMap, direction);

Fresnal effect

gives us much better result;

Toon Shading

  • Cel Shading Toon Shading

    Run the Lighting throught the Step function


Vertex Shader


  • Mesh is a collection of triangles

  • Vertex shaders have a few inputs

    • Attributes

      • Each Vertex Shader instance can read the data for the vertex it’s processing
    • Uniforms

      • Each vertex shader instance sees the same global uniforms
  • Output

    • gl_position

      • Clip Space Position

      • Position after world/view/Projection tranformaiton

    • Varyings

      • Interpolated across each face

      • used by fragment shaders


  • Operations are not Commutative

Varying - IN Depth

  • Varying shot commings

  • Varying

We careful what you do in vertex shader and fragment shaders

  • Pop- something on screen

    Using easing function to do animation like Pop. Use Clamp with time to do this things.

Warped Sphere

  • Ripple effect

  • pass the y cooridnates to sin function;

  • Normals will change caused due to changing the vertexs

SDF’s and Simple Shapes

Sine Distance Functions

Resouces - (create shapes with sdfs)[]

We can create shapes with sdfs

  • Transformations

    For transformation we would have to subtract from the world origin;

Antialiasing & Shading

Boolean Operations

float d1 = sdf1(); float d2 = sdf2();

float union = min(d1, d2);

float intersection = max(d1, d2);

float subtraction = max(-d1, d2);

Smooth Maximums;

Using SoftMax and SoftMin,we can blend shapes together


Smooth pseudo-random values Procedural content generation

Noise is just not random only,its more about smooth pseuda-random values.

we create a texture, then we get the random value from this.

  • Value & Gradient Noise

    Value Noise -> Lattice of random values

Gradient Noise -* Grid of random unit vectors -* Just looks better ( i guess)

  • Fitlering

    bilinear filtering

  • Perlin Noise : available Gradient Noise

  • Simplex Noise : patent

  • OpenSimplex Noise: Noise implementation is just beter

Fractal Brownian Motion(fbm) Momentum Movement

  • More Noises

    RidgedFBM -> to create a river

  • ridgedFBM

  • turbulenceFBM

  • cellular noise / Voronoi / Worle Noise

  • domainWarpingFBM


Post Processing: Shader that runs on a texture instead of a texture run on a shader

Color Grading Depth of Field

Color boost



Distortions and Ripples

Did you find this article valuable?

Support Pratik Sharma by becoming a sponsor. Any amount is appreciated!