ledbanner-shaders/raytracing.glsl
2018-05-19 17:23:49 +02:00

229 lines
4.8 KiB
GLSL

// line light test WIP
// original: http://glslsandbox.com/e#43990.0
#ifdef GL_ES
precision highp float;
#endif
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
//float t=2.6;
float t=time;
vec3 lightpos1 = vec3(-1.*cos(t),-.5+0.25*cos(t),sin(t));
vec3 lightpos2 = vec3(1.*cos(t),-.5+0.25*cos(t),-sin(t));
//vec3 lightpos1 = vec3(-2.8,10.+10.8*sin(time+0.),0.);
//vec3 lightpos2 = vec3(2.5,10.+10.8*sin(time),0.);
vec3 hsv2rgb(vec3 c)
{
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
vec3 rotatey(in vec3 p, float ang)
{
return vec3(p.x*cos(ang)-p.z*sin(ang), p.y, p.x*sin(ang)+p.z*cos(ang));
}
vec3 rotatex(in vec3 p, float ang)
{
return vec3(p.x, p.y*cos(ang)-p.z*sin(ang), p.y*sin(ang)+p.z*cos(ang));
}
vec3 rotatez(in vec3 p, float ang)
{
return vec3(p.x*cos(ang)-p.y*sin(ang), p.x*sin(ang)+p.y*cos(ang), p.z);
}
vec2 plane(in vec3 p, in vec3 n, float d, float obj)
{
n = normalize(n);
return vec2(dot(p,n) + d, obj);
}
vec2 rbox(in vec3 p, in vec3 pos, in vec3 ang, float obj)
{
vec3 b = vec3(0.3,0.3,0.3);
p -= pos;
p = rotatey(p, ang.y*time);
p = rotatex(p, ang.x*time);
p = rotatez(p, ang.z*time);
return vec2(length(max(abs(p)-b,0.0)) - 0.1, obj);
}
vec2 sdCapsule( vec3 p, vec3 a, vec3 b, float r, float obj )
{
vec3 pa = p - a, ba = b - a;
float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
return vec2(length( pa - ba*h ) - r, obj);
}
vec2 sph(in vec3 p, float r, float obj)
{
return vec2(length(p) - r, obj);
}
vec2 min2(vec2 o1, vec2 o2)
{
if (o1.x < o2.x)
return o1;
else
return o2;
}
vec2 scene(in vec3 p)
{
vec2 d = plane(p, vec3(0,1.0,0), 0.9, 0.0);
d = min2(d, plane(p, vec3(0,0.0,1.0), 1.3, 0.0));
d = min2(d, sdCapsule(p, lightpos1,lightpos2,0.1,6.));
d = min2(d, sph(p-vec3(1.),1.,0.0));
d = min2(d, sph(p-vec3(-0.,1.,0.),1.,0.0));
d = min2(d, sph(p-vec3(-2.,1.,-1.),1.,0.0));
return d;
}
vec3 get_normal(in vec3 p)
{
vec3 eps = vec3(0.0001, 0, 0);
float nx = scene(p + eps.xyy).x - scene(p - eps.xyy).x;
float ny = scene(p + eps.yxy).x - scene(p - eps.yxy).x;
float nz = scene(p + eps.yyx).x - scene(p - eps.yyx).x;
return normalize(vec3(nx,ny,nz));
}
float softshadow(in vec3 ro, in vec3 rd)
{
vec3 pos = ro;
float shade = 0.0;
for (int i = 0; i < 8; i++) {
vec2 d = scene(pos);
pos += rd*d.x;
shade += (1.0 - shade)*clamp(d.x, 0.0, 0.90);
}
return shade;
}
float ao(in vec3 ro, in vec3 rd)
{
vec3 pos = ro;
float shade = 1.0;
for (int i = 0; i < 5; i++) {
vec2 d = scene(pos);
pos += rd*d.x;
shade -= d.x*pow(2.0, 0.5*float(i));
}
return shade;
}
vec4 linelight( vec3 rd, vec3 pos, vec3 lp1, vec3 lp2 )
{
lp2-=lp1;
vec3 line = normalize(lp2);
vec3 rp = cross(line,rd);
rp = cross(rp,rd);
float dlp = dot(line,rp);
float ld = dot(pos-lp1,rp)/dlp;
float len = length(lp2);
ld = clamp(ld, 0.,len);
vec3 hit = lp1+ld*line;
float bri= ld/len;
return vec4(hit,bri);
}
vec4 linelightd( vec3 pos, vec3 lp1, vec3 lp2 )
{
vec3 p1=(lp1-pos);
vec3 p2=(lp2-pos);
vec3 halfv = normalize(normalize(p1)+normalize(p2));
float d1 = dot(halfv,p1);
float d2 = dot(halfv,p2);
float e1 = max(d1,d2);
float e2 = min(d1,d2);
//need to fix
vec3 hit = pos+halfv*pow(e1-0.5*(e1-e2),2.);
float bri= 1.;
return vec4(hit,bri);
}
void main( void ) {
vec2 p = 2.0* ( gl_FragCoord.xy / resolution.xy ) - 1.0;
p.x *= resolution.x/resolution.y;
p /= max(resolution.x, resolution.y) / 60.0;
vec3 color = vec3(0.0);
vec3 contrib = vec3(0.0);
vec3 ro = vec3(0.0,0,2.0);
vec3 rd = normalize(vec3(p.x,p.y,-1.0));
vec3 pos = ro;
float dist = 0.0;
vec2 d;
//pos+=rd*2.;
for (int i = 0; i < 64; i++) {
d = scene(pos);
pos += rd*d.x*1.0;
dist += d.x*1.0;
}
if (dist < 100.0 && d.x < 0.001) {
vec3 n = get_normal(pos);
vec3 rp = cross(n,rd);
vec3 ref = reflect(rd,n);
//spec
vec4 lineLight = linelight(ref,pos,lightpos1,lightpos2);
vec3 ls = lineLight.xyz-pos;
float bris = .5/sqrt(length(ls));
bris*=lineLight.a;
ls = normalize(ls);
//diffuse
lineLight = linelightd(pos,lightpos1,lightpos2);
vec3 ld = lineLight.xyz-pos;
float brid= .2/sqrt(length(ld));
brid*=lineLight.a;
ld = normalize(ld);
vec3 r = reflect(rd, n);
float diff = clamp(dot(n, ld), 0.0, 1.0);
float shade = smoothstep(0.0, 1.0, 1.0 - ao(pos+0.01*n, 0.5*n));
float spec = pow(clamp(dot(r, ls), 0.0, 1.0), 109.0);
float shadow = 0.;//clamp(softshadow(pos+0.01*n, l), -1.0, 1.0);
if (d.y > 0.5 && d.y < 1.5) color += diff*vec3(1,1,1)*brid;
else if(d.y > 5.5)
color = vec3(1,1,1);
else
color += diff*vec3(0.5,1,1)*brid*1. + spec*vec3(1,1,1)*hsv2rgb(vec3(bris,0.5,1.));
}
gl_FragColor = vec4(pow(color,vec3(1./2.2)), 1.0);
}