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 +}