qvolray

annotate volray.p.glsl @ 8:ae10631bb11b

cleaning up a bit to expand
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 07 Apr 2012 16:07:12 +0300
parents f40e4edfee7e
children
rev   line source
nuclear@0 1 uniform sampler3D volume;
nuclear@0 2 uniform sampler2D ray_tex;
nuclear@4 3 uniform sampler1D xfer_tex;
nuclear@7 4 uniform float ray_step;
nuclear@7 5 uniform float zclip;
nuclear@0 6
nuclear@0 7 struct Ray {
nuclear@0 8 vec3 origin, dir;
nuclear@0 9 };
nuclear@0 10
nuclear@4 11 struct AABBox {
nuclear@4 12 vec3 min, max;
nuclear@4 13 };
nuclear@4 14
nuclear@0 15 struct ISect {
nuclear@0 16 bool hit;
nuclear@7 17 float t0, t1;
nuclear@0 18 vec3 pos;
nuclear@0 19 vec3 normal;
nuclear@0 20 };
nuclear@0 21
nuclear@1 22 vec3 sky(Ray ray);
nuclear@7 23 vec3 ray_march(Ray ray, float t0, float t1);
nuclear@7 24 vec3 shade(Ray ray, vec3 pos, vec3 norm);
nuclear@0 25 Ray get_primary_ray();
nuclear@5 26 ISect intersect_aabb(Ray ray, AABBox aabb);
nuclear@0 27
nuclear@0 28 void main()
nuclear@0 29 {
nuclear@5 30 const AABBox aabb = AABBox(vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0));
nuclear@0 31 Ray ray = get_primary_ray();
nuclear@0 32
nuclear@4 33 vec3 color = vec3(0.0, 0.0, 0.0);
nuclear@4 34
nuclear@5 35 ISect res = intersect_aabb(ray, aabb);
nuclear@5 36 if(res.hit) {
nuclear@7 37 color = ray_march(ray, res.t0, res.t1);
nuclear@4 38 }
nuclear@4 39
nuclear@4 40 gl_FragColor = vec4(color, 1.0);
nuclear@0 41 }
nuclear@0 42
nuclear@4 43 float eval(vec3 pos)
nuclear@4 44 {
nuclear@5 45 vec3 tc = pos * 0.5 + 0.5;
nuclear@7 46
nuclear@7 47 if(tc.x < 0.0 || tc.y < 0.0 || tc.z < zclip || tc.x > 1.0 || tc.y > 1.0 || tc.z > 1.0) {
nuclear@7 48 return 0.0;
nuclear@7 49 }
nuclear@7 50
nuclear@5 51 return texture1D(xfer_tex, texture3D(volume, tc).x).x;
nuclear@4 52 }
nuclear@4 53
nuclear@7 54 #define OFFS 0.01
nuclear@7 55 vec3 ray_march(Ray ray, float t0, float t1)
nuclear@0 56 {
nuclear@0 57 float energy = 1.0;
nuclear@7 58 float t = t0;
nuclear@7 59 vec3 col = vec3(0.0, 0.0, 0.0);
nuclear@0 60
nuclear@7 61
nuclear@7 62 while(t < t1) {
nuclear@7 63 vec3 pos = ray.origin + ray.dir * t;
nuclear@7 64 t += ray_step;
nuclear@7 65
nuclear@8 66 float val = eval(pos);
nuclear@7 67 vec3 norm;
nuclear@7 68
nuclear@7 69 norm.x = eval(pos + vec3(OFFS, 0.0, 0.0)) - val;
nuclear@7 70 norm.y = eval(pos + vec3(0.0, OFFS, 0.0)) - val;
nuclear@7 71 norm.z = eval(pos + vec3(0.0, 0.0, OFFS)) - val;
nuclear@7 72
nuclear@8 73 col += shade(ray, pos, normalize(norm)) * val * energy;
nuclear@1 74 energy -= val;
nuclear@1 75 if(energy < 0.001) {
nuclear@1 76 break;
nuclear@1 77 }
nuclear@0 78 pos += ray.dir * ray_step;
nuclear@0 79 }
nuclear@0 80
nuclear@7 81 return col;
nuclear@0 82 }
nuclear@0 83
nuclear@7 84 vec3 shade(Ray ray, vec3 pos, vec3 norm)
nuclear@0 85 {
nuclear@8 86 vec3 ldir = -pos;//normalize(vec3(10.0, 10.0, -10.0) - pos);
nuclear@0 87 vec3 vdir = -ray.dir;
nuclear@0 88 vec3 hdir = normalize(ldir + vdir);
nuclear@0 89
nuclear@7 90 float ndotl = dot(ldir, norm);
nuclear@7 91 float ndoth = dot(hdir, norm);
nuclear@0 92
nuclear@8 93 vec3 dcol = vec3(0.9, 0.9, 0.9) * max(ndotl, 0.0);
nuclear@8 94 vec3 scol = vec3(0.5, 0.5, 0.5) * pow(max(ndoth, 0.0), 50.0);
nuclear@0 95
nuclear@0 96 return vec3(0.01, 0.01, 0.01) + dcol + scol;
nuclear@0 97 }
nuclear@0 98
nuclear@0 99 Ray get_primary_ray()
nuclear@0 100 {
nuclear@0 101 Ray ray;
nuclear@0 102 vec2 tc = gl_TexCoord[0].xy;
nuclear@0 103 ray.dir = gl_NormalMatrix * normalize(texture2D(ray_tex, tc).xyz);
nuclear@0 104 ray.origin = (gl_ModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0)).xyz;
nuclear@0 105 return ray;
nuclear@0 106 }
nuclear@4 107
nuclear@5 108 ISect intersect_aabb(Ray ray, AABBox aabb)
nuclear@4 109 {
nuclear@5 110 ISect res;
nuclear@5 111 res.hit = false;
nuclear@7 112 res.t0 = res.t1 = 0.0;
nuclear@5 113
nuclear@4 114 if(ray.origin.x >= aabb.min.x && ray.origin.y >= aabb.min.y && ray.origin.z >= aabb.min.z &&
nuclear@4 115 ray.origin.x < aabb.max.x && ray.origin.y < aabb.max.y && ray.origin.z < aabb.max.z) {
nuclear@5 116 res.hit = true;
nuclear@5 117 return res;
nuclear@4 118 }
nuclear@4 119
nuclear@4 120 vec4 bbox[2];
nuclear@4 121 bbox[0] = vec4(aabb.min.x, aabb.min.y, aabb.min.z, 0);
nuclear@4 122 bbox[1] = vec4(aabb.max.x, aabb.max.y, aabb.max.z, 0);
nuclear@4 123
nuclear@4 124 int xsign = int(ray.dir.x < 0.0);
nuclear@4 125 float invdirx = 1.0 / ray.dir.x;
nuclear@4 126 float tmin = (bbox[xsign].x - ray.origin.x) * invdirx;
nuclear@4 127 float tmax = (bbox[1 - xsign].x - ray.origin.x) * invdirx;
nuclear@4 128
nuclear@4 129 int ysign = int(ray.dir.y < 0.0);
nuclear@4 130 float invdiry = 1.0 / ray.dir.y;
nuclear@4 131 float tymin = (bbox[ysign].y - ray.origin.y) * invdiry;
nuclear@4 132 float tymax = (bbox[1 - ysign].y - ray.origin.y) * invdiry;
nuclear@4 133
nuclear@4 134 if(tmin > tymax || tymin > tmax) {
nuclear@5 135 return res;
nuclear@4 136 }
nuclear@4 137
nuclear@4 138 if(tymin > tmin) tmin = tymin;
nuclear@4 139 if(tymax < tmax) tmax = tymax;
nuclear@4 140
nuclear@4 141 int zsign = int(ray.dir.z < 0.0);
nuclear@4 142 float invdirz = 1.0 / ray.dir.z;
nuclear@4 143 float tzmin = (bbox[zsign].z - ray.origin.z) * invdirz;
nuclear@4 144 float tzmax = (bbox[1 - zsign].z - ray.origin.z) * invdirz;
nuclear@4 145
nuclear@4 146 if(tmin > tzmax || tzmin > tmax) {
nuclear@5 147 return res;
nuclear@4 148 }
nuclear@4 149
nuclear@7 150 res.t0 = tmin;
nuclear@7 151 res.t1 = tmax;
nuclear@5 152 res.hit = true;
nuclear@5 153 return res;
nuclear@4 154 }
nuclear@4 155