testing shader fragments
This commit is contained in:
174
sea.frag
Normal file
174
sea.frag
Normal file
@ -0,0 +1,174 @@
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
#define MAX_STEPS 100
|
||||
#define MAX_DIST 80.
|
||||
#define SURF_DIST .001
|
||||
#define TAU 6.283185
|
||||
#define PI 3.141592
|
||||
|
||||
//#define SUN_DIR vec3(0.5, 0.4, 2.)
|
||||
#define FOG_DENSITY 0.02
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
float sdBox(vec3 p, vec3 s) {
|
||||
p = abs(p)-s;
|
||||
return length(max(p, 0.))+min(max(p.x, max(p.y, p.z)), 0.);
|
||||
}
|
||||
|
||||
vec3 applyFog(in vec3 color, in float distance) {
|
||||
|
||||
float fogAmount = 1.0 - exp(-distance*FOG_DENSITY);
|
||||
vec3 fogColor = vec3(0.1, 0.18, 0.43);
|
||||
return mix( color, fogColor, fogAmount );
|
||||
}
|
||||
|
||||
vec3 translate(vec3 p) {
|
||||
p.xy *= Rot(u_time*0.4);
|
||||
p.yz *= Rot(u_time*0.4);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
vec2 opRevolution( in vec3 p, float w )
|
||||
{
|
||||
return vec2( length(p.xz) - w, p.y );
|
||||
}
|
||||
|
||||
vec4 opElongate( in vec3 p, in vec3 h )
|
||||
{
|
||||
vec3 q = abs(p)-h;
|
||||
return vec4( max(q,0.0), min(max(q.x,max(q.y,q.z)),0.0) );
|
||||
}
|
||||
|
||||
|
||||
// Scene
|
||||
Obj mapScene(vec3 p) {
|
||||
|
||||
vec3 p0 = p;
|
||||
|
||||
float dGround = p.y - 0.5*(sin(0.4*p.x+u_time*1.)+sin(1.0*p.z+u_time*1.));
|
||||
dGround *=0.8;
|
||||
|
||||
Obj ground = Obj(dGround, 0);
|
||||
|
||||
|
||||
p0.y = dGround + 0.1;
|
||||
|
||||
float d1 = length(p0) - 0.3;
|
||||
Obj ob1 = Obj(d1, 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.0001;
|
||||
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(.0001, 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);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = (2.0 * gl_FragCoord.xy - u_resolution.xy) / u_resolution.y;
|
||||
float angle = u_time*0.2;
|
||||
angle = 4.6; // comment to rotate
|
||||
|
||||
// camera
|
||||
vec3 ta = vec3(0.0, .5, 0.0);
|
||||
vec3 ro = ta + vec3(1.*sin(angle), .7, 2.); // *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.3*ww); // camera
|
||||
|
||||
// global light
|
||||
vec3 col = vec3(0.1216, 0.2863, 0.5529) - 0.5*rd.y;
|
||||
Obj t = castRay(ro, rd);
|
||||
|
||||
if (t.distance > 0.) {
|
||||
vec3 pos = ro + rd * t.distance;
|
||||
vec3 nor = calcNormal(pos);
|
||||
// vec3 r = reflect(rd, nor);
|
||||
vec3 outMaterial = vec3(0.1255, 0.1176, 0.1176);
|
||||
|
||||
if (t.material == 0) {
|
||||
outMaterial = vec3(0.0039, 0.2235, 0.4) + sin(t.distance)*0.1;
|
||||
} else if (t.material == 1) {
|
||||
outMaterial = vec3(0.8392, 0.0118, 0.0118);
|
||||
}
|
||||
vec3 SUN_DIR = vec3(0.5+sin(u_time*0.1), 0.4, 2.0+sin(u_time*0.2)*0.5);
|
||||
|
||||
float sun_dif = clamp(dot(nor, SUN_DIR), 0., 1.);
|
||||
float sun_sha = castShadow(pos + nor*0.02, SUN_DIR);
|
||||
float sky_dif = clamp(0.5 + 0.5 * dot(nor, vec3(0.,1.,0.)), 0., 1.);
|
||||
float bounce_dif = clamp(0.5 + 0.5 * dot(nor, vec3(.7,.5, 0.)), 0., 1.);
|
||||
|
||||
// format color + what to apply
|
||||
col = outMaterial * vec3(2.0,1.5, .2) * sun_dif * sun_dif * sun_sha;
|
||||
col += outMaterial * vec3(0.0196, 0.2078, 0.4196) * sky_dif;
|
||||
col += outMaterial * vec3(0.051, 0.0588, 0.5686) * bounce_dif;
|
||||
|
||||
// apply fog
|
||||
col = applyFog(col, t.distance);
|
||||
}
|
||||
|
||||
col = pow(col, vec3(.4545)); // gamma correction
|
||||
|
||||
gl_FragColor = vec4(col,1.0);
|
||||
}
|
||||
Reference in New Issue
Block a user