testing shader fragments
This commit is contained in:
233
cogs.frag
Normal file
233
cogs.frag
Normal file
@ -0,0 +1,233 @@
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
#define MAX_STEPS 100
|
||||
#define MAX_DIST 20.
|
||||
#define SURF_DIST .001
|
||||
#define TAU 6.283185
|
||||
#define PI 3.141592
|
||||
|
||||
#define FOG_DENSITY 0.01
|
||||
|
||||
uniform vec2 u_resolution;
|
||||
uniform float u_time;
|
||||
|
||||
struct Obj {
|
||||
float distance; // distance map
|
||||
int material; // material Id
|
||||
};
|
||||
|
||||
|
||||
mat2 Rot(float a) {
|
||||
float s=sin(a), c=cos(a);
|
||||
return mat2(c, -s, s, c);
|
||||
}
|
||||
|
||||
vec3 applyFog(in vec3 color, in float distance) {
|
||||
|
||||
float fogAmount = 1.0 - exp(-distance*FOG_DENSITY);
|
||||
vec3 fogColor = vec3(0.17, 0.16, 0.24);
|
||||
return mix( color, fogColor, fogAmount );
|
||||
}
|
||||
|
||||
float opExtrusion( in vec3 p, in float sdf, in float h )
|
||||
{
|
||||
vec2 w = vec2( sdf, abs(p.z) - h);
|
||||
return min(max(w.x,w.y),0.0) + length(max(w,0.0));
|
||||
}
|
||||
|
||||
float sdCog2d(vec2 pos) {
|
||||
float r = length(pos)*2.;
|
||||
float a = atan(pos.y,pos.x);
|
||||
float f = 1. - smoothstep(-0.2, .8, sin(a * 12.))*0.14;
|
||||
f = smoothstep(f,f + 2.,r);
|
||||
return f;
|
||||
}
|
||||
|
||||
float opSmoothSubtraction( float d1, float d2, float k )
|
||||
{
|
||||
float h = max(k-abs(-d1-d2),0.0);
|
||||
return max(-d1, d2) + h*h*0.25/k;
|
||||
}
|
||||
|
||||
float sdCapsule( vec3 p, vec3 a, vec3 b, float r )
|
||||
{
|
||||
vec3 pa = p - a, ba = b - a;
|
||||
float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
|
||||
return length( pa - ba*h ) - r;
|
||||
}
|
||||
|
||||
float sdCog(vec3 pos, float angle) {
|
||||
pos.xy *= Rot(angle);
|
||||
float d1 = opExtrusion(pos, sdCog2d(pos.xy), 0.15);
|
||||
float d2 = sdCapsule(pos - vec3(0.,0., -0.5), vec3(0., 0.0, 0.), vec3(0., 0., 1.), 0.2);
|
||||
return 0.8 * opSmoothSubtraction(d2,d1,0.02)-0.001;
|
||||
}
|
||||
|
||||
|
||||
// Scene
|
||||
Obj mapScene(in vec3 p) {
|
||||
float d = 1e10;
|
||||
|
||||
float dGround = p.y +1.5 + sin(p.z*0.6)*.2 + sin(p.x*1.3)*.1;
|
||||
Obj ground = Obj(dGround, 0);
|
||||
|
||||
{
|
||||
float d1 = sdCog(p+vec3(1., 0., 0.), u_time);
|
||||
d = min(d, d1);
|
||||
}
|
||||
{
|
||||
float d1 = sdCog(p+vec3(0.5, -.87, 0.), -u_time);
|
||||
d = min(d, d1);
|
||||
}
|
||||
{
|
||||
float d1 = sdCog(p+vec3(0.5, .87, 0.), -u_time);
|
||||
d = min(d, d1);
|
||||
}
|
||||
Obj ob1 = Obj(d, 1);
|
||||
|
||||
if (ground.distance > ob1.distance) return ob1;
|
||||
return ground;
|
||||
}
|
||||
|
||||
Obj castRay(vec3 ro, vec3 rd) {
|
||||
float t = 0.0;
|
||||
|
||||
Obj res = Obj(-1., -1);
|
||||
for(int i=0; i<MAX_STEPS; i++) {
|
||||
vec3 p = ro + rd * t;
|
||||
res = mapScene(p);
|
||||
t += res.distance;
|
||||
if (t > MAX_DIST || res.distance < abs(SURF_DIST*t) ) break;
|
||||
}
|
||||
if (t > MAX_DIST) t = -1.0;
|
||||
res.distance = t;
|
||||
return res;
|
||||
}
|
||||
|
||||
float castShadow(vec3 ro, vec3 rd) {
|
||||
float res = 1.0;
|
||||
float t = 0.001;
|
||||
for(int i = 0; i < MAX_STEPS; i++) {
|
||||
vec3 pos = ro + t* rd;
|
||||
float h = mapScene(pos).distance;
|
||||
res = min(res, 10.0*h/t);
|
||||
if (abs(h) < (0.001*t) ) break;
|
||||
t += h;
|
||||
if (t > 20.) break;
|
||||
}
|
||||
return clamp(res,0., 1.);
|
||||
}
|
||||
|
||||
vec3 calcNormal(vec3 pos) {
|
||||
vec2 e = vec2(.001, 0.);
|
||||
vec3 n = vec3( mapScene(pos+e.xyy).distance - mapScene(pos-e.xyy).distance,
|
||||
mapScene(pos+e.yxy).distance - mapScene(pos-e.yxy).distance,
|
||||
mapScene(pos+e.yyx).distance - mapScene(pos-e.yyx).distance
|
||||
);
|
||||
return normalize(n);
|
||||
}
|
||||
|
||||
vec3 fresnel( vec3 F0, vec3 h, vec3 l ) {
|
||||
return F0 + ( 1.0 - F0 ) * pow( clamp( 1.0 - dot( h, l ), 0.0, 1.0 ), 5.0 );
|
||||
}
|
||||
|
||||
|
||||
vec3 shading(vec3 v, vec3 n, vec3 dir, int material) {
|
||||
float shininess = 1.;
|
||||
vec3 final = vec3( 0.0 );
|
||||
vec3 ref = reflect( dir, n );
|
||||
vec3 Ks = vec3( 0.5 );
|
||||
vec3 Kd = vec3( 1.0 );
|
||||
vec3 outMaterial = vec3(0.1255, 0.1255, 0.1255);
|
||||
|
||||
if (material == 0) {
|
||||
outMaterial = vec3(0.1412, 0.1412, 0.1412);
|
||||
shininess = 3.1;
|
||||
} else if (material == 1) {
|
||||
outMaterial = vec3(0.1765, 0.1961, 0.2275);
|
||||
shininess = 21.;
|
||||
}
|
||||
|
||||
// light 0
|
||||
{
|
||||
vec3 light_pos = vec3( -2.,.3, 10. );
|
||||
vec3 light_color = vec3(0.71, 0.51, 0.72) * 5.;
|
||||
|
||||
vec3 vl = normalize( light_pos - v );
|
||||
|
||||
vec3 diffuse = Kd * vec3( max( 0.0, dot( vl, n ) ) );
|
||||
vec3 specular = vec3( max( 0.0, dot( vl, ref ) ) );
|
||||
|
||||
vec3 F = fresnel( Ks, normalize( vl - dir ), vl );
|
||||
specular = pow( specular, vec3( shininess ) );
|
||||
final += outMaterial * specular * light_color * mix( diffuse, specular, F );
|
||||
}
|
||||
|
||||
// light 1
|
||||
{
|
||||
vec3 light_pos = vec3( 5.0, 5.0, -20.0 );
|
||||
vec3 light_color = vec3(0.14, 0.36, 0.83)* 7.;
|
||||
|
||||
vec3 vl = normalize( light_pos - v );
|
||||
|
||||
vec3 diffuse = Kd * vec3( max( 0.0, dot( vl, n ) ) );
|
||||
vec3 specular = vec3( max( 0.0, dot( vl, ref ) ) );
|
||||
|
||||
vec3 F = fresnel( Ks, normalize( vl - dir ), vl );
|
||||
specular = pow( specular, vec3( shininess ) );
|
||||
|
||||
final += outMaterial * specular * light_color * mix( diffuse, specular, F );
|
||||
}
|
||||
{
|
||||
vec3 SUN_DIR = vec3(0. , .4, 1.);
|
||||
float sun_dif = clamp(dot(n, SUN_DIR), 0., 1.);
|
||||
float shadow = castShadow(v + n*0.02, SUN_DIR);
|
||||
final += outMaterial * vec3(1.1,1.2, 1.5) * sun_dif * sun_dif * shadow;
|
||||
}
|
||||
{
|
||||
vec3 SUN_DIR = vec3(0. , .6, -1.);
|
||||
float sun_dif = clamp(dot(n, SUN_DIR), 0., 1.);
|
||||
final += outMaterial * vec3(0.0353, 0.2667, 0.4784) * sun_dif;
|
||||
}
|
||||
// final += texture( iChannel0, ref ).rgb * fresnel( Ks, n, -dir );
|
||||
// vec3 col = vec3(0.4)* ref.x;
|
||||
//vec3 col = vec3(0.0588, 0.0588, 0.1216);// - vec3(0.149, 0.0863, 0.2314) * v.x;
|
||||
//final += col * fresnel( vec3(.5), ref, -dir );
|
||||
|
||||
return final;
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = (2.0 * gl_FragCoord.xy - u_resolution.xy) / u_resolution.y;
|
||||
float angle = u_time*0.4;
|
||||
// angle = 2.0; // comment to rotate
|
||||
// gl_FragColor = vec4(vec3(sdCog2d(p)), 1.);
|
||||
// return;
|
||||
// camera
|
||||
vec3 ta = vec3(0.0, 0., 0.0);
|
||||
vec3 ro = ta + vec3(4.*sin(angle), cos(angle), 4.*cos(angle)); // *cos(angle))
|
||||
|
||||
vec3 ww = normalize(ta-ro);
|
||||
vec3 uu = normalize(cross(ww, vec3(0,1,0)));
|
||||
vec3 vv = normalize(cross(uu,ww));
|
||||
|
||||
vec3 rd = normalize(p.x * uu + p.y*vv + 1.4*ww); // camera
|
||||
|
||||
// global light
|
||||
vec3 col = vec3(0.1451, 0.1098, 0.1608) - vec3(0.9725, 0.5176, 0.0) *rd.y;
|
||||
Obj t = castRay(ro, rd);
|
||||
|
||||
if (t.distance > 0.) {
|
||||
vec3 pos = ro + rd * t.distance;
|
||||
vec3 nor = calcNormal(pos);
|
||||
col = shading(pos, nor, rd , t.material);
|
||||
// apply fog
|
||||
col = applyFog(col, t.distance);
|
||||
}
|
||||
|
||||
gl_FragColor = vec4( pow( col, vec3(1.0/1.3) ), 1.0 );
|
||||
}
|
||||
Reference in New Issue
Block a user