bloboland
diff sdr/bloboray.p.glsl @ 4:9021a906c5d3
lots of stuff
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 18 Dec 2012 06:13:09 +0200 |
parents | a39c301cdcce |
children | 2f4406cc341e |
line diff
1.1 --- a/sdr/bloboray.p.glsl Sun Dec 16 14:24:16 2012 +0200 1.2 +++ b/sdr/bloboray.p.glsl Tue Dec 18 06:13:09 2012 +0200 1.3 @@ -12,32 +12,60 @@ 1.4 float t0, t1; 1.5 vec3 pos, normal; 1.6 vec4 color; 1.7 + vec3 refl; 1.8 }; 1.9 1.10 vec3 shade(Ray ray, HitPoint hit); 1.11 -HitPoint intersect_voxels(Ray ray); 1.12 +vec3 sky(Ray ray); 1.13 +HitPoint ray_march(Ray ray); 1.14 +float eval_blobs(vec3 pt); 1.15 +vec3 calc_blob_normal(vec3 pt); 1.16 HitPoint intersect_aabb(Ray ray, AABBox aabb); 1.17 Ray get_primary_ray(float x, float y); 1.18 +float luminance(vec3 col); 1.19 +float fresnel(float r, float cosa); 1.20 +vec3 get_blob(int i); 1.21 1.22 -#define RAY_STEP 0.001 1.23 +#define BLOB_THRESHOLD 0.5 1.24 +#define BLOB_SCALE (1.0 / 4.0) 1.25 +#define MAX_ITER 1 1.26 + 1.27 +#define RAY_STEP (0.75 / volsize.z) 1.28 1.29 #define FOV camprop.x 1.30 #define ASPECT camprop.y 1.31 uniform vec4 camprop; 1.32 uniform vec3 volsize; 1.33 uniform sampler3D voltex; 1.34 +uniform vec3 worldsize; 1.35 1.36 -//const vec3 worldsize = vec3(4.0, 4.0, 2.0); 1.37 -const vec3 worldsize = vec3(1.0, 1.0, 0.5); 1.38 +uniform sampler1D blobtex; 1.39 +uniform int num_blobs; 1.40 1.41 void main() 1.42 { 1.43 Ray ray = get_primary_ray(gl_TexCoord[0].x, gl_TexCoord[0].y); 1.44 1.45 + HitPoint hit; 1.46 vec3 color = vec3(0.0, 0.0, 0.0); 1.47 - HitPoint hit = intersect_voxels(ray); 1.48 - if(hit.hit) { 1.49 - color = shade(ray, hit); 1.50 + vec3 power = vec3(1.0, 1.0, 1.0); 1.51 + 1.52 + for(int i=0; i<=MAX_ITER; i++) { 1.53 + hit = ray_march(ray); 1.54 + if(hit.hit) { 1.55 + color += shade(ray, hit) * power; 1.56 + } else { 1.57 + color += sky(ray) * power; 1.58 + break; 1.59 + } 1.60 + 1.61 + ray.origin = hit.pos + hit.normal * RAY_STEP; 1.62 + ray.dir = reflect(ray.dir, hit.normal); 1.63 + power *= hit.refl; 1.64 + 1.65 + if(luminance(power) < 0.075) { 1.66 + break; 1.67 + } 1.68 } 1.69 1.70 gl_FragColor = vec4(color, 1.0); 1.71 @@ -55,9 +83,30 @@ 1.72 float ndoth = max(dot(hit.normal, hvec), 0.0); 1.73 1.74 vec3 diffuse = hit.color.xyz * ndotl; 1.75 - vec3 specular = vec3(0.4, 0.4, 0.4) * pow(ndoth, 60.0); 1.76 + vec3 specular = hit.refl * pow(ndoth, 60.0); 1.77 1.78 - return diffuse + specular; 1.79 + vec3 color = diffuse + specular; 1.80 + 1.81 + float fog = 0.0;//smoothstep(4.0, 8.0, hit.t0); 1.82 + 1.83 + //const float fog_density = 0.18; 1.84 + //float fog = exp(-fog_density * fog_density * hit.t0 * hit.t0); 1.85 + //fog = clamp(fog, 0.0, 1.0); 1.86 + 1.87 + return mix(color, sky(ray), fog); 1.88 +} 1.89 + 1.90 +#define M_PI 3.141592653 1.91 + 1.92 +vec3 sky(Ray ray) 1.93 +{ 1.94 + const vec3 horiz = vec3(0.64, 0.70, 0.76); 1.95 + const vec3 zenith = vec3(0.65, 0.82, 0.94); 1.96 + 1.97 + float angle = acos(ray.dir.y); 1.98 + float t = 1.0 - angle / (M_PI / 2.0); 1.99 + 1.100 + return mix(horiz, zenith, smoothstep(-0.2, 0.2, t)); 1.101 } 1.102 1.103 vec4 fetch_voxel(vec3 pt) 1.104 @@ -68,7 +117,7 @@ 1.105 1.106 vec3 calc_voxel_normal(vec3 pt) 1.107 { 1.108 - vec3 offs = 1.8 / volsize; 1.109 + vec3 offs = 6.0 / volsize; 1.110 float dfdx = fetch_voxel(pt + vec3(offs.x, 0.0, 0.0)).w - fetch_voxel(pt - vec3(offs.x, 0.0, 0.0)).w; 1.111 float dfdy = fetch_voxel(pt + vec3(0.0, offs.y, 0.0)).w - fetch_voxel(pt - vec3(0.0, offs.y, 0.0)).w; 1.112 float dfdz = fetch_voxel(pt + vec3(0.0, 0.0, offs.z)).w - fetch_voxel(pt - vec3(0.0, 0.0, offs.z)).w; 1.113 @@ -76,12 +125,17 @@ 1.114 return -normalize(vec3(dfdx, dfdy, dfdz)); 1.115 } 1.116 1.117 -HitPoint intersect_voxels(Ray ray) 1.118 +HitPoint ray_march(Ray ray) 1.119 { 1.120 HitPoint hit; 1.121 //AABBox aabb = AABBox(vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0)); 1.122 AABBox aabb = AABBox(-worldsize.xzy, worldsize.xzy); 1.123 1.124 + hit.hit = false; 1.125 + hit.t0 = hit.t1 = 0.0; 1.126 + hit.pos = hit.normal = vec3(0.0, 0.0, 0.0); 1.127 + hit.color = vec4(1.0, 1.0, 1.0, 1.0); 1.128 + 1.129 1.130 hit = intersect_aabb(ray, aabb); 1.131 if(!hit.hit) { 1.132 @@ -96,14 +150,25 @@ 1.133 1.134 while(dist < end_dist) { 1.135 vec3 pt = ray.origin + ray.dir * dist; 1.136 + 1.137 + // first try evaluating the blob field at this point 1.138 + float blob = eval_blobs(pt); 1.139 + if(blob >= BLOB_THRESHOLD) { 1.140 + hit.t0 = dist; 1.141 + hit.pos = pt; 1.142 + hit.normal = calc_blob_normal(pt); 1.143 + hit.color = vec4(0.0, 0.0, 0.0, 1.0); 1.144 + hit.refl = vec3(1.0, 0.9, 0.75); 1.145 + return hit; 1.146 + } 1.147 + 1.148 vec4 voxel = fetch_voxel(pt.xzy); 1.149 - 1.150 - 1.151 if(voxel.a > 0.5) { 1.152 hit.t0 = dist; 1.153 hit.pos = pt; 1.154 hit.normal = calc_voxel_normal(pt.xzy).xzy; 1.155 hit.color = voxel; 1.156 + hit.refl = vec3(0.0, 0.0, 0.0); 1.157 return hit; 1.158 } 1.159 1.160 @@ -114,24 +179,48 @@ 1.161 return hit; 1.162 } 1.163 1.164 +float eval_blobs(vec3 pt) 1.165 +{ 1.166 + float val = 0.0; 1.167 + 1.168 + for(int i=0; i<num_blobs; i++) { 1.169 + float dist = length(pt - get_blob(i)); 1.170 + val += (dist * dist * (3.0 - 2.0 * dist)); 1.171 + } 1.172 + return val; 1.173 +} 1.174 + 1.175 +vec3 calc_blob_normal(vec3 pt) 1.176 +{ 1.177 + const float offs = 0.01; 1.178 + vec3 grad; 1.179 + grad.x = eval_blobs(pt + vec3(offs, 0.0, 0.0)) - eval_blobs(pt - vec3(offs, 0.0, 0.0)); 1.180 + grad.y = eval_blobs(pt + vec3(0.0, offs, 0.0)) - eval_blobs(pt - vec3(0.0, offs, 0.0)); 1.181 + grad.z = eval_blobs(pt + vec3(0.0, 0.0, offs)) - eval_blobs(pt - vec3(0.0, 0.0, offs)); 1.182 + 1.183 + return -normalize(grad); 1.184 +} 1.185 + 1.186 HitPoint intersect_aabb(Ray ray, AABBox aabb) 1.187 { 1.188 HitPoint res; 1.189 1.190 + res.pos = res.normal = vec3(0.0, 0.0, 0.0); 1.191 + res.color = vec4(1.0, 1.0, 1.0, 1.0); 1.192 + res.refl = vec3(0.0, 0.0, 0.0); 1.193 + 1.194 vec3 invR = 1.0 / ray.dir; 1.195 - vec3 tbot = invR * (aabb.vmin - ray.origin); 1.196 - vec3 ttop = invR * (aabb.vmax - ray.origin); 1.197 - vec3 tmin = min(ttop, tbot); 1.198 - vec3 tmax = max(ttop, tbot); 1.199 - vec2 t = max(tmin.xx, tmin.yz); 1.200 - float t0 = max(t.x, t.y); 1.201 - t = min(tmax.xx, tmax.yz); 1.202 - float t1 = min(t.x, t.y); 1.203 + vec3 tbot = invR * (aabb.vmin - ray.origin); 1.204 + vec3 ttop = invR * (aabb.vmax - ray.origin); 1.205 + vec3 tmin = min(ttop, tbot); 1.206 + vec3 tmax = max(ttop, tbot); 1.207 + vec2 t = max(tmin.xx, tmin.yz); 1.208 + res.t0 = max(t.x, t.y); 1.209 + t = min(tmax.xx, tmax.yz); 1.210 + res.t1 = min(t.x, t.y); 1.211 1.212 - if(t0 <= t1) { 1.213 + if(res.t0 <= res.t1) { 1.214 res.hit = true; 1.215 - res.t0 = t0; 1.216 - res.t1 = t1; 1.217 } else { 1.218 res.hit = false; 1.219 } 1.220 @@ -150,3 +239,24 @@ 1.221 ray.dir = gl_NormalMatrix * normalize(dir); 1.222 return ray; 1.223 } 1.224 + 1.225 +float luminance(vec3 col) 1.226 +{ 1.227 + //const vec3 fact = vec3(0.2126, 0.7152, 0.0722); 1.228 + //return dot(col, fact); 1.229 + return (col.x + col.y + col.z) / 3.0; 1.230 +} 1.231 + 1.232 +float fresnel(float r, float cosa) 1.233 +{ 1.234 + float inv_cosa = 1.0 - cosa; 1.235 + float inv_cosa_sq = inv_cosa * inv_cosa; 1.236 + 1.237 + return r + (1.0 - r) * inv_cosa_sq * inv_cosa_sq * inv_cosa; 1.238 +} 1.239 + 1.240 +vec3 get_blob(int i) 1.241 +{ 1.242 + float tc = float(i) / float(num_blobs); 1.243 + return texture1D(blobtex, tc).xyz; 1.244 +}