Thread: [PyOpenGL-Users] volume rendering
Brought to you by:
mcfletch
From: Andrew W. <and...@al...> - 2008-12-04 19:23:01
|
Hello, I've got an opengl question, figured there are a few experts on this list. I'm generating a 3D volume render using 3d textures and would like to setup multiple regions of interest (ROIs) where only the volume data within the ROI is displayed (everything else is transparent). This is rather easy using the clipping planes for rectangular shaped ROI's and can be faked for ellipsoidal ROIs with the stenil buffer. The tricky part is to render multiple ROI's simultaneously without much performance hit. I'm having a hardtime doing this elegantly. Some ideas are: 1. Clip the actual 3d texture to the different ROI's using a binary mask and reload the texture to the GPU. This becomes problematic for non-rectangular ROIs as the ROIs will look "voxelated" but is nice because it is a single pass for all rendering all ROIs. 2. For each ROI, render the 3d texture clipped with that ROI's bounds. This require multiple renderings and would slow down quite a bit for many ROI's, this will look the best but is not all that elegant. 3. Use a shader to clip the ROI's Any other obvious solutions or ticks that would do this? Any help is much appreciated. Andrew |
From: Dirk R. <di...@li...> - 2008-12-08 14:40:38
|
Hi Andrew, I'm not really an expert in volume rendering, but an interesting problem nonetheless... Andrew Wilson wrote: > Hello, > I've got an opengl question, figured there are a few experts on this > list. I'm generating a 3D volume render using 3d textures and would like to > setup multiple regions of interest (ROIs) where only the volume data within > the ROI is displayed (everything else is transparent). This is rather easy > using the clipping planes for rectangular shaped ROI's and can be faked for > ellipsoidal ROIs with the stenil buffer. The tricky part is to render > multiple ROI's simultaneously without much performance hit. I'm having a > hardtime doing this elegantly. Some ideas are: Basic question: how are you doing the volume rendering? Texture slicing or shader-based ray marching? > 1. Clip the actual 3d texture to the different ROI's using a binary mask > and reload the texture to the GPU. This becomes problematic for > non-rectangular ROIs as the ROIs will look "voxelated" but is nice because > it is a single pass for all rendering all ROIs. You can avoid the voxelisation by not storing a bit but a plane equation in the voxel. That would allow fairly high precision clipping, even for an 4x8 bit texture. But it really is only necessary if your volumes are small, so that a voxel is blown to many pixels. Is that the case? > 2. For each ROI, render the 3d texture clipped with that ROI's bounds. > This require multiple renderings and would slow down quite a bit for many > ROI's, this will look the best but is not all that elegant. Nope, and pretty slow to boot, and I'm not sure if you can make it work for overlapping ROIs. You'd have to do some solid model operations to make it clean. > 3. Use a shader to clip the ROI's That sounds like the best idea, IMHO, as long as you have a relatively small number of ROIs. How many are you expecting? > Any other obvious solutions or ticks that would do this? Any help is much > appreciated. Nothing obvious, sorry. :( Yours Dirk |
From: Andrew W. <and...@al...> - 2008-12-08 15:12:41
|
Hey Dirk, See the response below: On Mon, Dec 8, 2008 at 9:44 AM, Dirk Reiners <di...@li...> wrote: > > Basic question: how are you doing the volume rendering? Texture slicing or > shader-based ray marching? > I'm simply doing texture slicing for volume rendering. > You can avoid the voxelisation by not storing a bit but a plane equation in > the voxel. That would allow fairly high precision clipping, even for an 4x8 > bit texture. But it really is only necessary if your volumes are small, so > that a voxel is blown to many pixels. Is that the case? I am running with low resolution textures (10x8x8 to 20x16x16 or so). I'm not sure I understand the full implementation of storing a plane equation in the voxel, can you elaborate a bit more? > 3. Use a shader to clip the ROI's >> > > That sounds like the best idea, IMHO, as long as you have a relatively > small number of ROIs. How many are you expecting? > I'm expecting on the order of 4-6 ROI's per dataset and may have 2-4 datasets up at the same time. I've pinged the opengl groups too, they recommended using using the multitexture extension with an alpha texture with higher resolution than the dataset to minimize the voxelation. I think this is pretty interesting too. Thanks Andrew |
From: Dirk R. <di...@li...> - 2008-12-08 15:46:57
|
Hi Andrew, Andrew Wilson wrote: > > I'm simply doing texture slicing for volume rendering. OK. > I am running with low resolution textures (10x8x8 to 20x16x16 or so). Ouch! That is low. ;) > I'm > not sure I understand the full implementation of storing a plane equation in > the voxel, can you elaborate a bit more? There was a paper a few years ago that did this for shadow mapping, but I can't find it right now. The main idea is to think of the pixel/voxel as a cube that is split into two parts, one inside, one outside (in your case, of the ROI). When you render a pixel that belongs to the cube, you figure out where it is in the cube (fractional texcoords should be fine), and use that to decide whether it's in or out, and act accordingly. So for you you could save a plane equation that says for example that the area left of the x=.75 point in your cube is inside the ROI, the rest is outside, and you would get super-voxel resolution ROIs. You could also go beyond planes to higher-order > I'm expecting on the order of 4-6 ROI's per dataset and may have 2-4 > datasets up at the same time. OK. For those numbers you should be able to make it real simple and just run the inside/outside test inside the fragment shader for each fragment. That would given you pretty much zero-cost changes to the ROI, if needed. > I've pinged the opengl groups too, they recommended using using the > multitexture extension with an alpha texture with higher resolution than the > dataset to minimize the voxelation. I think this is pretty interesting too. Interesting idea, too. I guess the question is how often you need to update the ROI, and how high the ROI resolution really needs to be. Yours Dirk |
From: Andrew W. <and...@al...> - 2008-12-08 16:00:17
|
Hey Dirk There was a paper a few years ago that did this for shadow mapping, but I > can't find it right now. The main idea is to think of the pixel/voxel as a > cube that is split into two parts, one inside, one outside (in your case, of > the ROI). When you render a pixel that belongs to the cube, you figure out > where it is in the cube (fractional texcoords should be fine), and use that > to decide whether it's in or out, and act accordingly. So for you you could > save a plane equation that says for example that the area left of the x=.75 > point in your cube is inside the ROI, the rest is outside, and you would get > super-voxel resolution ROIs. You could also go beyond planes to higher-order > Got it, sounds a lot like generating an isosurface using marching cubes or something similar. > I guess the question is how often you need to update the ROI, and how high > the ROI resolution really needs to be. > You've hit the nail on the head, I like the idea of using shaders as it won't require much editing of existing opengl code and would provide the best looking results. Thanks for the help, much appreciated. Andrew |