qvolray

changeset 7:f40e4edfee7e

shading
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 05 Apr 2012 00:52:11 +0300
parents 04316e9e95dc
children ae10631bb11b
files src/volray.c volray.p.glsl
diffstat 2 files changed, 44 insertions(+), 50 deletions(-) [+]
line diff
     1.1 --- a/src/volray.c	Wed Apr 04 01:37:58 2012 +0300
     1.2 +++ b/src/volray.c	Thu Apr 05 00:52:11 2012 +0300
     1.3 @@ -54,11 +54,12 @@
     1.4  int raytex_needs_recalc = 1;
     1.5  
     1.6  unsigned int xfer_tex;
     1.7 -float xfer_mean = 0.5, xfer_sdev = 1.0;
     1.8 +float xfer_mean = 0.7, xfer_sdev = 0.1;
     1.9  int xfertex_needs_recalc = 1;
    1.10  
    1.11  static int uimode;
    1.12 -static float cur_z = 0.5;
    1.13 +static float cur_z = 0.0;
    1.14 +static float ray_step = 0.01;
    1.15  
    1.16  int main(int argc, char **argv)
    1.17  {
    1.18 @@ -99,6 +100,8 @@
    1.19  	set_uniform_int(vol_sdr, "volume", 0);
    1.20  	set_uniform_int(vol_sdr, "ray_tex", 1);
    1.21  	set_uniform_int(vol_sdr, "xfer_tex", 2);
    1.22 +	set_uniform_float(vol_sdr, "ray_step", ray_step);
    1.23 +	set_uniform_float(vol_sdr, "zclip", cur_z);
    1.24  
    1.25  	if(!(slice_sdr = create_program_load(0, "slice.p.glsl"))) {
    1.26  		return -1;
    1.27 @@ -127,7 +130,7 @@
    1.28  
    1.29  		if(i == 0) {
    1.30  			/* allocate storage for the texture */
    1.31 -			glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, xsz, ysz, nslices, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    1.32 +			glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA32F, xsz, ysz, nslices, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    1.33  
    1.34  			vol_xsz = xsz;
    1.35  			vol_ysz = ysz;
    1.36 @@ -388,6 +391,8 @@
    1.37  			cur_z = 0.0;
    1.38  		if(cur_z > 1.0)
    1.39  			cur_z = 1.0;
    1.40 +
    1.41 +		set_uniform_float(vol_sdr, "zclip", cur_z);
    1.42  		glutPostRedisplay();
    1.43  		break;
    1.44  
     2.1 --- a/volray.p.glsl	Wed Apr 04 01:37:58 2012 +0300
     2.2 +++ b/volray.p.glsl	Thu Apr 05 00:52:11 2012 +0300
     2.3 @@ -1,6 +1,8 @@
     2.4  uniform sampler3D volume;
     2.5  uniform sampler2D ray_tex;
     2.6  uniform sampler1D xfer_tex;
     2.7 +uniform float ray_step;
     2.8 +uniform float zclip;
     2.9  
    2.10  struct Ray {
    2.11  	vec3 origin, dir;
    2.12 @@ -12,14 +14,14 @@
    2.13  
    2.14  struct ISect {
    2.15  	bool hit;
    2.16 -	float t;
    2.17 +	float t0, t1;
    2.18  	vec3 pos;
    2.19  	vec3 normal;
    2.20  };
    2.21  
    2.22  vec3 sky(Ray ray);
    2.23 -vec3 ray_march(Ray ray);
    2.24 -vec3 shade(Ray ray, ISect isect);
    2.25 +vec3 ray_march(Ray ray, float t0, float t1);
    2.26 +vec3 shade(Ray ray, vec3 pos, vec3 norm);
    2.27  Ray get_primary_ray();
    2.28  ISect intersect_aabb(Ray ray, AABBox aabb);
    2.29  
    2.30 @@ -32,38 +34,44 @@
    2.31  
    2.32  	ISect res = intersect_aabb(ray, aabb);
    2.33  	if(res.hit) {
    2.34 -		ray.origin += ray.dir * res.t;
    2.35 -		color = ray_march(ray);
    2.36 +		color = ray_march(ray, res.t0, res.t1);
    2.37  	}
    2.38  
    2.39  	gl_FragColor = vec4(color, 1.0);
    2.40  }
    2.41  
    2.42 -vec3 sky(Ray ray)
    2.43 -{
    2.44 -	vec3 col1 = vec3(0.75, 0.78, 0.8);
    2.45 -	vec3 col2 = vec3(0.56, 0.7, 1.0);
    2.46 -
    2.47 -	float t = max(ray.dir.y, -0.5);
    2.48 -	return mix(col1, col2, t);
    2.49 -}
    2.50 -
    2.51  float eval(vec3 pos)
    2.52  {
    2.53  	vec3 tc = pos * 0.5 + 0.5;
    2.54 +
    2.55 +	if(tc.x < 0.0 || tc.y < 0.0 || tc.z < zclip || tc.x > 1.0 || tc.y > 1.0 || tc.z > 1.0) {
    2.56 +		return 0.0;
    2.57 +	}
    2.58 +
    2.59  	return texture1D(xfer_tex, texture3D(volume, tc).x).x;
    2.60  }
    2.61  
    2.62 -vec3 ray_march(Ray ray)
    2.63 +#define OFFS	0.01
    2.64 +vec3 ray_march(Ray ray, float t0, float t1)
    2.65  {
    2.66 -	const float ray_step = 0.1;
    2.67  	float energy = 1.0;
    2.68 -	vec3 pos = ray.origin;
    2.69 -	float col = 0.0;
    2.70 +	float t = t0;
    2.71 +	vec3 col = vec3(0.0, 0.0, 0.0);
    2.72  
    2.73 -	for(int i=0; i<40; i++) {
    2.74 +
    2.75 +	while(t < t1) {
    2.76 +		vec3 pos = ray.origin + ray.dir * t;
    2.77 +		t += ray_step;
    2.78 +
    2.79  		float val = eval(pos) * energy;
    2.80 -		col += val;
    2.81 +		vec3 norm;
    2.82 +
    2.83 +		norm.x = eval(pos + vec3(OFFS, 0.0, 0.0)) - val;
    2.84 +		norm.y = eval(pos + vec3(0.0, OFFS, 0.0)) - val;
    2.85 +		norm.z = eval(pos + vec3(0.0, 0.0, OFFS)) - val;
    2.86 +		norm = normalize(norm);
    2.87 +
    2.88 +		col += shade(ray, pos, norm) * val;
    2.89  		energy -= val;
    2.90  		if(energy < 0.001) {
    2.91  			break;
    2.92 @@ -71,17 +79,17 @@
    2.93  		pos += ray.dir * ray_step;
    2.94  	}
    2.95  
    2.96 -	return vec3(col, col, col);
    2.97 +	return col;
    2.98  }
    2.99  
   2.100 -vec3 shade(Ray ray, ISect isect)
   2.101 +vec3 shade(Ray ray, vec3 pos, vec3 norm)
   2.102  {
   2.103 -	vec3 ldir = normalize(vec3(10.0, 10.0, -10.0) - isect.pos);
   2.104 +	vec3 ldir = normalize(vec3(10.0, 10.0, -10.0) - pos);
   2.105  	vec3 vdir = -ray.dir;
   2.106  	vec3 hdir = normalize(ldir + vdir);
   2.107  
   2.108 -	float ndotl = dot(ldir, isect.normal);
   2.109 -	float ndoth = dot(hdir, isect.normal);
   2.110 +	float ndotl = dot(ldir, norm);
   2.111 +	float ndoth = dot(hdir, norm);
   2.112  
   2.113  	vec3 dcol = vec3(1.0, 1.0, 1.0) * max(ndotl, 0.0);
   2.114  	vec3 scol = vec3(0.6, 0.6, 0.6) * pow(max(ndoth, 0.0), 50.0);
   2.115 @@ -102,10 +110,10 @@
   2.116  {
   2.117  	ISect res;
   2.118  	res.hit = false;
   2.119 +	res.t0 = res.t1 = 0.0;
   2.120  
   2.121  	if(ray.origin.x >= aabb.min.x && ray.origin.y >= aabb.min.y && ray.origin.z >= aabb.min.z &&
   2.122  			ray.origin.x < aabb.max.x && ray.origin.y < aabb.max.y && ray.origin.z < aabb.max.z) {
   2.123 -		res.t = 0.0;
   2.124  		res.hit = true;
   2.125  		return res;
   2.126  	}
   2.127 @@ -140,28 +148,9 @@
   2.128  		return res;
   2.129  	}
   2.130  
   2.131 -	res.t = tmin;
   2.132 +	res.t0 = tmin;
   2.133 +	res.t1 = tmax;
   2.134  	res.hit = true;
   2.135 -	res.pos = ray.origin + ray.dir * res.t;
   2.136 -
   2.137 -	/*if(res.pos.x > res.pos.y && res.pos.x > res.pos.z) {
   2.138 -		res.normal = vec3(1.0, 0.0, 0.0);
   2.139 -	} else if(res.pos.x < res.pos.y && res.pos.x < res.pos.z) {
   2.140 -		res.normal = vec3(-1.0, 0.0, 0.0);
   2.141 -	} else if(res.pos.y > res.pos.x && res.pos.y > res.pos.z) {
   2.142 -		res.normal = vec3(0.0, 1.0, 0.0);
   2.143 -	} else if(res.pos.y < res.pos.x && res.pos.y < res.pos.z) {
   2.144 -		res.normal = vec3(0.0, -1.0, 0.0);
   2.145 -	} else if(res.pos.z > res.pos.x && res.pos.z > res.pos.y) {
   2.146 -		res.normal = vec3(0.0, 0.0, 1.0);
   2.147 -	} else {
   2.148 -		res.normal = vec3(0.0, 0.9, -1.0);
   2.149 -	}
   2.150 -	if(res.pos.x < 0.0) {
   2.151 -		res.normal = vec3(1.0, 0.0, 0.0);
   2.152 -	} else {
   2.153 -		res.normal = vec3(0.0, 0.0, 1.0);
   2.154 -	}*/
   2.155  	return res;
   2.156  }
   2.157