Volume rendering invalid texture dimensions

Hi everyone, I’m using vtkSmartVolumeMapper to render volume. The resolution is about 4000 in each dimension. When I run the rendering I get ERROR: OpenGL MAX_3D_TEXTURE_SIZE is 2048. Invalid texture dimensions.
How does the vtk handle if the volume is bigger than opengl max texture size? Should I handle it myself? What are the ways to deal with it?

Yes, the OpenGL2 rendering backend currently does not automatically downsample the volume, so if you have a graphics card that cannot handle large textures then you need to downsample the volume yourself. You can use vtkImageShrink3D or vtkImageReslice for this.

Thanks for the reply. I actually don’t want to downsample the volume.
I tried to use partitions inside vtkOpenGLGPUVolumeRayCastMapper, but it slowed down the rendering a lot. Better approach for me was to split the volume into blocks on the CPU and then use vtkMultiBlockVolumeMapper.
My question would be, is there any vtk data structure that would load memory not contiguously, but strided, so that I wouldn’t have to split the volume in memory? Also any additional optimizations regarding this approach?

What graphics card do you have? What is the current rendering speed with vtkMultiBlockVolumeMapper?What is the rendering speed with a volume downsampled to 2000x2000x2000 and 1000x1000x1000 if you use vtkGPUVolumeRayCastMapper?

My graphics card (geforce gtx 1070) actually supports this big volume, but the customer gpu probably will not support these dimensions.
The rendering speeds for 4112x3008x32 are as follow:
whole volume with vtkOpenGLGPUVolumeRayCastMapper : ~150fps
whole volume with vtkOpenGLGPUVolumeRayCastMapper and SetPartitions(2, 2, 2) : ~3fps
partitioned volume with vtkMultiBlockVolumeMapper 2x2x2 : ~70fps

I’ve found vtkDataTransferHelper which seems to do exactly what I want, but I’ve no idea how to integrate it into the pipeline with vtkOpenGLGPUVolumeRayCastMapper?

I can confirm similar tremendous volume rendering slowdowns if I use SetPartitions(2,2,2).
@sankhesh is this expected?

Helper classes in VTK are typically intended for VTK’s internal use only.

SetPartitions should be analogous to the MultiBlockVolumeMapper approach as all it does it splits up the volume into the request number of textures and streams each texture to the GPU. The only additional step that paritioning with GPU volume mapper does over multiblock volume mapper is sorting the blocks before rendering. Having said that, I don’t think the SetPartitions logic is stress-tested enough. I am sure there are areas of improvement there.

1 Like

@sankhesh Thanks for the information.

@mykolav It would be great if you could do some profiling and debugging to see what causes the slowdown with partitioning (or if you don’t have time or expertise but you need this feature then you could contract Kitware or someone else to do this work for you).

If vtkMultiBlockVolumeMapper works fine and the only issue is that you don’t want to split in memory then you could check if there is an image file reader that can read a partial volume, specified by requested extent (maybe vtkMetaImageWriter can do it?) and if you don’t find any then implement it yourself. For large images, it could be more efficient anyway to store images in a tile-based file format, maybe also at different resolutions.

I just experimented with SetPartitions as well as it would be the simplest solution for large volumes, but also noticed the slowdown. Haven’t tried vtkMultiBlockVolumeMapper yet.

@mykolav did you arrive at a satisfactory solution for your use case in the end? I’m hoping to get some inspiration for mine :wink: