# Screen-space ambient occlusion for volume rendering

**URL:** <https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323>\
**Category:** Development\
**Tags:** volume-rendering\
**Created:** [October 19, 2023, 9:16am UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323 "2023-10-19T09:16:17Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![LucasGandel](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lucasgandel/32/18202_2.png) [@LucasGandel](https://discourse.slicer.org/u/LucasGandel)\
**Post date:** [October 25, 2023, 1:35pm UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/21 "2023-10-25T13:35:22Z")

</div>

Thanks for the clarification, I now understand that you need SSAO for semi-transparent surface actors, not volumes. This is yet another story 🙂 which can be partially solved with the information in this topic.  
Similar to what is required for volumes, you will indeed need to change the SSAO pass in the Lights.py script (or VTK later) so that it uses vtkRenderStepPass instead of the opaque pass. As long as you don’t render volume, you don’t need/are not impacted by the VTK hack.  
However, similar hack/commit might be required to fully support SSAO for transparent surface actors: semi-transparent actors do not write to the depth buffer, this must be changed in a similar way as it was done for volumes [here](https://gitlab.kitware.com/LucasGandelKitware/vtk/-/commit/586e173991b60aa6fa24dc261099f76d7cdfea70#632b3677f9257d77462fa7b0ef618b50511becae_53_52).

For now I will focus on implementing the proper fix for volumes in VTK. I’ll see to give a try to transparent actors in the meantime

---

<div class="post-metadata">

**Author:** ![cpinter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/cpinter/32/7995_2.png) [@cpinter](https://discourse.slicer.org/u/cpinter)\
**Post date:** [October 25, 2023, 1:39pm UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/22 "2023-10-25T13:39:35Z")

</div>

Thank you so much @LucasGandel for bearing with me and answering corner case questions 🙂 I understand now, that it is about the depth buffer, and profound changes would be needed to do this fix. OK let’s put this aside for now, I appreciate you helping me understand the root cause!

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 25, 2023, 2:48pm UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/23 "2023-10-25T14:48:32Z")

</div>

Yay, with the Lights module change it all works in Slicer:

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/7/1/7147013c78e32618150708ee4d5f3dd8ef88e493.jpeg)

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/5/4/547b4aa84e1f8b1a0e4d877772609ad567689573.jpeg)

@LucasGandel a few things about the shader:

1. We need to make the opacity threshold (originally 0.5, here 0.25) configurable here, as \>0.0 makes very transparent pieces to cast shadow that is not optimal:

```auto
if(!g_skip && g_srcColor.a > 0.25 && l_updateDepth)

```

1. This line looks suspicious:

```auto
gl_FragData[1] = gl_FragData[1];

```

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 25, 2023, 3:50pm UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/24 "2023-10-25T15:50:13Z")

</div>

I’ve submitted a pull request for the Lights module that takes care of setting up everything (enable SSAO rendering pass for transparent rendering, applies shader replacements, allows customizing the opacity threshold):

> <https://github.com/PerkLab/SlicerSandbox/pull/23>
>
> requires VTK fix described here:
> https://discourse.slicer.org/t/screen-space-am…bient-occlusion-for-volume-rendering/32323/18

I’ll wait for a proper VTK fix from @LucasGandel that we can merge into Slicer’s VTK and then I’ll merge the pull request and the feature will be available for everyone.

Until then the feature is only available for developers who apply the VTK fix locally and use this branch of the Sandbox.

---

<div class="post-metadata">

**Author:** ![LucasGandel](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lucasgandel/32/18202_2.png) [@LucasGandel](https://discourse.slicer.org/u/LucasGandel)\
**Post date:** [October 25, 2023, 4:12pm UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/25 "2023-10-25T16:12:14Z")

</div>

This is fantastic @lassoan, thank you for trying and for creating the branch.  
So I understand that there is interest for it, and that it should be finalized at some point. If yes, I will now focus on the fix for volume occlusion, the rest of the change can be integrated with mapper options or volume properties.  
I completely agree with your points:

1. A configurable threshold makes sense as it can highlights different structures (in addition to prevent weird effect with almost fully transparent pixels when 0.0 is used as you said). I started work in this direction and I think g\_fragColor.a must be used to take the opacity transfer function instead of g\_srcColor.a (at least it makes a difference for RGBA columes I think)
2. Right, this line is non-sense. I just added it because the RenderDoc frame debugger needs anything to be written to the texture, but those fragments are not used in the final blending as no depth is associated to them. This needs to be fixed when mixing volumes and surface to ensure existing fragments are not overridden

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 25, 2023, 4:17pm UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/26 "2023-10-25T16:17:20Z")

</div>

An overview of how much improvement we achieved compared to the baseline (what was possible a few weeks ago) in Slicer’s volume rendering with introducing colorized rendering and SSAO:

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/f/3/f33eede8d3e6d6f913adf32a7698b598e4aa7a7f.jpeg)

