If you like Shader, and would want to learn more about shader, Simon devs course is great.
Here a link to the Course:
https://simondev.teachable.com/courses/
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 :
%[https://www.youtube.com/watch?v=C8YtdC8mxTU&t=2s&ab_channel=BranchEducation]
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
Filtering
Zoom in, Zoom out
Standard Options - Nearest Filtering - Linear Filtering
.magFilter = THREE.NearestFilter; => become pixellated, its Fast .magFilter = THREE.LinearFilter; =>
Mipmaps
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]
example:
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)
Swizzling
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;
writing
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
sRGB
perpetual Color Spac
Do lighting in linear color Space.
If not convert to lineart to vector
Converting from ‘linear’ to ‘sRGB’:
-
Linear -> Gamma;
-
Gamma -> sRGB;
vec3 linearTosRGB(vec3 value){ vec3 lt=vec3(lessThanEqual(value.rgb,vec3(.0031308))); vec3 v1=value*12.92; vec3 v2=pow(value.xyz,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
BRDF
Vertex Shader
Recap
-
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
-
-
Transformations
- 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)[https://iquilezles.org]
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
Noise
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
PostFX
Post Processing: Shader that runs on a texture instead of a texture run on a shader
Color Grading Depth of Field
Color boost
Vignette
Pixelation
Distortions and Ripples