Skip to content

Instantly share code, notes, and snippets.

@dlublin
Created May 10, 2024 19:07
Show Gist options
  • Save dlublin/2df96d7e9f0a72dd9a1260d8309a722f to your computer and use it in GitHub Desktop.
Save dlublin/2df96d7e9f0a72dd9a1260d8309a722f to your computer and use it in GitHub Desktop.
Mapping ISF 2024 Cheat Sheet
// GLSL / ISF "cheat sheet"
Some of these are resources are designed to be read like a textbook, with examples and challenges along the way.
- The Book of Shaders (https://thebookofshaders.com/)
- Inigo Quilez articles (https://iquilezles.org/articles/)
- The ISF Reference and Primer (https://docs.isf.video/)
- Standard GLSL data types (https://www.khronos.org/opengl/wiki/Data_Type_(GLSL))
In general the GLSL community is very open when it comes to sharing code.
It is important to be respectful when it comes to reusing and remixing other peoples artwork, particularly when it comes to commercial use.
- ISF Online Editor (https://editor.isf.video/)
- Shadertoy (https://www.shadertoy.com)
- GLSL Sandbox (https://glslsandbox.com/)
- Lygia (https://www.lygia.xyz/)
Tips for converting GLSL shaders to the ISF Specification:
https://docs.isf.video/ref_converting.html#texture2d-or-texture2drect
Automatically Generated Variables In ISF
- gl_FragCoord: This holds the values of the fragment coordinate vector are given in the window coordinate system. In 2D space the .xy from this can be used to get the non-normalized pixel location.
- isf_FragNormCoord : A vec2. This is a convenience variable, and repesents the normalized coordinates of the current fragment ([0,0] is the bottom-left, [1,1] is the top-right).
- TIME: A float that is set to the current rendering time (in seconds) of the shader.
- FRAMEINDEX: An int used to pass the index of the frame being rendered to the shader- this value is 0 when the first frame is rendered, and is incremented after each frame has finished rendering.
- DATE: This vec4 DATE is used to pass the date and time to the shader. The first element of the vector is the year, the second element is the month, the third element is the day, and the fourth element is the time (in seconds) within the day.
- RENDERSIZE: A vec2 that is set to the rendering size (in pixels) of the current rendering pass.
- PASSINDEX: Set to 0 on the first rendering pass. Subsequent passes (defined by the dicts in your PASSES array) increment this int.
Sampling a color from an input or imported image in ISF
vec4 inputPixelColor;
// both of these are the same - these use pixel coordinates
inputPixelColor = IMG_THIS_PIXEL(inputImage);
inputPixelColor = IMG_PIXEL(inputImage, gl_FragCoord.xy);
// both of these are also the same - these use normalized coordinates
inputPixelColor = IMG_NORM_PIXEL(inputImage, isf_FragNormCoord.xy);
inputPixelColor = IMG_THIS_NORM_PIXEL(inputImage);
Some particularly useful built-in GLSL functions:
- standard math functions:
sin(), cos(), tan(), asin(), acos(), atan(), pow(), exp(), log(), sqrt(), abs(), sign(), floor(), ceil(), fract(), mod(), min(), max(), round(), and clamp()
- mix: genType mix( genType x, genType y, genType a);
(linearly interpolate between two values)
- step: genType step( genType edge, genType x );
(generate a step function by comparing two values; values below edge return 0.0, values equal to or above return 1.0)
- smoothstep: genDType smoothstep( genDType edge0, genDType edge1, genDType x );
(performs smooth interpolation between 0 and 1 when edge0 < x < edge1)
Some custom functions you can use:
// invert an RGB color
vec3 invertColor (vec3 c)
{
return 1.0 - c;
}
float gray(vec4 n)
{
// return the grayscale value
return (n.r + n.g + n.b)/3.0;
}
// PI is not natively defined in GLSL, include this in shader code if needed
#define PI 3.14159265359
#define TWO_PI 6.28318530718
// converting from angles to radians
// eg PI / 2 is 90 degrees
float degrees = rads * 180.0 / PI;
// converting from radians to angles
// eg 90 degress is PI / 2
float rads = degrees * PI / 180.0;
// converting from cartesian coordinates to polar coordinates
// where st is the normalized point value to convert
// first remap the space to -1. to 1.
vec2 st = isf_FragNormCoord.xy;
// determine the angle in radians and distance from our center, vec2(0.5)
vec2 pos = st - vec2(0.5);
float r = distance(vec2(0.5),st);
float a = atan(pos.y,pos.x);
// converting from polar coordinates to cartesian coordinates
// where r is the radius and a is the angle in radians - cosine is used for the x component, sin is used for the y component
// and we offset relative to our original center, vec2(0.5)
vec2 loc = r * vec2(cos(a), sin (a)) + vec2(0.5);
// random function
// from book of shaders chapter 10
// see https://thebookofshaders.com/10/ for usage
float random (vec2 st) {
return fract(sin(dot(st.xy,vec2(12.9898,78.233)))* 43758.5453123);
}
// 2D SDF functions
// borrowed from pixel spirit deck!
// https://github.com/patriciogonzalezvivo/PixelSpiritDeck/tree/master/lib
float triSDF(vec2 st) {
st = (st*2.-1.)*2.;
return max(abs(st.x) * 0.866025 + st.y * 0.5, -st.y * 0.5);
}
float circleSDF(vec2 st) {
return length(st-.5)*2.;
}
float polySDF(vec2 st, int V) {
st = st*2.-1.;
float a = atan(st.x,st.y)+pi;
float r = length(st);
float v = tau/float(V);
return cos(floor(.5+a/v)*v-a)*r;
}
float pentSDF(vec2 st) {
vec2 pt = st;
pt.y /= 0.89217;
return polySDF(pt, 5);
}
float hexSDF(vec2 st) {
st = abs(st*2.-1.);
return max(abs(st.y), st.x * 0.866025 + st.y * 0.5);
}
float flowerSDF(vec2 st, int N) {
st = st*2.-1.;
float r = length(st)*2.;
float a = atan(st.y,st.x);
float v = float(N)*.5;
return 1.-(abs(cos(a*v))*.5+.5)/r;
}
float heartSDF(vec2 st) {
st -= vec2(.5,.8);
float r = length(st)*5.5;
st = normalize(st);
return r -
((st.y*pow(abs(st.x),0.67))/
(st.y+1.5)-(2.)*st.y+1.26);
}
float starSDF(vec2 st, int V, float s) {
st = st*4.-2.;
float a = atan(st.y, st.x)/tau;
float seg = a * float(V);
a = ((floor(seg) + 0.5)/float(V) +
mix(s,-s,step(.5,fract(seg))))
* tau;
return abs(dot(vec2(cos(a),sin(a)),
st));
}
float raysSDF(vec2 st, int N) {
st -= .5;
return fract(atan(st.y,st.x)/tau*float(N));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment