qvolray

view volray.p.glsl @ 4:3e53a16d4667

foo
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 02 Apr 2012 17:59:46 +0300
parents 57072295eb83
children 0c3874aa717a
line source
1 uniform sampler3D volume;
2 uniform sampler2D ray_tex;
3 uniform sampler1D xfer_tex;
5 struct Ray {
6 vec3 origin, dir;
7 };
9 struct AABBox {
10 vec3 min, max;
11 };
13 struct ISect {
14 bool hit;
15 float t;
16 vec3 pos;
17 vec3 normal;
18 };
20 vec3 sky(Ray ray);
21 vec3 ray_march(Ray ray);
22 vec3 shade(Ray ray, ISect isect);
23 Ray get_primary_ray();
24 bool intersect_aabb(Ray ray, AABBox aabb, out float t);
26 void main()
27 {
28 const AABBox aabb = AABBox(vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0));
29 Ray ray = get_primary_ray();
31 vec3 color = vec3(0.0, 0.0, 0.0);
33 float start_t;
34 if(intersect_aabb(ray, aabb, start_t)) {
35 ray.origin += ray.dir * start_t;
36 color = vec3(1.0, 0.0, 0.0);//ray_march(ray);
37 }
39 gl_FragColor = vec4(color, 1.0);
40 }
42 vec3 sky(Ray ray)
43 {
44 vec3 col1 = vec3(0.75, 0.78, 0.8);
45 vec3 col2 = vec3(0.56, 0.7, 1.0);
47 float t = max(ray.dir.y, -0.5);
48 return mix(col1, col2, t);
49 }
51 float eval(vec3 pos)
52 {
53 return texture1D(xfer_tex, texture3D(volume, pos).x).x;
54 }
56 vec3 ray_march(Ray ray)
57 {
58 const float ray_step = 0.1;
59 float energy = 1.0;
60 vec3 pos = ray.origin;
61 float col = 0.0;
63 for(int i=0; i<40; i++) {
64 float val = eval(pos) * energy;
65 col += val;
66 energy -= val;
67 if(energy < 0.001) {
68 break;
69 }
70 pos += ray.dir * ray_step;
71 }
73 return vec3(col, col, col);
74 }
76 vec3 shade(Ray ray, ISect isect)
77 {
78 vec3 ldir = normalize(vec3(10.0, 10.0, -10.0) - isect.pos);
79 vec3 vdir = -ray.dir;
80 vec3 hdir = normalize(ldir + vdir);
82 float ndotl = dot(ldir, isect.normal);
83 float ndoth = dot(hdir, isect.normal);
85 vec3 dcol = vec3(1.0, 1.0, 1.0) * max(ndotl, 0.0);
86 vec3 scol = vec3(0.6, 0.6, 0.6) * pow(max(ndoth, 0.0), 50.0);
88 return vec3(0.01, 0.01, 0.01) + dcol + scol;
89 }
91 Ray get_primary_ray()
92 {
93 Ray ray;
94 vec2 tc = gl_TexCoord[0].xy;
95 ray.dir = gl_NormalMatrix * normalize(texture2D(ray_tex, tc).xyz);
96 ray.origin = (gl_ModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0)).xyz;
97 return ray;
98 }
100 bool intersect_aabb(Ray ray, AABBox aabb, out float t)
101 {
102 if(ray.origin.x >= aabb.min.x && ray.origin.y >= aabb.min.y && ray.origin.z >= aabb.min.z &&
103 ray.origin.x < aabb.max.x && ray.origin.y < aabb.max.y && ray.origin.z < aabb.max.z) {
104 return true;
105 }
107 vec4 bbox[2];
108 bbox[0] = vec4(aabb.min.x, aabb.min.y, aabb.min.z, 0);
109 bbox[1] = vec4(aabb.max.x, aabb.max.y, aabb.max.z, 0);
111 int xsign = int(ray.dir.x < 0.0);
112 float invdirx = 1.0 / ray.dir.x;
113 float tmin = (bbox[xsign].x - ray.origin.x) * invdirx;
114 float tmax = (bbox[1 - xsign].x - ray.origin.x) * invdirx;
116 int ysign = int(ray.dir.y < 0.0);
117 float invdiry = 1.0 / ray.dir.y;
118 float tymin = (bbox[ysign].y - ray.origin.y) * invdiry;
119 float tymax = (bbox[1 - ysign].y - ray.origin.y) * invdiry;
121 if(tmin > tymax || tymin > tmax) {
122 return false;
123 }
125 if(tymin > tmin) tmin = tymin;
126 if(tymax < tmax) tmax = tymax;
128 int zsign = int(ray.dir.z < 0.0);
129 float invdirz = 1.0 / ray.dir.z;
130 float tzmin = (bbox[zsign].z - ray.origin.z) * invdirz;
131 float tzmax = (bbox[1 - zsign].z - ray.origin.z) * invdirz;
133 if(tmin > tzmax || tzmin > tmax) {
134 return false;
135 }
137 t = tmin;
138 return tmin < 1.0 && tmax > 0.0;
139 }