Created
February 20, 2020 12:35
-
-
Save totetmatt/843760ad087cbbcb1976224aa2c1d1bb to your computer and use it in GitHub Desktop.
Kodelife shader program
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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