With more opaque rendering:

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/1/a/1a60ec48860e35815190ad881fb30bed42748fa4.jpeg)

---

<div class="post-metadata">

**Author:** ![LucasGandel](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lucasgandel/32/18202_2.png) [@LucasGandel](https://discourse.slicer.org/u/LucasGandel)\
**Post date:** [October 25, 2023, 4:22pm UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/27 "2023-10-25T16:22:05Z")

</div>

This is amazing, thanks for sharing!

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 25, 2023, 6:25pm UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/28 "2023-10-25T18:25:28Z")

</div>

Here is a video, that shows details of muscles:

---

<div class="post-metadata">

**Author:** ![jay1987](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jay1987/32/16183_2.png) [@jay1987](https://discourse.slicer.org/u/jay1987)\
**Post date:** [October 26, 2023, 3:02am UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/29 "2023-10-26T03:02:21Z")

</div>

it’s amazing lassoan,can you give us a simple tutorial on how to use slicer to achieve the effect you have?

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 26, 2023, 3:06am UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/30 "2023-10-26T03:06:47Z")

</div>

@LucasGandel needs to do some cleanup of a VTK fix, which may take some time (hopefully not more than a few days?) and then we can make the ambient shading available for everyone. We’ll post updates on this thread.

If you want to access this feature earlier then you ned to build Slicer from source code and apply the VTK fix locally.

---

<div class="post-metadata">

