3d texture shading

Hello everybody…

I am using a 3d texture containing a medical volume, Sliced according to the viewpoint. I need to shade the volume so that the tissue facing the viewer has this ‘shining’ effect.

Can anybody give me a pointer or resource to read to do this effect?

Thank You :slight_smile:

Hi Tomy,

I’ve done lighting of volumes in two ways - to pre compute a normal map for the 3D texture and store it as RGB (Nx,Ny,Nz) or RGBA (Nx,Ny,Nz,inensity), or to directy compute the normal from the gradient of intensity of the 3D texture within the fragment shader itself. Doing the late does mean extra texture access though, since you’ll need four samples per fragment, but you save on texture memory :slight_smile:

Once you have the normal you can do a dot product against the light vector to give you the intensity.

I don’t have any code samples on this computer, but when I boot up my machine with the my volume rendering experiments on, I’ll post a code sample. or simply check it into the OpenSceneGraph CVS respository that you can browse online.

Robert.

Thank you Robert for your helpful hints…

I have some comments, please correct me if I am wrong…

Doesn’t the first method you mentioned require that I have a model of the surface of the object I need to shade, which is not the case?

About the second method, is it possible to compute light in a fragment shader? Furthermore, would a complex medical volume’s surface normals be successfully calculated using gradients?

Thank you once again :slight_smile:

Originally posted by Tomy:
[b]Thank you Robert for your helpful hints…

I have some comments, please correct me if I am wrong…

Doesn’t the first method you mentioned require that I have a model of the surface of the object I need to shade, which is not the case?
[/b]
No, you don’t need the surface, just compute the gradients along the x, y and z axis.

Have a look a the normal map code in the osgvolume.cpp example from the OpenSceneGraph distrubtion. The code is a bit undocumented, but its all C++ so should be readable. You don’t need to download the whole distrubtion as your can browse the file from the online CVS respository:

http://openscenegraph.org/viewcvs/examples/osgvolume/osgvolume.cpp?view=markup

It has one GLSL shader in there too, but not my latest experiments with compute the gradient in the fragment program. I’ll check these in sometime next week.

Originally posted by Tomy:
About the second method, is it possible to compute light in a fragment shader? Furthermore, would a complex medical volume’s surface normals be successfully calculated using gradients?

Thank you once again :slight_smile: [/QB]
The fragment shader I’ver written pretty well the same maths (using gradients as a normal) as the computation done on the CPU to the orignal source volume.

Robert.

Robert (and others), hi.

Can you elaborate on what you mean by

directy compute the normal from the gradient of intensity
I’m wondering if this might apply to my problem, which is posted here .

Can you elaborate on what you mean by
“directy compute the normal from the gradient of intensity”

The volume can be thought of as a 3D density field. The gradient of that field is a vector. You can compute it by combining the partial derivatives in the principal directions (x, y, z) into a vector. In a sampled (voxel) volume, you take finite differences to approximate the derivative. The gradient points towards the direction of fastest increase in the density field. If there is a planar surface with a density change in the volume, the gradient at that surface will be a normal to it.

If you need a better explanation with examples, look this up in any book on volume rendering.

Interesting. Maybe I understand this not correctly since I’m quite new to computer vision / opengl.

But this here sounds rather like a local illumination model. What I’m doing in my own 3d texture based volumetric rendering application is the "volumetric lighting algorithm described in the book “GPU Gems” (1), page 682, algorithm 39-3 by Milan Ikits, Joe Kniss et al.
The algorithm described there is for global illumination and requires 2 passes. You render the volume (slices) for the eye and for the light.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.