3 uniform mat3 dirmatrix;
5 #define DIST_THRES 1e-3
9 vec3 raymarch(inout vec3 p, in vec3 dir, out float depth);
10 vec3 shade(in vec3 p, in vec3 dir, in float dist, in float total_dist);
11 vec3 backdrop(in vec3 dir);
12 float eval_sdf(in vec3 p);
13 vec3 eval_grad(in vec3 p, float dist);
14 vec3 primray(in vec2 uv, out vec3 org);
16 float boxdist(in vec3 p, in vec3 b);
17 float sphdist(in vec3 p, in vec3 sp, in float srad);
21 vec2 uv = gl_TexCoord[0].st;
23 vec3 rdir = primray(uv, rorg);
26 gl_FragColor.rgb = raymarch(rorg, rdir, depth);
29 vec4 projp = gl_ProjectionMatrix * vec4(0.0, 0.0, -depth, 1.0);
30 float zval = projp.z / projp.w;
35 vec3 raymarch(inout vec3 p, in vec3 dir, out float depth)
37 float d, total_d = 0.0;
39 for(int i=0; i<MAX_ITER; i++) {
40 if((d = eval_sdf(p)) <= DIST_THRES) {
42 return shade(p, dir, d, total_d);
51 depth = -gl_DepthRange.far;
55 vec3 shade(in vec3 p, in vec3 dir, in float dist, in float total_dist)
57 const vec3 kd = vec3(1.0, 0.3, 0.1);
58 const vec3 ks = vec3(0.7, 0.7, 0.7);
59 const vec3 ldir = normalize(vec3(-1.0, 1.0, -1.5));
60 const vec3 vdir = vec3(0.0, 0.0, -1.0);
62 vec3 diffuse = vec3(0.0, 0.0, 0.0);
63 vec3 specular = vec3(0.0, 0.0, 0.0);
65 vec3 n = eval_grad(p, dist);
67 vec3 hdir = normalize(ldir + vdir);
69 float ndotl = max(dot(n, ldir), 0.0);
70 float ndoth = max(dot(n, hdir), 0.0);
72 diffuse += kd * ndotl;
73 specular += ks * pow(ndoth, 50.0);
75 float fog = clamp(300.0 / (total_dist * total_dist), 0.0, 1.0);
77 return mix(backdrop(dir), diffuse + specular, fog);
80 vec3 backdrop(in vec3 dir)
82 return vec3(0.1, 0.1, 0.1);
86 vec3 eval_grad(in vec3 p, float dist)
88 float dfdx = eval_sdf(p + vec3(DELTA, 0.0, 0.0)) - dist;
89 float dfdy = eval_sdf(p + vec3(0.0, DELTA, 0.0)) - dist;
90 float dfdz = eval_sdf(p + vec3(0.0, 0.0, DELTA)) - dist;
91 return normalize(vec3(dfdx, dfdy, dfdz));
94 vec3 primray(in vec2 uv, out vec3 org)
96 vec3 origin = (gl_ModelViewMatrixInverse * vec4(0.0, 0.0, 0.0, 1.0)).xyz;
99 vec2 nuv = uv * 2.0 - 1.0;
100 vec4 cp_near = vec4(nuv, -1.0, 1.0);
102 vec4 vdir = gl_ProjectionMatrixInverse * cp_near;
103 vec4 wdir = gl_ModelViewMatrixInverse * vec4(vdir.xyz, 0.0);
105 return normalize(wdir.xyz);
108 float boxdist(in vec3 p, in vec3 b)
111 return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0);
114 float sphdist(in vec3 p, in vec3 sp, in float srad)
116 return length(p - sp) - srad;