# HG changeset patch # User John Tsiombikas # Date 1333576331 -10800 # Node ID f40e4edfee7e1ee1c2f8192e9e3f707d88c57c82 # Parent 04316e9e95dc531dc520fa28f6dde001576894be shading diff -r 04316e9e95dc -r f40e4edfee7e src/volray.c --- a/src/volray.c Wed Apr 04 01:37:58 2012 +0300 +++ b/src/volray.c Thu Apr 05 00:52:11 2012 +0300 @@ -54,11 +54,12 @@ int raytex_needs_recalc = 1; unsigned int xfer_tex; -float xfer_mean = 0.5, xfer_sdev = 1.0; +float xfer_mean = 0.7, xfer_sdev = 0.1; int xfertex_needs_recalc = 1; static int uimode; -static float cur_z = 0.5; +static float cur_z = 0.0; +static float ray_step = 0.01; int main(int argc, char **argv) { @@ -99,6 +100,8 @@ set_uniform_int(vol_sdr, "volume", 0); set_uniform_int(vol_sdr, "ray_tex", 1); set_uniform_int(vol_sdr, "xfer_tex", 2); + set_uniform_float(vol_sdr, "ray_step", ray_step); + set_uniform_float(vol_sdr, "zclip", cur_z); if(!(slice_sdr = create_program_load(0, "slice.p.glsl"))) { return -1; @@ -127,7 +130,7 @@ if(i == 0) { /* allocate storage for the texture */ - glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, xsz, ysz, nslices, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA32F, xsz, ysz, nslices, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); vol_xsz = xsz; vol_ysz = ysz; @@ -388,6 +391,8 @@ cur_z = 0.0; if(cur_z > 1.0) cur_z = 1.0; + + set_uniform_float(vol_sdr, "zclip", cur_z); glutPostRedisplay(); break; diff -r 04316e9e95dc -r f40e4edfee7e volray.p.glsl --- a/volray.p.glsl Wed Apr 04 01:37:58 2012 +0300 +++ b/volray.p.glsl Thu Apr 05 00:52:11 2012 +0300 @@ -1,6 +1,8 @@ uniform sampler3D volume; uniform sampler2D ray_tex; uniform sampler1D xfer_tex; +uniform float ray_step; +uniform float zclip; struct Ray { vec3 origin, dir; @@ -12,14 +14,14 @@ struct ISect { bool hit; - float t; + float t0, t1; vec3 pos; vec3 normal; }; vec3 sky(Ray ray); -vec3 ray_march(Ray ray); -vec3 shade(Ray ray, ISect isect); +vec3 ray_march(Ray ray, float t0, float t1); +vec3 shade(Ray ray, vec3 pos, vec3 norm); Ray get_primary_ray(); ISect intersect_aabb(Ray ray, AABBox aabb); @@ -32,38 +34,44 @@ ISect res = intersect_aabb(ray, aabb); if(res.hit) { - ray.origin += ray.dir * res.t; - color = ray_march(ray); + color = ray_march(ray, res.t0, res.t1); } gl_FragColor = vec4(color, 1.0); } -vec3 sky(Ray ray) -{ - vec3 col1 = vec3(0.75, 0.78, 0.8); - vec3 col2 = vec3(0.56, 0.7, 1.0); - - float t = max(ray.dir.y, -0.5); - return mix(col1, col2, t); -} - float eval(vec3 pos) { vec3 tc = pos * 0.5 + 0.5; + + if(tc.x < 0.0 || tc.y < 0.0 || tc.z < zclip || tc.x > 1.0 || tc.y > 1.0 || tc.z > 1.0) { + return 0.0; + } + return texture1D(xfer_tex, texture3D(volume, tc).x).x; } -vec3 ray_march(Ray ray) +#define OFFS 0.01 +vec3 ray_march(Ray ray, float t0, float t1) { - const float ray_step = 0.1; float energy = 1.0; - vec3 pos = ray.origin; - float col = 0.0; + float t = t0; + vec3 col = vec3(0.0, 0.0, 0.0); - for(int i=0; i<40; i++) { + + while(t < t1) { + vec3 pos = ray.origin + ray.dir * t; + t += ray_step; + float val = eval(pos) * energy; - col += val; + vec3 norm; + + norm.x = eval(pos + vec3(OFFS, 0.0, 0.0)) - val; + norm.y = eval(pos + vec3(0.0, OFFS, 0.0)) - val; + norm.z = eval(pos + vec3(0.0, 0.0, OFFS)) - val; + norm = normalize(norm); + + col += shade(ray, pos, norm) * val; energy -= val; if(energy < 0.001) { break; @@ -71,17 +79,17 @@ pos += ray.dir * ray_step; } - return vec3(col, col, col); + return col; } -vec3 shade(Ray ray, ISect isect) +vec3 shade(Ray ray, vec3 pos, vec3 norm) { - vec3 ldir = normalize(vec3(10.0, 10.0, -10.0) - isect.pos); + vec3 ldir = normalize(vec3(10.0, 10.0, -10.0) - pos); vec3 vdir = -ray.dir; vec3 hdir = normalize(ldir + vdir); - float ndotl = dot(ldir, isect.normal); - float ndoth = dot(hdir, isect.normal); + float ndotl = dot(ldir, norm); + float ndoth = dot(hdir, norm); vec3 dcol = vec3(1.0, 1.0, 1.0) * max(ndotl, 0.0); vec3 scol = vec3(0.6, 0.6, 0.6) * pow(max(ndoth, 0.0), 50.0); @@ -102,10 +110,10 @@ { ISect res; res.hit = false; + res.t0 = res.t1 = 0.0; if(ray.origin.x >= aabb.min.x && ray.origin.y >= aabb.min.y && ray.origin.z >= aabb.min.z && ray.origin.x < aabb.max.x && ray.origin.y < aabb.max.y && ray.origin.z < aabb.max.z) { - res.t = 0.0; res.hit = true; return res; } @@ -140,28 +148,9 @@ return res; } - res.t = tmin; + res.t0 = tmin; + res.t1 = tmax; res.hit = true; - res.pos = ray.origin + ray.dir * res.t; - - /*if(res.pos.x > res.pos.y && res.pos.x > res.pos.z) { - res.normal = vec3(1.0, 0.0, 0.0); - } else if(res.pos.x < res.pos.y && res.pos.x < res.pos.z) { - res.normal = vec3(-1.0, 0.0, 0.0); - } else if(res.pos.y > res.pos.x && res.pos.y > res.pos.z) { - res.normal = vec3(0.0, 1.0, 0.0); - } else if(res.pos.y < res.pos.x && res.pos.y < res.pos.z) { - res.normal = vec3(0.0, -1.0, 0.0); - } else if(res.pos.z > res.pos.x && res.pos.z > res.pos.y) { - res.normal = vec3(0.0, 0.0, 1.0); - } else { - res.normal = vec3(0.0, 0.9, -1.0); - } - if(res.pos.x < 0.0) { - res.normal = vec3(1.0, 0.0, 0.0); - } else { - res.normal = vec3(0.0, 0.0, 1.0); - }*/ return res; }