转载自: http://glslsandbox.com/e#44314.0
precision highp float;
uniform vec2 resolution; // resolution (width, height)
uniform vec2 mouse; // mouse (0.0 ~ 1.0)
uniform float time; // time (1second == 1.0)
uniform sampler2D backbuffer; // previous scene texture
const vec3 V=vec3(.001,25,0);
const vec3 L=vec3(0,.707,.707);
const vec3 Amb=vec3(0,1,0);
const vec3 BG=vec3(0.0);
const vec3 PI = vec3(1.5707963,3.1415927,6.2831853);
vec2 uv(){return(gl_FragCoord.xy*2.-resolution)/resolution.y;}
vec4 bb(){return texture2D(backbuffer,gl_FragCoord.xy/resolution);}
vec4 gamna(vec3 c){return vec4(pow(c,vec3(1./2.2)),1);}
float rnd(vec3 s){s=fract(s*443.8975);s+=dot(s,s.yzx+19.19);return fract((s.x+s.y)*s.z);}
vec3 hsv(float h,float s,float v){return((clamp(abs(fract(h+vec3(0,2,1)/3.)*6.-3.)-1.,0.,1.)-1.)*s+1.)*v;}
vec2 circle(float a){return vec2(cos(a),sin(a));}
float smin(float a, float b, float k){return -log(exp(-k*a)+exp(-k*b))/k;}
mat3 camera(vec3 p, vec3 t, vec3 h){vec3 w=normalize(p-t),u=normalize(cross(w,h));return mat3(u,normalize(cross(u,w)),w);}
mat3 euler(float h, float p, float r){float a=sin(h),b=sin(p),c=sin(r),d=cos(h),e=cos(p),f=cos(r);return mat3(f*e,c*e,-b,f*b*a-c*d,f*d+c*b*a,e*a,c*a+f*b*d,c*b*d-f*a,e*d);}
vec3 dlight(vec3 n, vec3 l, vec3 c){return clamp((dot(n,l)+1.)*.5,0.,1.)*c;}
float checker(vec3 u, vec3 s){return mod(floor(u.x/s.x)+floor(u.y/s.y)+floor(u.z/s.z),2.);}
float fresnel(float r, float dp) {return r+(1.-r)*pow(1.-abs(dp),5.);}
vec2 doKaleido(vec2 uv){ return abs(mat2(1,1.732,1,-1.732)*abs(fract(mat2(1.,-1.,-1.732,-1.732)*uv+.5)-.5)); }
float efExpIO(float t, float m){return (t<.5)?(.5*exp(m*(t-.5))):(1.-.5*exp(m*(.5-t)));}
float dfPln(vec3 p, vec3 n, float d){return dot(p,n)+d;}
float dfBox(vec3 p, vec3 b, float r){return length(max(abs(p)-b,0.))-r;}
float map(in vec3 p) {
return min(dfPln(p, vec3(0,1,0), 0.), dfBox(p-vec3(0,.2,0), vec3(.15), .04));
}
vec3 background(vec3 pos, vec3 dir, inout float bld) {
bld = 0.;
return BG;
}
float shadow(vec3 pos, vec3 lit) {
float s=V.y, t=.1;
for (int i=10; i!=0; --i) {
float d = map(pos + lit * t);
t += max(d, .1);
s = min(s, d*.5/t);
if (d<V.x || t>V.y) break;
}
return clamp(s, 0., 1.);
}
float occlusion(vec3 pos, in vec3 nml) {
float s=0.;
for (int i=5; i!=0; --i) {
float t = .01 + float(i) * .3;
float d = map(pos + nml * t);
s += t - d;
}
return clamp(1.-s*.2, 0., 1.);
}
vec3 trace(inout vec3 pos, inout vec3 dir, inout float bld) {
float t = 0.;
for (int i=50; i!=0; --i) {
float d = map(pos + dir * t);
t += d;
if (d < V.x) break;
if (t > V.y) return bld * background(pos, dir, bld);
}
vec3 p = pos + dir * t;
vec3 n = normalize(vec3(map(p+V.xzz),map(p+V.zxz),map(p+V.zzx))-map(p));
vec3 lit = normalize(vec3(sin(time*2.)*3.,sin(time*.5)+2.,cos(time*2.)*3.) - p);
vec3 c = (dlight(n,lit,vec3(1)) * shadow(p, lit) + dlight(n,Amb,vec3(.1))) * occlusion(p, n);
return mix(c, BG, clamp((length(p.xz)-1.)/10.,0.,1.))*bld;
}
vec3 render(in vec3 pos, in vec3 dir) {
float b = 1.;
vec3 col = trace(pos, dir, b);
//if (b > V.x) col += trace(pos, dir, b);
//if (b > V.x) col += trace(pos, dir, b);
return col;
}
void main(){
vec3 pos = vec3(sin(time)*3.5,1.5,cos(time)*3.5);
vec3 dir = camera(pos, vec3(0,0,0), vec3(0,1,0)) * normalize(vec3(uv(),-1.732));
gl_FragColor = gamna(render(pos, dir));
}