Skip to content

Instantly share code, notes, and snippets.

@totetmatt
Created February 20, 2020 12:35
Show Gist options
  • Save totetmatt/843760ad087cbbcb1976224aa2c1d1bb to your computer and use it in GitHub Desktop.
Save totetmatt/843760ad087cbbcb1976224aa2c1d1bb to your computer and use it in GitHub Desktop.
Kodelife shader program
#version 150
in VertexData
{
vec4 v_position;
vec3 v_normal;
vec2 v_texcoord;
} inData;
out vec4 fragColor;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
uniform vec2 iResolution;
uniform float iTime;
uniform float iTimeDelta;
uniform int iFrame;
uniform vec4 iMouse;
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
uniform sampler2D iChannel2;
uniform sampler2D iChannel3;
uniform vec4 iDate;
uniform float iSampleRate;
#define PI 3.141592
#define PI3 2*PI/3
#define ITER 64
void mainImage(out vec4, in vec2);
void main(void) { mainImage(fragColor,inData.v_texcoord * iResolution.xy); }
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// 2D matrix Rotation
mat2 r(float a){return mat2(cos(a),sin(a),
-sin(a),cos(a));}
// A lot of people in research try to find correct SDF function for object
// A famous one is Inigo Quilez
// https://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
//
// SDF Box
float sdBox (vec3 p, vec3 corner)
{
vec3 q = abs(p)-corner;
return min(0.,max(q.x,max(q.y,q.z))) + length(max(q,0.));
}
// SDF Sphere
float sdSphere( vec3 p, float s )
{
return length(p)-s;
}
float sdCappedCylinder(vec3 p, vec3 a, vec3 b, float r)
{
vec3 ba = b - a;
vec3 pa = p - a;
float baba = dot(ba,ba);
float paba = dot(pa,ba);
float x = length(pa*baba-ba*paba) - r*baba;
float y = abs(paba-baba*0.5)-baba*0.5;
float x2 = x*x;
float y2 = y*y*baba;
float d = (max(x,y)<0.0)?-min(x2,y2):(((x>0.0)?x2:0.0)+((y>0.0)?y2:0.0));
return sign(d)*sqrt(abs(d))/baba;
}
float sdTriPrism( vec3 p, vec2 h )
{
const float k = sqrt(3.0);
h.x *= 0.5*k;
p.xy /= h.x;
p.x = abs(p.x) - 1.0;
p.y = p.y + 1.0/k;
if( p.x+k*p.y>0.0 ) p.xy=vec2(p.x-k*p.y,-k*p.x-p.y)/2.0;
p.x -= clamp( p.x, -2.0, 0.0 );
float d1 = length(p.xy)*sign(-p.y)*h.x;
float d2 = abs(p.z)-h.y;
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
}
// Global SDF
// This represent our "scene" with the objects
#define ttime floor(iTime) + pow(fract(iTime),2.5)
float SDF(vec3 pos) {
pos.yz*=r(iTime*.5);
pos.yx*=r(iTime*.7);
pos .xz*=r(iTime+sin(pos.y*2.*cos(iTime)));
float sideBox = sdBox(pos+vec3(.1,0.,0.),vec3(0.4,0.76,0.3));
float sph = sdSphere(pos-vec3(.1,0.,0.),0.9);
return mix(sideBox,sph,sin(ttime)*.5+.4);
}
// Compute a normal from a vec3.
vec3 get_normal(vec3 p)
{
vec2 eps = vec2(0.1,0.);
return normalize(
vec3(
SDF(p+eps.xyy) - SDF(p-eps.xyy), // Diff in X
SDF(p+eps.yxy) - SDF(p-eps.yxy), // Diff in Y
SDF(p+eps.yyx) - SDF(p-eps.yyx) // Diff in Z
)
); // Math Vector
}
// Lighting, here my limit of the knowledge
float diffuse_directional(vec3 n,vec3 l){
float a = max(0.,dot(n,normalize(l))); // realistic lighting
float b = dot(n,normalize(l))*.5+.5; // less realistic lighting
return (b+a)/2. ;
}
// Main function
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
// Remember we want to be centered,-.5;+.5 and fix aspect ratio
vec2 uv = (fragCoord-.5*iResolution) / iResolution.y;
// Initialization of the Ray Marching algorithm
vec3 ray_origin = vec3(.1,.1,-3.); // Were we start
vec3 ray_direction = normalize(vec3(uv,1.)); // going forward
vec3 position = ray_origin ;
vec3 color = vec3(0.); // By default, everything will be black
bool hit = false;
float shad = 0.;
for(float i=0.; i<ITER; ++i) { // We iterate the ray
float _distance = SDF(position); // Find the closest distance from the current position
if(_distance <0.0001) { // If we are close enough, it's a hit, we put the shad and break the loop
shad = i / ITER;
hit = true;
break;
}
position += _distance * ray_direction; // Otherwise we conditnue the marching, updating the ray position
}
if(hit) { // If there is a hit we want to perfom some coloring
// I don't really understand here, just some lighting effect to get a good rendering
vec3 n = get_normal(position);
vec3 l = vec3(0.0001,-0.5,-5.);
color = vec3(diffuse_directional(n,l)); // light diffuse
color *= vec3(1.-shad*.6);
// Using the mix method toget some color
color = mix(vec3(0.1,0.1,0.1), vec3(0.9,0.1,0.7), color)*(1.-shad);
}
fragColor = vec4(color,1.);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment