Skip to content

Instantly share code, notes, and snippets.

@sketchpunk
Last active November 27, 2023 20:42
Show Gist options
  • Save sketchpunk/e9a21dbc4c5245d466379787d0e72b9b to your computer and use it in GitHub Desktop.
Save sketchpunk/e9a21dbc4c5245d466379787d0e72b9b to your computer and use it in GitHub Desktop.
GLSL Shader Snippets
//https://blog.demofox.org/2014/08/28/one-dimensional-bezier-curves/
//http://www.demofox.org/bezcubic1d.html
//1D Cubic (3rd) Bezier through A, B, C, D where a Start and d is end are assumed to be 0 and 1.
float norm_bezier3( float b, float c, float t ){
float s = 1.0 - t;
float t2 = t * t;
return (3.0 * b * s * s * t) + (3.0 * c * s * t2) + t2 * t;
}
float bezier3( float a, float b, float c, float d, float t ){
//y = A * (1-x)^3 + B * 3x(1-x)^2 + C * 3x^2(1-x) + D * x^3
float s = 1.0 - t;
float s2 = s * s;
float t2 = t * t;
return ( a * s2 * s ) + ( b * 3.0 * t * s2 ) + ( c * 3.0 * t2 * s ) + ( d * t2 * t );
}
// QUADRATIC BEZIER CURVE
vec3 qbezier_at( vec3 a, vec3 b, vec3 c, float t ){
float s = 1.0 - t;
return s * ( s * a + t * b ) + t * ( s * b + t * c );
}
vec3 qbezier_dxdy( vec3 a, vec3 b, vec3 c, float t ){
return 2.0 * ( 1.0 - t ) * ( b - a ) + 2.0 * t * ( c - b );
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// UV to Radial UV
float u = sqrt(dot(uv, uv))*2.0;
float v = (atan(uv.x,uv.y)/-3.14) * 0.5 + 0.5;
uv.x = u;
uv.y = v;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ROTATE UV
vec2 rot_uv = mat2( 0.707, -0.707, 0.707, 0.707 ) * screen_uv; // Rotate 45 degrees raw UV
vec2 cell_pos = fract( uv_scale * rot_uv ) * 2.0 - 1.0; // Scale UV, fraction, then 0,1 to -1,1
float px = texture( main_tex, cell_pos ).r; // Get Rotated Texture Pixel
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Screen Space UV
// VERT - Save Screen Ratio in Z to fix X Stretching.
vec3 screen_pos = pvm * vertex_pos;
vec3 screen_pos.z = screen.x / screen.y;
//FRAG
vec2 screen_uv = (screen_pos.xy / screen_pos.w)*0.5+0.5;
screen_uv.x *= screen_pos.z;
// 2D Rotate 45 Degrees
vec2 rot_uv = mat2( 0.707, -0.707, 0.707, 0.707 ) * screen_uv;
[BETTER - Just Vert Shader]
vec4 wpos = model.view_matrix * vec4( a_pos, 1.0 );
gl_Position = global.proj_view * wpos;
screen_uv.xy = gl_Position.xy / gl_Position.w;
screen_uv.x *= global.screen_size.x / global.screen_size.y; // Fix X Stretch
screen_uv.xy = screen_uv.xy * 0.5 + 0.5; // To -1,1 to 0,1
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
float remap(float value, float inMin, float inMax, float outMin, float outMax) {
return outMin + (outMax - outMin) * (value - inMin) / (inMax - inMin);
}
vec2 map(vec2 value, vec2 inMin, vec2 inMax, vec2 outMin, vec2 outMax) {
return outMin + (outMax - outMin) * (value - inMin) / (inMax - inMin);
}
vec3 map(vec3 value, vec3 inMin, vec3 inMax, vec3 outMin, vec3 outMax) {
return outMin + (outMax - outMin) * (value - inMin) / (inMax - inMin);
}
vec4 map(vec4 value, vec4 inMin, vec4 inMax, vec4 outMin, vec4 outMax) {
return outMin + (outMax - outMin) * (value - inMin) / (inMax - inMin);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vec3 red = rgb( 0xff0000 );
vec3 rgb( int c ){
return vec3(
float( ( c >> 16 ) & 0xff ) * 0.00392156863,
float( ( c >> 8 ) & 0xff ) * 0.00392156863,
float( c & 0xff ) * 0.00392156863
);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// RAMPs
float step_val[5] = float[]( 0.65, 0.70, 0.9, 0.0, 0.0 );
float step_pos[5] = float[]( 0.0, 0.15, 0.4, 9.0, 9.0 );
float step_ramp( float t, float step_val[5], float step_pos[5], float feather, int i ){
for( i; i > 0; i-- ){
if( (step_pos[ i ]-feather) <= t ){
return mix(
step_val[ i-1 ],
step_val[ i ],
smoothstep( step_pos[ i ] - feather, step_pos[ i ] + feather, t )
);
}
}
return step_val[ 0 ];
}
float bw_step_ramp( float grad, float[4] ramp, float[4] ramp_pos, int cnt ){
if( grad >= ramp_pos[ cnt-1 ] ) return ramp[ cnt-1 ]; // Greater ten final check.
for( int i=1; i < cnt; i++ ){
if( ramp_pos[ i ] > grad ) return ramp[ i-1 ];
}
return ramp[ 0 ];
}
vec3 ramp_col[3] = vec3[]( rgb(0x1D212A), rgb(0x2A4B53), rgb(0x81FFE9) );
float ramp_wgt[3] = float[]( 0.0, 0.427386, 0.78 );
out_color.rgb = color_step_ramp( ramp_col, ramp_wgt, 0.5 );
vec3 color_step_ramp( vec3[3] color, float[3] wgt, float t ){
for( int i=2; i > 0; i-- ){
if( wgt[ i ] <= t ) return color[ i ];
}
return color[ 0 ];
}
struct DotRamp{
vec3 color_a;
vec3 color_b;
float t;
};
void color_dot_ramp( vec3[5] color, float[5] wgt, float t, float feather, int i, out DotRamp dr ){
for( i; i > 0; i-- ){
if( ( wgt[ i ] - feather ) <= t ){
dr.color_a = color[ i-1 ];
dr.color_b = color[ i ];
dr.t = smoothstep( wgt[ i ] - feather, wgt[ i ] + feather, t );
return;
}
}
dr.color_a = color[ 0 ];
dr.color_b = color[ 0 ];
dr.t = 0.0;
}
void color_dot_ramp2( vec3[5] color, float[5] wgt, float t, float feather, int i, out DotRamp dr ){
for( i; i > 0; i-- ){
if( ( wgt[ i ] ) <= t ){
dr.color_a = color[ i-1 ];
dr.color_b = color[ i ];
dr.t = clamp( ( t - wgt[i] ) / feather, 0.0, 1.0 );
return;
}
}
dr.color_a = color[ 0 ];
dr.color_b = color[ 0 ];
dr.t = 0.0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// https://docs.unity3d.com/Packages/com.unity.shadergraph@6.9/manual/Posterize-Node.html
// Posterization or posterisation of an image entails conversion of a continuous gradation of
// tone to several regions of fewer tones, with abrupt changes from one tone to another.
float Posterize( float In, float Steps ){
//return floor( In / ( 1.0 / Steps ) ) * ( 1.0 / Steps ); // WHY UNITY??? To much divisions.
return floor( In * Steps ) / Steps;
}
// This is from a custom blender node, does a nicer job then unities.
float posterization_plus( float grad, float steps ){
float raw = round( grad * steps ) / steps;
float first_step = 1.0 / steps;
float is_raw_less = ( raw < 0.001 )? 1.0 : 0.0;
return raw + first_step * is_raw_less ;
}
vec3 quat_mul_vec3( vec4 q, vec3 v ){ return v + (2.0 * cross(q.xyz, cross(q.xyz, v) + (q.w * v))); }
vec4 quat_mul(vec4 q1, vec4 q2){
return vec4(q2.xyz * q1.w + q1.xyz * q2.w + cross(q1.xyz, q2.xyz), q1.w * q2.w - dot(q1.xyz, q2.xyz) );
}
vec4 quat_axis_angle( vec3 axis, float angle ){ return vec4( axis * sin( angle * 0.5 ), cos( angle * 0.5 ) ); }
vec4 quat_unit_vecs( vec3 a, vec3 b ){
// Using unit vectors, Shortest rotation from Direction A to Direction B
// http://glmatrix.net/docs/quat.js.html#line548
// http://physicsforgames.blogspot.com/2010/03/Quat-tricks.html
float dot = dot( a, b );
if( dot < -0.999999 ){
vec3 v = cross( vec3( 1.0, 0.0, 0.0 ), a );
if( length( v ) < 0.000001 ) v = cross( vec3( 0.0, 1.0, 0.0 ), a );
return quat_axis_angle( normalize( v ), PI );
}else if( dot > 0.999999 ){
return vec4( 0.0, 0.0, 0.0, 1.0 );
}
return normalize( vec4( cross( a, b ), 1.0 + dot ) );
}
vec3 closest_point_to_line( vec3 a, vec3 b, vec3 p ){
vec3 d = b - a;
vec3 v = ((p - a) * d);
float t = (v.x + v.y + v.z) / dot( d, d );
return a * ( 1.0 - t ) + b * t;
}
// https://www.shadertoy.com/view/dsGBzW
mat3 TBN(vec3 N) {
//Returns the simple tangent space matrix
vec3 Nb,Nt;
if (abs(N.y)>0.999) {
Nb = vec3(1.,0.,0.);
Nt = vec3(0.,0.,1.);
} else {
Nb = normalize(cross(N,vec3(0.,1.,0.)));
Nt = normalize(cross(Nb,N));
}
return mat3(Nb.x,Nt.x,N.x,Nb.y,Nt.y,N.y,Nb.z,Nt.z,N.z);
}
vec3 TBN(vec3 N, out vec3 O) {
//Returns the simple tangent space directions
if (abs(N.y)>0.999) {
O = vec3(1.,0.,0.);
return vec3(0.,0.,1.);
} else {
O = normalize(cross(N,vec3(0.,1.,0.)));
return normalize(cross(O,N));
}
}
vec3 SchlickFresnel(vec3 r0, float angle) {
//Return a Schlick Fresnel approximation
return r0+(1.-r0)*pow(1.-angle,5.);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment