Created
March 27, 2020 17:26
-
-
Save solsarratea/6c5166db6c70c5d09dbd4da52025f3e4 to your computer and use it in GitHub Desktop.
Raymarching Mandelbulb in Kodelife
This file contains hidden or 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
uniform float time; | |
uniform vec2 resolution; | |
uniform vec3 spectrum; | |
uniform sampler2D texture0; | |
out vec4 fragColor; | |
#define PHI (sqrt(5)*0.5 + 0.5) | |
//Color function | |
vec3 palette( in float t, in vec3 a, in vec3 b, in vec3 c, in vec3 d ) | |
{ | |
return a + b*cos( 9.28*(c*t+d) ); | |
} | |
void pR(inout vec2 p, float a) { | |
p = cos(a)*p + sin(a)*vec2(p.y, -p.x); | |
} | |
int Iterations = 30; | |
float Scale = 2.; | |
//float Power = abs(sin(time/20))*8.; //Continous rendering | |
float Power = 2.; | |
float Bailout = 2.8; | |
//Distance estimator function | |
float DE3(vec3 pos) { | |
vec3 z = pos; | |
float dr = 1.0; | |
float r = 0.0; | |
for (int i = 0; i < Iterations ; i++) { | |
r = length(z); | |
if (r>Bailout) break; | |
float theta = acos(z.z/r); | |
float phi = atan(z.y,z.x); | |
dr = pow( r, Power-1.0)*Power*dr ; | |
float zr = pow( r,Power); | |
theta = theta*Power; | |
phi = phi*Power; | |
z = zr*vec3(sin(theta)*cos(phi), sin(phi)*sin(theta), cos(theta)); | |
z+=pos; | |
} | |
return 0.3*log(r)*r/dr; | |
} | |
float scene(vec3 ray){ | |
ray = ray-vec3(0.03,0.5,1.); | |
vec3 ray2 = ray; | |
//Spin it - change the plane | |
pR(ray2.zx,time/2); // rotating | |
ray.xy = mod(ray.yx,4.)-vec2(2.); | |
return max(DE3(ray2),0.); | |
} | |
vec3 estimateNormal(vec3 p) { | |
float smallNumber = 0.1; | |
vec3 n = vec3( | |
scene(vec3(p.x + smallNumber, p.yz)) - | |
scene(vec3(p.x - smallNumber, p.yz)), | |
scene(vec3(p.x, p.y + smallNumber, p.z)) - | |
scene(vec3(p.x, p.y - smallNumber, p.z)), | |
scene(vec3(p.xy, p.z + smallNumber)) - | |
scene(vec3(p.xy, p.z - smallNumber)) | |
); | |
return normalize(n); | |
} | |
float lighting(vec3 origin, vec3 dir, vec3 normal) { | |
vec3 lightPos = vec3(cos(time/20)*5, sin(time), 1.); | |
vec3 light = normalize(lightPos - origin); | |
float diffuse = max(0., dot(light, normal)); | |
vec3 reflectedRay = 1.5 * dot(light, normal) * normal - light; | |
float specular = max(0.3, (pow(dot(reflectedRay, light), 4))); | |
float ambient = 0.08; | |
return ambient + diffuse + specular; | |
} | |
vec4 trace(vec3 rayOrigin, vec3 dir){ | |
vec3 ray = rayOrigin; | |
float dist = 0.; | |
float totalDist = 0.; | |
float maxDist = 5.; | |
for (int i = 0; i < 40 ; i++){ | |
dist = scene(ray); | |
if(dist < 0.0001){ | |
vec4 distCol = vec4(1. - vec4(totalDist/maxDist)); | |
vec3 hsvCol = palette( | |
distCol.b, | |
vec3(0.5, 0.5, 0.5) , | |
vec3(1, 0.5, 0.9) , | |
vec3(.5, 1.0, .8), | |
vec3(.6, .4, .2)); | |
vec4 lightingCol = vec4(lighting(rayOrigin,dir,estimateNormal(ray))); | |
return vec4(hsvCol,1.)*.9 - lightingCol*0.8; | |
} | |
totalDist += dist; | |
ray += dist * dir; | |
} | |
return vec4(0.); | |
} | |
vec3 lookAt(vec2 uv, vec3 camOrigin, vec3 camTarget){ | |
vec3 zAxis = normalize(camTarget - camOrigin); | |
vec3 up = vec3(-0.03,0.4,0.2); | |
vec3 xAxis = normalize(cross(up, zAxis)); | |
vec3 yAxis = normalize(cross(zAxis, xAxis)); | |
float fov = 2; | |
vec3 dir = (normalize(uv.x * xAxis + uv.y * yAxis + zAxis * fov)); | |
return dir; | |
} | |
void main(void){ | |
vec2 uv = gl_FragCoord.xy/resolution.xy; | |
uv.x *= resolution.x/resolution.y; | |
vec2 st = uv* 2. - 1.; | |
vec3 camOrigin = vec3(-2. , 5., -1. + 1.5*sin(time/2)); //z axis foward and backwards | |
vec3 camTarget = vec3(-2,-2,3); | |
vec3 rayOrigin = vec3(camOrigin.xy, camOrigin.z - 2.5); | |
vec3 direction = lookAt(uv, camOrigin, camTarget); | |
fragColor = trace(rayOrigin, direction); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Playing with spectrum and continous transition