nuclear@0: uniform sampler3D volume; nuclear@0: uniform sampler2D ray_tex; nuclear@0: nuclear@0: struct Ray { nuclear@0: vec3 origin, dir; nuclear@0: }; nuclear@0: nuclear@0: struct ISect { nuclear@0: bool hit; nuclear@0: float t; nuclear@0: vec3 pos; nuclear@0: vec3 normal; nuclear@0: }; nuclear@0: nuclear@1: vec3 sky(Ray ray); nuclear@0: vec3 ray_march(Ray ray); nuclear@0: vec3 shade(Ray ray, ISect isect); nuclear@0: Ray get_primary_ray(); nuclear@0: nuclear@0: void main() nuclear@0: { nuclear@0: Ray ray = get_primary_ray(); nuclear@0: nuclear@0: gl_FragColor = vec4(ray_march(ray), 1.0); nuclear@1: //gl_FragColor = vec4(sky(ray), 1.0); nuclear@0: } nuclear@0: nuclear@1: vec3 sky(Ray ray) nuclear@0: { nuclear@0: vec3 col1 = vec3(0.75, 0.78, 0.8); nuclear@0: vec3 col2 = vec3(0.56, 0.7, 1.0); nuclear@0: nuclear@0: float t = max(ray.dir.y, -0.5); nuclear@0: return mix(col1, col2, t); nuclear@1: } nuclear@0: nuclear@0: vec3 ray_march(Ray ray) nuclear@0: { nuclear@1: const float ray_step = 0.1; nuclear@0: float energy = 1.0; nuclear@0: vec3 pos = ray.origin; nuclear@1: float col = 0.0; nuclear@0: nuclear@1: for(int i=0; i<40; i++) { nuclear@1: float val = texture3D(volume, pos).x; nuclear@1: val *= energy; nuclear@1: col += val; nuclear@1: energy -= val; nuclear@1: if(energy < 0.001) { nuclear@1: break; nuclear@1: } nuclear@0: pos += ray.dir * ray_step; nuclear@0: } nuclear@0: nuclear@1: return vec3(col, col, col); nuclear@0: } nuclear@0: nuclear@0: vec3 shade(Ray ray, ISect isect) nuclear@0: { nuclear@0: vec3 ldir = normalize(vec3(10.0, 10.0, -10.0) - isect.pos); nuclear@0: vec3 vdir = -ray.dir; nuclear@0: vec3 hdir = normalize(ldir + vdir); nuclear@0: nuclear@0: float ndotl = dot(ldir, isect.normal); nuclear@0: float ndoth = dot(hdir, isect.normal); nuclear@0: nuclear@0: vec3 dcol = vec3(1.0, 1.0, 1.0) * max(ndotl, 0.0); nuclear@0: vec3 scol = vec3(0.6, 0.6, 0.6) * pow(max(ndoth, 0.0), 50.0); nuclear@0: nuclear@0: return vec3(0.01, 0.01, 0.01) + dcol + scol; nuclear@0: } nuclear@0: nuclear@0: Ray get_primary_ray() nuclear@0: { nuclear@0: Ray ray; nuclear@0: vec2 tc = gl_TexCoord[0].xy; nuclear@0: ray.dir = gl_NormalMatrix * normalize(texture2D(ray_tex, tc).xyz); nuclear@0: ray.origin = (gl_ModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0)).xyz; nuclear@0: return ray; nuclear@0: }