Skip to content

Instantly share code, notes, and snippets.

@spenceryonce
Created August 8, 2023 17:24
Show Gist options
  • Save spenceryonce/f56b6ef045180c0136a3f09ab6a282fa to your computer and use it in GitHub Desktop.
Save spenceryonce/f56b6ef045180c0136a3f09ab6a282fa to your computer and use it in GitHub Desktop.
GLSL Reference Library
//----------------------CONSTANTS------------------------------------------
#define PI 3.141592653589793238462643383
//----------------------COLORSPACE CONVERSION------------------------------
vec3 encodeSRGB(vec3 linearRGB)
{
vec3 a = 12.92 * linearRGB;
vec3 b = 1.055 * pow(linearRGB, vec3(1.0 / 2.4)) - 0.055;
vec3 c = step(vec3(0.0031308), linearRGB);
return mix(a, b, c);
}
vec3 decodeSRGB(vec3 screenRGB)
{
vec3 a = screenRGB / 12.92;
vec3 b = pow((screenRGB + 0.055) / 1.055, vec3(2.4));
vec3 c = step(vec3(0.04045), screenRGB);
return mix(a, b, c);
}
//-------------------------RANDOM-----------------------------------------
float hash12(vec2 p)
{
vec3 p3 = fract(vec3(p.xyx) * .1031);
p3 += dot(p3, p3.yzx+.8);
return step(fract((p3.x + p3.y) * p3.z), .4);
}
float GetHeight(float x)
{
return sin(x*0.371)+sin(x)*0.274;
}
float rand(float y){
return fract(sin(y)*10000000.0);
}
float random(vec2 st) {
return fract(sin(dot(st.xy,
vec2(12.9898,78.233)))*
43758.5453123);
}
//-------------------------------SDFs---------------------------------------
float sdRing(vec2 p, vec2 uv, float r1, float r2)
{
float d = length(uv-p);
return step(d, r2) - step(d, r1);
}
float sdBox( in vec2 p, in vec2 b )
{
vec2 d = abs(p)-b;
return length(max(d,vec2(0))) + min(max(d.x,d.y),0.0);
}
float sdOrientedBox( in vec2 p, in vec2 a, in vec2 b, float th )
{
float l = length(b-a);
vec2 d = (b-a)/l;
vec2 q = (p-(a+b)*0.5);
q = mat2(d.x,-d.y,d.y,d.x)*q;
q = abs(q)-vec2(l,th)*0.5;
return length(max(q,0.0)) + min(max(q.x,q.y),0.0);
}
float sdSegment( in vec2 p, in vec2 a, in vec2 b )
{
vec2 pa = p-a, ba = b-a;
float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
return length( pa - ba*h );
}
float sdArc( in vec2 p, in vec2 sc, in float ra, float rb )
{
// sc is the sin/cos of the arc's aperture
p.x = abs(p.x);
return ((sc.y*p.x>sc.x*p.y) ? length(p-sc*ra) :
abs(length(p)-ra)) - rb;
}
float sdMoon(vec2 p, float d, float ra, float rb )
{
p.y = abs(p.y);
float a = (ra*ra - rb*rb + d*d)/(2.0*d);
float b = sqrt(max(ra*ra-a*a,0.0));
if( d*(p.x*b-p.y*a) > d*d*max(b-p.y,0.0) )
return length(p-vec2(a,b));
return max( (length(p )-ra),
-(length(p-vec2(d,0))-rb));
}
float sdRoundedX( in vec2 p, in float w, in float r )
{
p = abs(p);
return length(p-min(p.x+p.y,w)*0.5) - r;
}
float sdTaperBox(vec2 p, float wb, float wt, float yb, float yt, float blur)
{
float m = smoothstep(-blur,blur,p.y-yb);
m *= smoothstep(blur,-blur,p.y-yt);
p.x = abs(p.x);
float w = mix(wb, wt, (p.y-yb) / (yt - yb));
m *= smoothstep(blur,-blur,p.x-w);
return m;
}
vec4 sdTree(vec2 uv, vec3 col, float blur)
{
float m = sdTaperBox(uv, .03, .03, -.05, .25,blur); //trunk
m += sdTaperBox(uv, .2, .1, .25,0.5,blur); //canopy 1
m += sdTaperBox(uv, .15, .05,0.5,0.75,blur); //canopy 2
m += sdTaperBox(uv, .1, .0, .75, 1.,blur); //canopy 3
float shadow = sdTaperBox(uv-vec2(.2,0), 0.1, 0.5, 0.15, 0.25, blur);
shadow += sdTaperBox(uv+vec2(.3,0), 0.1, 0.5, 0.43, 0.5, blur);
shadow += sdTaperBox(uv-vec2(.25,0), 0.1, 0.5, 0.7, 0.75, blur);
col -= shadow*0.8;
//m = 1.;
return vec4(col, m);
}
float sdCircle( vec2 p, float r )
{
return length(p) - r;
}
//-------------------------------PLOTTING-----------------------------------
float plot(vec2 uv, float y){
float blur = 0.572;
return smoothstep(-0.02*blur,0.02*blur,uv.x-y)-
smoothstep(0.02*blur,-0.02*blur,uv.x-y);
}
float plotv2(vec2 uv, float pct){
return smoothstep( pct-0.02, pct, uv.y) -
smoothstep( pct, pct+0.02, uv.y);
}
//-----------------------------VARIOUS-SHAPES-------------------------------
float DistLine(vec3 ro, vec3 rd, vec3 p)
{
return length(cross(p-ro,rd))/length(rd);
}
float circle(vec3 point, vec3 ro, vec3 rd)
{
float d = DistLine(ro,rd,point);
d = smoothstep(.1,.09,d);
return d;
}
vec3 rayDirection(vec2 uv, vec3 ro)
{
return vec3(uv.x,uv.y,0.)-ro;
}
//------------------------------SHAPING FUNCTIONS------------------------------
//SHAPING HELPERS
float sphere(vec3 origin, float radius)
{
return length(origin) - radius;
}
float cylinder(vec3 origin, float radius)
{
return length(origin.xz) - radius;
}
mat2 rotate2d(float angle)
{
return mat2(cos(angle),sin(angle),-sin(angle),cos(angle));
}
//------------------------------INTERSECTORS-----------------------------------
// sphere of size ra (radius) centered at point ce (center) ro (ray origin), rd (ray direction)
vec2 sphereIntersect( in vec3 ro, in vec3 rd, in vec3 ce, float ra )
{
vec3 oc = ro - ce;
float b = dot( oc, rd );
float c = dot( oc, oc ) - ra*ra;
float h = b*b - c;
if( h<0.0 ) return vec2(-1.0); // no intersection
h = sqrt( h );
return vec2( -b-h, -b+h );
}
// axis aligned box centered at the origin, with size boxSize
vec2 boxIntersect( in vec3 ro, in vec3 rd, vec3 boxSize, out vec3 outNormal )
{
vec3 m = 1.0/rd; // can precompute if traversing a set of aligned boxes
vec3 n = m*ro; // can precompute if traversing a set of aligned boxes
vec3 k = abs(m)*boxSize;
vec3 t1 = -n - k;
vec3 t2 = -n + k;
float tN = max( max( t1.x, t1.y ), t1.z );
float tF = min( min( t2.x, t2.y ), t2.z );
if( tN>tF || tF<0.0) return vec2(-1.0); // no intersection
outNormal = (tN>0.0) ? step(vec3(tN),t1) : // ro ouside the box
step(t2,vec3(tF)); // ro inside the box
outNormal *= -sign(rd);
return vec2( tN, tF );
}
// plane degined by p (p.xyz must be normalized)
float planeIntersect( in vec3 ro, in vec3 rd, in vec4 p )
{
return -(dot(ro,p.xyz)+p.w)/dot(rd,p.xyz);
}
//------------------------------SMOOTHSTEP FUNCTIONS---------------------------
//smoothstep cubic polynomial
float smoothstepCubicP( float x )
{
return x*x*(3.0-2.0*x);
}
//smoothstep quartic polynomial
float smoothstepQuarticP( float x )
{
return x*x*(2.0-x*x);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment