# Negative values in vtkCamera projection transform breaks GPU volume raycast mapper

**URL:** https://discourse.vtk.org/t/negative-values-in-vtkcamera-projection-transform-breaks-gpu-volume-raycast-mapper/14593
**Category:** Support
**Created:** [September 18, 2024, 4:35pm UTC](https://discourse.vtk.org/t/negative-values-in-vtkcamera-projection-transform-breaks-gpu-volume-raycast-mapper/14593 "2024-09-18T16:35:12Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![Jeremy](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/j/82dd89/32.png) [@Jeremy](https://discourse.vtk.org/u/Jeremy)
#### Post date: [September 18, 2024, 4:35pm UTC](https://discourse.vtk.org/t/negative-values-in-vtkcamera-projection-transform-breaks-gpu-volume-raycast-mapper/14593/1 "2024-09-18T16:35:12Z")

</div>

Hi everyone,

I’m having issues with the vtkOpenGLGPUVolumeRayCastMapper class. What seems to work with the vtkFixedPointVolumeRaycastMapper doesn’t seem to work with the GPU variant.

To be more precise, I’m flipping the X and Y axis of the vtkCamera projection transform by setting the 0th and 5th values of the matrix to -1

Here are some screenshots of it working perfectly with the vtkFixedPointVolumeRaycastMapper:

 ![fixed_point](https://discourse.vtk.org/uploads/default/original/2X/3/389ced48054b1867f926fb360f1c1f042ca1ab60.jpeg) ![fixed_point_flipped_x](https://discourse.vtk.org/uploads/default/original/2X/e/e213bb0a58241e95fdeac7d088133af3a1b2618c.jpeg)  
 ![fixed_point_flipped_y](https://discourse.vtk.org/uploads/default/original/2X/a/af971ff3c64ce86810ee1388bf5d9404291586f7.jpeg) ![fixed_point_flipped_x_y](https://discourse.vtk.org/uploads/default/original/2X/1/18c9f348d484a31f675e473956b40e4d34823699.jpeg)

Here are some screenshots of it breaking with the vtkOpenGLGPUVolumeRayCastMapper :

 ![gpu_mapper](https://discourse.vtk.org/uploads/default/original/2X/4/4c0b144f91d1ee66149c0c17fb66f7a0cd80c7ce.jpeg) ![gpu_mapper_flipped_x](https://discourse.vtk.org/uploads/default/original/2X/7/7c283f5861ad83ddcace18d9b4db80b99e6ff942.png)  
 ![gpu_mapper_flipped_y](https://discourse.vtk.org/uploads/default/original/2X/5/5ac472d3a9ce95b21f3c869683dc30b3ac74cbc7.png) ![gpu_mapper_flipped_x_y](https://discourse.vtk.org/uploads/default/original/2X/d/dff94c0c6b096f01fd4e6e39dc3554d3545bfe2d.jpeg)

When only flipping X or Y we can see the tips of the model, so it’s almost working but not quite.  
Seemingly the signs cancel when flipping both X and Y, which makes things work again?

On a probably related note, I’m also having issues with the lighting when reversing the Z axis.

I’ve taken a look at the shader of vtkOpenGLGPUVolumeRayCastMapper but did not manage to figure out why would this happen.

What I’m doing is similar to what’s being done in this thread:

> [@Inverted perspective divide in VTK](https://discourse.vtk.org/t/inverted-perspective-divide-in-vtk/13061/9#volume-rendering-2):
>
> I’ve tested this and you can get the correct reverse perspective by inverting the sign of the third column of the perspective projection matrix: Surface rendering Normal perspective: Reverse perspective: Volume rendering It also works for CPU volume rendering (unfortunately, ray computation seem to be implemented with some custom logic in the GPU volume renderer, so that would need some fixes). Normal perspective: Reverse perspective: Implementation T…

What @lassoan says

> It also works for CPU volume rendering (unfortunately, ray computation seem to be implemented with some custom logic in the GPU volume renderer, so that would need some fixes).

seems to imply that it would be possible to fix, if that’s the case what would be the potential fix or lead to explore?

Any help would be greatly appreciated !  
Thank you

---

<div class="post-metadata">

### Author: ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)
#### Post date: [September 18, 2024, 6:21pm UTC](https://discourse.vtk.org/t/negative-values-in-vtkcamera-projection-transform-breaks-gpu-volume-raycast-mapper/14593/2 "2024-09-18T18:21:05Z")

</div>

Yes, GPU volume rendering ray computation would need an update to allow reverse perspective rendering. This rendering mode is essential for fluoroscopy fusion applications, but not for much else, so waiting for some project to fund the development could take years. If you need it sooner then you can try to implement it yourself or give a small contract to Kitware or other developers experienced with VTK rendering to implement it for you.

---

<div class="post-metadata">

### Author: ![LucasGandel](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lucasgandel/32/1831_2.png) [@LucasGandel](https://discourse.vtk.org/u/LucasGandel)
#### Post date: [September 19, 2024, 8:04am UTC](https://discourse.vtk.org/t/negative-values-in-vtkcamera-projection-transform-breaks-gpu-volume-raycast-mapper/14593/3 "2024-09-19T08:04:07Z")

</div>

Could you try to bypass the `IsCameraInside()` check in vtkOpenGLGPUVolumeRayCastMapper to see if it helps please?

---

<div class="post-metadata">

### Author: ![Jeremy](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/j/82dd89/32.png) [@Jeremy](https://discourse.vtk.org/u/Jeremy)
#### Post date: [September 19, 2024, 8:58am UTC](https://discourse.vtk.org/t/negative-values-in-vtkcamera-projection-transform-breaks-gpu-volume-raycast-mapper/14593/4 "2024-09-19T08:58:42Z")

</div>

Thank you for the prompt reply!

I’m willing to give it a go myself, if anyone has any resources regarding the implementation used that would be very helpful.

---

<div class="post-metadata">

### Author: ![Jeremy](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/j/82dd89/32.png) [@Jeremy](https://discourse.vtk.org/u/Jeremy)
#### Post date: [September 19, 2024, 9:01am UTC](https://discourse.vtk.org/t/negative-values-in-vtkcamera-projection-transform-breaks-gpu-volume-raycast-mapper/14593/5 "2024-09-19T09:01:28Z")

</div>

Sadly it didn’t change anything.  
I also checked its return value and it seems to behave the same with the axis flipped.

---

<div class="post-metadata">

### Author: ![LucasGandel](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lucasgandel/32/1831_2.png) [@LucasGandel](https://discourse.vtk.org/u/LucasGandel)
#### Post date: [September 20, 2024, 9:03am UTC](https://discourse.vtk.org/t/negative-values-in-vtkcamera-projection-transform-breaks-gpu-volume-raycast-mapper/14593/6 "2024-09-20T09:03:24Z")

</div>

Ok thanks for trying.  
Then you might want to check the computation of [rayOrigin](https://gitlab.kitware.com/vtk/vtk/-/blob/master/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h#L409) and [rayTermination](https://gitlab.kitware.com/vtk/vtk/-/blob/master/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h#L3310) as well as code involving g\_skip.

---

<div class="post-metadata">

### Author: ![Jeremy](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/j/82dd89/32.png) [@Jeremy](https://discourse.vtk.org/u/Jeremy)
#### Post date: [September 20, 2024, 4:09pm UTC](https://discourse.vtk.org/t/negative-values-in-vtkcamera-projection-transform-breaks-gpu-volume-raycast-mapper/14593/7 "2024-09-20T16:09:43Z")

</div>

Thank you for your help!

Regarding the computation of rayOrigin you pointed to, by default UseDepthPass is turned off so this part of the shader is not executed from my observations (I’m outputing the compiled shader to file inside the BuildShader method, I’m not sure this is the best method but I haven’t found another solution)

Simply enabling UseDepthPass seems to break the rendering. Barely anything renders:

 ![gpu_mapper_usedepthpass](https://discourse.vtk.org/uploads/default/original/2X/e/e71d92e0256bd00a084e42cccf6235bd97ebb55a.png)

The documentation points at the need to define contour values which I did, this is the result:  
 ![gpu_mapper_usedepthpass_contour_rotX90](https://discourse.vtk.org/uploads/default/original/2X/a/ad5347fc9990e1085d38fe25e0b09bcf0780487f.gif)

However after removing the initial rotation I applied to the volume, the rendering seems mostly okay except for a weird artifact at the bottom:  
 ![gpu_mapper_usedepthpass_contour](https://discourse.vtk.org/uploads/default/original/2X/6/62721510093995b50cd051b0e726b808a5f71948.gif)

Moreover, without the rotation, the X/Y axis flip seems to work!

 ![gpu_mapper_usedepthpass_contour_flipped_x](https://discourse.vtk.org/uploads/default/original/2X/4/47028c67db9e9b5b0b0e63d9b2943a2dc206282c.jpeg) ![gpu_mapper_usedepthpass_contour_flipped_y](https://discourse.vtk.org/uploads/default/original/2X/d/d46759476fb8fc7f60c8be8b66b63a79ac72f330.jpeg)

So it seems that transformations applied to volumes are at cause?

---

<div class="post-metadata">

### Author: ![LucasGandel](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lucasgandel/32/1831_2.png) [@LucasGandel](https://discourse.vtk.org/u/LucasGandel)
#### Post date: [October 18, 2024, 3:46pm UTC](https://discourse.vtk.org/t/negative-values-in-vtkcamera-projection-transform-breaks-gpu-volume-raycast-mapper/14593/8 "2024-10-18T15:46:16Z")

</div>

Sorry for the late reply. I think the reason why it works better with the depth pass is because the ray origin is computed by taking the projection matrix into account in this case (see [here](https://gitlab.kitware.com/vtk/vtk/-/blob/master/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h#L404)). Maybe a similar approach can be implemented without using the depth pass, but then there will be probably other issues with lighting, clipping,…  
Just to understand the use case, could flipping the image on the CPU with vtkImageFlip be an option? or does it really have to be done at the rendering step?

---

<div class="post-metadata">

### Author: ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)
#### Post date: [October 18, 2024, 4:41pm UTC](https://discourse.vtk.org/t/negative-values-in-vtkcamera-projection-transform-breaks-gpu-volume-raycast-mapper/14593/9 "2024-10-18T16:41:14Z")

</div>

Flipping the image is not an option, as all the sizes are correct as they are (anterior part of the patient is farther from the generator, so magnification factor is smaller than for the posterior side), but the clinician usually wants to see the anterior part appear in the front (occluding the posterior side).

Everything (lighting, etc.) works well for surface rendering, and even for volume rendering with the CPU mapper. Only the GPU mapper is broken with reverse persepective projection.
