qvolray
diff sdr/volray.p.glsl @ 9:a6765984e057
moved the volume loading to volume.c
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 08 Apr 2012 07:11:54 +0300 |
parents | volray.p.glsl@ae10631bb11b |
children | 68c6eb619d1c |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/sdr/volray.p.glsl Sun Apr 08 07:11:54 2012 +0300 1.3 @@ -0,0 +1,155 @@ 1.4 +uniform sampler3D volume; 1.5 +uniform sampler2D ray_tex; 1.6 +uniform sampler1D xfer_tex; 1.7 +uniform float ray_step; 1.8 +uniform float zclip; 1.9 + 1.10 +struct Ray { 1.11 + vec3 origin, dir; 1.12 +}; 1.13 + 1.14 +struct AABBox { 1.15 + vec3 min, max; 1.16 +}; 1.17 + 1.18 +struct ISect { 1.19 + bool hit; 1.20 + float t0, t1; 1.21 + vec3 pos; 1.22 + vec3 normal; 1.23 +}; 1.24 + 1.25 +vec3 sky(Ray ray); 1.26 +vec3 ray_march(Ray ray, float t0, float t1); 1.27 +vec3 shade(Ray ray, vec3 pos, vec3 norm); 1.28 +Ray get_primary_ray(); 1.29 +ISect intersect_aabb(Ray ray, AABBox aabb); 1.30 + 1.31 +void main() 1.32 +{ 1.33 + const AABBox aabb = AABBox(vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0)); 1.34 + Ray ray = get_primary_ray(); 1.35 + 1.36 + vec3 color = vec3(0.0, 0.0, 0.0); 1.37 + 1.38 + ISect res = intersect_aabb(ray, aabb); 1.39 + if(res.hit) { 1.40 + color = ray_march(ray, res.t0, res.t1); 1.41 + } 1.42 + 1.43 + gl_FragColor = vec4(color, 1.0); 1.44 +} 1.45 + 1.46 +float eval(vec3 pos) 1.47 +{ 1.48 + vec3 tc = pos * 0.5 + 0.5; 1.49 + 1.50 + if(tc.x < 0.0 || tc.y < 0.0 || tc.z < zclip || tc.x > 1.0 || tc.y > 1.0 || tc.z > 1.0) { 1.51 + return 0.0; 1.52 + } 1.53 + 1.54 + return texture1D(xfer_tex, texture3D(volume, tc).a).x; 1.55 +} 1.56 + 1.57 +#define OFFS 0.01 1.58 +vec3 ray_march(Ray ray, float t0, float t1) 1.59 +{ 1.60 + float energy = 1.0; 1.61 + float t = t0; 1.62 + vec3 col = vec3(0.0, 0.0, 0.0); 1.63 + 1.64 + 1.65 + while(t < t1) { 1.66 + vec3 pos = ray.origin + ray.dir * t; 1.67 + t += ray_step; 1.68 + 1.69 + float val = eval(pos); 1.70 + vec3 norm; 1.71 + 1.72 + norm.x = eval(pos + vec3(OFFS, 0.0, 0.0)) - val; 1.73 + norm.y = eval(pos + vec3(0.0, OFFS, 0.0)) - val; 1.74 + norm.z = eval(pos + vec3(0.0, 0.0, OFFS)) - val; 1.75 + 1.76 + col += shade(ray, pos, normalize(norm)) * val * energy; 1.77 + energy -= val; 1.78 + if(energy < 0.001) { 1.79 + break; 1.80 + } 1.81 + pos += ray.dir * ray_step; 1.82 + } 1.83 + 1.84 + return col; 1.85 +} 1.86 + 1.87 +vec3 shade(Ray ray, vec3 pos, vec3 norm) 1.88 +{ 1.89 + vec3 ldir = -pos;//normalize(vec3(10.0, 10.0, -10.0) - pos); 1.90 + vec3 vdir = -ray.dir; 1.91 + vec3 hdir = normalize(ldir + vdir); 1.92 + 1.93 + float ndotl = dot(ldir, norm); 1.94 + float ndoth = dot(hdir, norm); 1.95 + 1.96 + vec3 dcol = vec3(0.9, 0.9, 0.9) * max(ndotl, 0.0); 1.97 + vec3 scol = vec3(0.5, 0.5, 0.5) * pow(max(ndoth, 0.0), 50.0); 1.98 + 1.99 + return vec3(0.01, 0.01, 0.01) + dcol + scol; 1.100 +} 1.101 + 1.102 +Ray get_primary_ray() 1.103 +{ 1.104 + Ray ray; 1.105 + vec2 tc = gl_TexCoord[0].xy; 1.106 + ray.dir = gl_NormalMatrix * normalize(texture2D(ray_tex, tc).xyz); 1.107 + ray.origin = (gl_ModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0)).xyz; 1.108 + return ray; 1.109 +} 1.110 + 1.111 +ISect intersect_aabb(Ray ray, AABBox aabb) 1.112 +{ 1.113 + ISect res; 1.114 + res.hit = false; 1.115 + res.t0 = res.t1 = 0.0; 1.116 + 1.117 + if(ray.origin.x >= aabb.min.x && ray.origin.y >= aabb.min.y && ray.origin.z >= aabb.min.z && 1.118 + ray.origin.x < aabb.max.x && ray.origin.y < aabb.max.y && ray.origin.z < aabb.max.z) { 1.119 + res.hit = true; 1.120 + return res; 1.121 + } 1.122 + 1.123 + vec4 bbox[2]; 1.124 + bbox[0] = vec4(aabb.min.x, aabb.min.y, aabb.min.z, 0); 1.125 + bbox[1] = vec4(aabb.max.x, aabb.max.y, aabb.max.z, 0); 1.126 + 1.127 + int xsign = int(ray.dir.x < 0.0); 1.128 + float invdirx = 1.0 / ray.dir.x; 1.129 + float tmin = (bbox[xsign].x - ray.origin.x) * invdirx; 1.130 + float tmax = (bbox[1 - xsign].x - ray.origin.x) * invdirx; 1.131 + 1.132 + int ysign = int(ray.dir.y < 0.0); 1.133 + float invdiry = 1.0 / ray.dir.y; 1.134 + float tymin = (bbox[ysign].y - ray.origin.y) * invdiry; 1.135 + float tymax = (bbox[1 - ysign].y - ray.origin.y) * invdiry; 1.136 + 1.137 + if(tmin > tymax || tymin > tmax) { 1.138 + return res; 1.139 + } 1.140 + 1.141 + if(tymin > tmin) tmin = tymin; 1.142 + if(tymax < tmax) tmax = tymax; 1.143 + 1.144 + int zsign = int(ray.dir.z < 0.0); 1.145 + float invdirz = 1.0 / ray.dir.z; 1.146 + float tzmin = (bbox[zsign].z - ray.origin.z) * invdirz; 1.147 + float tzmax = (bbox[1 - zsign].z - ray.origin.z) * invdirz; 1.148 + 1.149 + if(tmin > tzmax || tzmin > tmax) { 1.150 + return res; 1.151 + } 1.152 + 1.153 + res.t0 = tmin; 1.154 + res.t1 = tmax; 1.155 + res.hit = true; 1.156 + return res; 1.157 +} 1.158 +