**Author:** ![jay1987](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jay1987/32/16183_2.png) [@jay1987](https://discourse.slicer.org/u/jay1987)\
**Post date:** [October 26, 2023, 3:13am UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/31 "2023-10-26T03:13:35Z")

</div>

thank you lassoan , I will try to hack into vtk follow @LucasGandel vtk’s thread commit ,the rendering looks amazing!

---

<div class="post-metadata">

**Author:** ![LucasGandel](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lucasgandel/32/18202_2.png) [@LucasGandel](https://discourse.slicer.org/u/LucasGandel)\
**Post date:** [October 27, 2023, 6:30am UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/32 "2023-10-27T06:30:26Z")

</div>

Yesterday I could find the fix to bring back volume depth occlusion. The required change will be done in the coming days. I have a project to handle the integration of the depth mask change in VTK so I will start with that. For this we will use the vtkOpenActor::DepthMaskOverride information key.  
@lassoan Is it possible to set the information key from python? like [this](https://gitlab.kitware.com/vtk/vtk/-/blob/master/Rendering/OpenGL2/vtkDepthPeelingPass.cxx#L475)

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 27, 2023, 10:38pm UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/33 "2023-10-27T22:38:38Z")

</div>

You can set those information keys in Slicer in Python like this:

```python
threeDViewWidget = slicer.app.layoutManager().threeDWidget(0)
vrDisplayableManager = threeDViewWidget.threeDView().displayableManagerByClassName("vtkMRMLVolumeRenderingDisplayableManager")

volumeNode = slicer.mrmlScene.GetFirstNodeByClass('vtkMRMLVolumeNode')

volumeActor = vrDisplayableManager.GetVolumeActor(volumeNode)
info = volumeActor.GetPropertyKeys()
if not info:
    info = vtk.vtkInformation()
    volumeActor.SetPropertyKeys(info)
info.Set(vtk.vtkOpenGLActor.GLDepthMaskOverride(), 1)

```

Would it be possible to set enable depth mask override by default to avoid the need for such low-level manipulations? None of the other volume rendering techniques require such calls.

If there are some negative side-effects of enabling depth mask override in some cases then making it optional could make sense, but then there should be more convenient API, for example a method in `vtkVolume`.

---

<div class="post-metadata">

**Author:** ![LucasGandel](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lucasgandel/32/18202_2.png) [@LucasGandel](https://discourse.slicer.org/u/LucasGandel)\
**Post date:** [October 30, 2023, 7:14am UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/34 "2023-10-30T07:14:44Z")

</div>

Perfect, thanks. Eventually it will be enabled by default by the ssao pass so it won’t be required anymore. Same for the shaders replacement and modification of the ssao pass detp texture format. But for now, all the VTK hack from my volume-ssao branch can be replaced with:

1. [VTK!10642](https://gitlab.kitware.com/vtk/vtk/-/merge_requests/10642) makes it possible to use the [GLDepthMaskOverride key](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/33) to write to the depth buffer.
2. [VTK!10644](https://gitlab.kitware.com/vtk/vtk/-/merge_requests/10644) allows for calling `ssaoPass->SetDepthFormat(vtkTextureObject::Fixed32);` to fix the issue with volume depth occlusion
3. [VTK!10645](https://gitlab.kitware.com/vtk/vtk/-/merge_requests/10645) allows to add the following shader replacement to fix the previously hardcoded one:

```auto
  volume->GetShaderProperty()->AddFragmentShaderReplacement("//VTK::ComputeLighting::Exit", false,
    "\n //VTK::ComputeLighting::Exit\
     \n g_dataNormal = -shading_gradient.xyz;",
    false);

```

I will follow up as soon as I can, but the change in the ssao pass to make this automatic should be ready by next week

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 30, 2023, 11:48am UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/35 "2023-10-30T11:48:53Z")

</div>

Thank you for working on this and for clarifying the roadmap. When I reviewed the VTK merge requests I was not sure if we’ll need all the low-level API calls to activate this feature, but it’s great to hear that it’ll be all seamlessly integrated into the existing SSAO feature! I’ll test this and let you know if it all works the same way as before.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [November 17, 2023, 6:15am UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/36 "2023-11-17T06:15:43Z")

</div>

I’ve tried to apply all the VTK changes, enabled GLDepthMaskOverride, changed depth format, and added the shader replacement. Unfortunately, the volume disappears and this message is displayed:

```auto
[VTK] 0(350) : error C1503: undefined variable "g_dataNormal"
[VTK] Shader failed to compile

```

Where g\_dataNormal is defined?

---

<div class="post-metadata">

**Author:** ![LucasGandel](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lucasgandel/32/18202_2.png) [@LucasGandel](https://discourse.slicer.org/u/LucasGandel)\
**Post date:** [November 17, 2023, 5:03pm UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/37 "2023-11-17T17:03:41Z")

</div>

Thanks a lot for following up on this. To answer your question, this is defined in the shader replacement that you must add on the application side for now. See the following code from previous comments:

```auto
vtkShaderProgram::Substitute(fragmentShader, "//VTK::ComputeLighting::Dec",
      "vec3 g_dataNormal; \n"
      "//VTK::ComputeLighting::Dec\n",
      false);

```

However, this won’t be required anymore when everything gets moved to the SSAO pass. I am almost done with that, still need to write a test and open an MR on VTK, but you can access the code on my updated [volume-ssao branch](https://gitlab.kitware.com/LucasGandelKitware/vtk/-/tree/volume-ssao?ref_type=heads).  
The branch has been rebased on master and only [VTK!10644](https://gitlab.kitware.com/vtk/vtk/-/merge_requests/10644) has been cherry-picked because it did not make it yet into VTK ( [VTK!10642](https://gitlab.kitware.com/vtk/vtk/-/merge_requests/10642) and [VTK!10645](https://gitlab.kitware.com/vtk/vtk/-/merge_requests/10645) have been merged).

The only thing that is still required on the application side if using my volume-ssao branch is to set the depth format on the ssao pass: `ssao->SetDepthFormat(vtkTextureObject::Fixed32);`.

Let me know if something is still missing after that, setting the vtkRenderStepPass as a delegate of the SSAO pass is still required on the application too as I did not change the vtkRenderer SSAO pass.

---

<div class="post-metadata">

**Author:** ![LucasGandel](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lucasgandel/32/18202_2.png) [@LucasGandel](https://discourse.slicer.org/u/LucasGandel)\
**Post date:** [November 24, 2023, 12:45pm UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/38 "2023-11-24T12:45:12Z")

</div>

All the low level pending MRs have been merged into VTK and [VTK!10725](https://gitlab.kitware.com/vtk/vtk/-/merge_requests/10725) handles shader replacements in the SSAO pass and is ready for reviews 🎉

I plan to write a post on the Kitware blog to present the approach. If anyone wants to provide data or screenshots, that would be much appreciated. Maybe a second blog post presenting the same at an higher level, with the colorized volume approach, also makes sense, if anyone wants to co-author that. I really think we should communicate more on this now that it is kind of ready. @lassoan WDYT?

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [November 24, 2023, 2:33pm UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/39 "2023-11-24T14:33:42Z")

</div>

Great, thank you very much for all your work on this. I’ll test this and provide data and screenshots. I would also be happy to help with a blog post and probably write a short paper that can be cited, because I think this (along with colorizing volume using segmentation) may be a breakthrough in utilizing data that all the new “AI” segmentation tools provide.

---

<div class="post-metadata">

**Author:** ![rbumm](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/rbumm/32/9404_2.png) [@rbumm](https://discourse.slicer.org/u/rbumm)\
**Post date:** [November 24, 2023, 4:07pm UTC](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323/40 "2023-11-24T16:07:46Z")

</div>

This is fascinating. Is there a way to test this feature ?

[Previous page](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323.md?page=1)

[Next page](https://discourse.slicer.org/t/screen-space-ambient-occlusion-for-volume-rendering/32323.md?page=3)
