qvolray

annotate volray.p.glsl @ 5:0c3874aa717a

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