Hide
Easily highlight source code for your blog with our Syntax Highlighter. Join Siafoo Now or Learn More

A crude Ray Casting (GLSL) fragment shader Atom Feed 0

In Brief A Volume Ray Caster written in the OpenGL Shading Language. It is very crude and only placed here to serve as a starting point for better ray casters.... more
# 's
  1// Data
2uniform sampler1D TransferFunction;
3uniform sampler3D VolumeData;
4uniform sampler2D RayEnd;
5uniform sampler2D RayStart;
6
7// Lighting Stuff
8const vec3 LightPosition = vec3(0.0, 1.0, 1.0);
9const float SpecularContribution = 0.3;
10const float DiffuseContribution = 1.0 - SpecularContribution;
11const float cellSize = 1.0 / 256.0;
12
13// RayCasting stuff
14const float stepSize = 0.001;
15
16vec3 traverseVector;
17vec3 ec;
18
19// Compute the Normal around the current voxel
20vec3 getNormal(vec3 at)
21{
22 vec3 n = vec3(texture3D(VolumeData, at - vec3(cellSize, 0.0, 0.0)).w - texture3D(VolumeData, at + vec3(cellSize, 0.0, 0.0)).w,
23 texture3D(VolumeData, at - vec3(0.0, cellSize, 0.0)).w - texture3D(VolumeData, at + vec3(0.0, cellSize, 0.0)).w,
24 texture3D(VolumeData, at - vec3(0.0, 0.0, cellSize)).w - texture3D(VolumeData, at + vec3(0.0, 0.0, cellSize)).w
25 );
26
27 return normalize(n);
28}
29
30float getLightIntensity(vec3 norm)
31{
32 float LightIntensity = 1.0;
33 vec3 lightVec = normalize(LightPosition - ec);
34 vec3 viewVec = normalize(-ec);
35
36 vec3 reflectVec = reflect(-lightVec, norm);
37 float diffuse = max(dot(lightVec, norm), 0.3);
38 float spec = 0.0;
39
40 if (diffuse > 0.0)
41 {
42 spec = max(dot(reflectVec, viewVec), 0.2);
43 spec = pow(spec, 16.0);
44 }
45
46 return SpecularContribution*spec + DiffuseContribution*diffuse;
47}
48
49void main(void)
50{
51
52 // Get the end point of the ray (from the front-culled faces rendering)
53 vec3 rayStart = texture2D(RayStart, gl_TexCoord[0].st).xyz;
54 vec3 rayEnd = texture2D(RayEnd, gl_TexCoord[0].st).xyz;
55
56 // Get a vector from back to front
57 traverseVector = rayEnd - rayStart;
58
59 // The maximum length of the ray
60 float maxLength = length(traverseVector);
61
62 // Construct a ray in the correct direction and of step length
63 ec = normalize(traverseVector);
64 vec3 step = stepSize * ec;
65 vec3 ray = vec3(0.0, 0.0, 0.0);
66
67 // The color accumulation buffer
68 vec4 acc = vec4(0.0, 0.0, 0.0, 0.0);
69
70 // Holds current voxel color
71 vec4 voxelColor;
72
73 // Lighting
74 float LightIntensity = 1.0;
75
76 // Advance ray
77 for (int i = 0; i < int(1.0/stepSize) + 1; ++i)
78 {
79 if (length(ray) >= maxLength || acc.a >= 1.0)
80 {
81 acc.a = 1.0;
82 break;
83 }
84
85 LightIntensity = getLightIntensity(getNormal(ray + rayStart));
86
87 voxelColor = texture1D(TransferFunction, texture3D(VolumeData, ray + rayStart).w);
88
89 // Accumulate RGB : acc.rgb = voxelColor.rgb*voxelColor.a + (1.0 - voxelColor.a)*acc.rgb;
90 acc.rgb = mix(acc.rgb, voxelColor.rgb, voxelColor.a)*LightIntensity;
91
92 // Accumulate Opacity: acc.a = acc.a + (1.0 - acc.a)*voxelColor.a;
93 acc.a = mix(voxelColor.a, 1.0, acc.a);
94
95 ray += step;
96
97 }
98
99 gl_FragColor = acc;
100 return;
101}

A Volume Ray Caster written in the OpenGL Shading Language. It is very crude and only placed here to serve as a starting point for better ray casters.

Look at RayCasting with PyOpenGL for some Python code that will run this.

The MRI_Head dataset produces something like this:

http://www.siafoo.net/image/41

Comments

updated over 6 years ago (18 Nov 2009 at 05:19 AM) by toneburst
Hiya,

great work, and thanks very much for sharing it!!
just wondering where you got that dataset from. I followed the link, but couldn't find a download of the dataset anywhere.

Cheers,

a|x
http://machinesdontcare.wordpress.com
over 6 years ago (18 Nov 2009 at 12:15 PM) by Stou S.
The volumes are available here: http://lcni.uoregon.edu/~mark/Space_software/example_volumes.html but they are in a different format than my code expects.

If I get some spare time this week I'll verify that these volumes are identical to what I have and if so I will upload my copies. The main problem is that when I was given the datasets I was told not to redistribute them.
over 6 years ago (20 Nov 2009 at 02:39 AM) by toneburst
Thanks for that. I notice some of the datasets say that they're unrestricted. On the other hand, I'm not sure I can open .vol files. I'd need to convert them to 'contactsheet' and save as a standard 2D image.

a|x