# Rendering glitches when using vtkSSAOPass and vtkDepthPeelingPass

**URL:** https://discourse.vtk.org/t/rendering-glitches-when-using-vtkssaopass-and-vtkdepthpeelingpass/15762
**Category:** Support
**Created:** [June 26, 2025, 10:04am UTC](https://discourse.vtk.org/t/rendering-glitches-when-using-vtkssaopass-and-vtkdepthpeelingpass/15762 "2025-06-26T10:04:40Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![ctroesch](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/c/c0e974/32.png) [@ctroesch](https://discourse.vtk.org/u/ctroesch)
#### Post date: [June 26, 2025, 10:04am UTC](https://discourse.vtk.org/t/rendering-glitches-when-using-vtkssaopass-and-vtkdepthpeelingpass/15762/1 "2025-06-26T10:04:40Z")

</div>

I there,

I just moved from **VTK 9.3.0** to **VTK 9.5.0** and I experiment rendering glitches when displaying a scene with vtkSSAOPass on MacOS:

 ![image](https://discourse.vtk.org/uploads/default/original/2X/9/91e8f5a9df33ea779664d1ac9a818a1989cb0b35.jpeg)  
 ![image](https://discourse.vtk.org/uploads/default/original/2X/5/565dc99cfe2eb44581db4b4eb5473c10f330dc54.jpeg)

I’m on an MacOS 15.4.1 (Sequoia) and using Xcode 16.3 (Apple clang version 17.0.0).

Here is a simple example to reproduce the issue:

```c++
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkCubeSource.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkOpenGLRenderer.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderStepsPass.h>
#include <vtkSSAOPass.h>
#include <vtkOpaquePass.h>
#include <vtkProperty.h>

int main() {
    // Cube source
    vtkNew<vtkCubeSource> cube;
    cube->SetXLength(1.0);
    cube->SetYLength(1.0);
    cube->SetZLength(1.0);
    cube->Update();

    // Mapper and Actor
    vtkNew<vtkPolyDataMapper> mapper;
    mapper->SetInputConnection(cube->GetOutputPort());

    vtkNew<vtkActor> actor;
    actor->SetMapper(mapper);
    actor->GetProperty()->SetColor(1.0, 0.5, 0.3);
    actor->GetProperty()->SetInterpolationToPBR();
    actor->GetProperty()->SetMetallic(0.3);
    actor->GetProperty()->SetRoughness(0.5);

    // Renderer
    vtkNew<vtkOpenGLRenderer> renderer;
    renderer->SetBackground(0.1, 0.1, 0.1);
    renderer->AddActor(actor);

    // SSAO pass setup
    vtkNew<vtkSSAOPass> ssaoPass;
    vtkNew<vtkOpaquePass> opaquePass;
    ssaoPass->SetDelegatePass(opaquePass); // SSAO wraps opaque geometry

    vtkNew<vtkRenderStepsPass> stepsPass;
    stepsPass->SetOpaquePass(ssaoPass); // Inject SSAO into render pipeline

    renderer->SetPass(stepsPass); // Use composed render pass

    // Render window and interactor
    vtkNew<vtkRenderWindow> renderWindow;
    renderWindow->AddRenderer(renderer);
    renderWindow->SetSize(800, 600);

    vtkNew<vtkRenderWindowInteractor> interactor;
    interactor->SetRenderWindow(renderWindow);

    // Camera setup
    renderer->ResetCamera();
    renderer->GetActiveCamera()->Azimuth(30);
    renderer->GetActiveCamera()->Elevation(30);

    renderWindow->Render();
    interactor->Start();

    return EXIT_SUCCESS;
}

```

```cmake
cmake_minimum_required(VERSION 3.16)

project(vtk-test-app VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_BUILD_TYPE Debug)

# Note: Update path to VTK
set(CMAKE_PREFIX_PATH "../vtk/install/lib/cmake")

find_package(VTK REQUIRED COMPONENTS
  CommonCore
  FiltersSources
  InteractionStyle
  RenderingCore
  RenderingOpenGL2
  RenderingFreeType
  RenderingVolumeOpenGL2
  RenderingSceneGraph
)

if (NOT VTK_FOUND)
  message(FATAL_ERROR "Unable to find the VTK build folder.")
endif()

set(CMAKE_AUTOUIC OFF)

file(GLOB SRC_FILES ${PROJECT_SOURCE_DIR}/*.cpp)

add_executable(vtk-test-app ${SRC_FILES})

target_link_libraries(vtk-test-app PRIVATE ${VTK_LIBRARIES})

# vtk_module_autoinit is needed
vtk_module_autoinit(
  TARGETS vtk-test-app
  MODULES ${VTK_LIBRARIES}
)

```

I had no issue running the example with VTK 9.3.0.

Is this a bug or did I miss something following the update ?

Thanks a lot,

Clément

---

<div class="post-metadata">

### Author: ![lgivord](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lgivord/32/3543_2.png) [@lgivord](https://discourse.vtk.org/u/lgivord)
#### Post date: [June 26, 2025, 1:08pm UTC](https://discourse.vtk.org/t/rendering-glitches-when-using-vtkssaopass-and-vtkdepthpeelingpass/15762/2 "2025-06-26T13:08:10Z")

</div>

It’s definitively a bug, @LucasGandel does that ring a bell ?

---

<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: [June 27, 2025, 6:42am UTC](https://discourse.vtk.org/t/rendering-glitches-when-using-vtkssaopass-and-vtkdepthpeelingpass/15762/3 "2025-06-27T06:42:41Z")

</div>

Your render passes setup looks weird to me. The steps pass should be the delegate of the ssao pass. Here is how the VTK test initializes the render passes:

```auto
  vtkNew<vtkRenderStepsPass> basicPasses;

  vtkNew<vtkSSAOPass> ssao;
  ssao->SetRadius(0.05);
  ssao->SetKernelSize(128);
  ssao->SetDelegatePass(basicPasses);

  vtkOpenGLRenderer* glrenderer = vtkOpenGLRenderer::SafeDownCast(renderer);
  glrenderer->SetPass(ssao);

```

Is the result the same if you use this code?

---

<div class="post-metadata">

### Author: ![ctroesch](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/c/c0e974/32.png) [@ctroesch](https://discourse.vtk.org/u/ctroesch)
#### Post date: [June 27, 2025, 8:52am UTC](https://discourse.vtk.org/t/rendering-glitches-when-using-vtkssaopass-and-vtkdepthpeelingpass/15762/4 "2025-06-27T08:52:48Z")

</div>

Thanks for the replies.

You are right, your configuration works to display the SSAO, however when I add a depth peeling pass, the SSAO doesn’t work anymore I get the following warning:

> vtkOpenGLState.cxx:623 WARN| Attempt to set draw buffers from a Framebuffer Object that is not bound.

I guess there is something wrong in the way I set up the rendering passes, here is my updated code:

```c++
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkCubeSource.h>
#include <vtkDepthPeelingPass.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkOBJReader.h>
#include <vtkOpaquePass.h>
#include <vtkOpenGLRenderer.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderStepsPass.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSSAOPass.h>

#include <array>
#include <string>

vtkSmartPointer<vtkActor> read(const std::string& filename, std::array<double, 4> color)
{
    // Read the OBJ file
    vtkNew<vtkOBJReader> reader;
    reader->SetFileName(filename.c_str());
    reader->Update();

    // Mapper and Actor
    vtkNew<vtkPolyDataMapper> mapper;
    mapper->SetInputConnection(reader->GetOutputPort());

    const auto actor = vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);
    actor->GetProperty()->SetColor(color[0], color[1], color[2]);
    actor->GetProperty()->SetOpacity(color[3]);
    actor->GetProperty()->SetInterpolationToPBR();
    actor->GetProperty()->SetMetallic(0);
    actor->GetProperty()->SetRoughness(0.5);

    return actor;
}

int main() {

    // Renderer
    vtkNew<vtkOpenGLRenderer> renderer;
    renderer->SetBackground(0.1, 0.1, 0.1);

    // Load meshes
    renderer->AddActor(read("Bronchus.obj", { 1, 0.9, 0.9, 1 }));
    renderer->AddActor(read("Pulmonary_Artery.obj", { 1, 0.1, 0.1, 1 }));
    renderer->AddActor(read("Pulmonary_Vein.obj", { 0.2, 0.4, 1, 1 }));
    renderer->AddActor(read("Left_Lung.obj", { 1, 0.8, 0.9, 0.4 }));

    // Create steps pass
    vtkNew<vtkRenderStepsPass> stepsPass;

    // Depth Peeling pass
    vtkNew<vtkDepthPeelingPass> depthPeelingPass;
    depthPeelingPass->SetMaximumNumberOfPeels(8);
    depthPeelingPass->SetOcclusionRatio(0);
    depthPeelingPass->SetTranslucentPass(stepsPass->GetTranslucentPass());
    stepsPass->SetTranslucentPass(depthPeelingPass);

    // SSAO pass setup
    vtkNew<vtkSSAOPass> ssaoPass;
    ssaoPass->SetDelegatePass(stepsPass);
    ssaoPass->SetRadius(20);
    ssaoPass->SetKernelSize(256);

    // Use SSAO pass as render pass
    renderer->SetPass(ssaoPass);

    // Render window and interactor
    vtkNew<vtkRenderWindow> renderWindow;
    renderWindow->AddRenderer(renderer);
    renderWindow->SetSize(800, 600);

    vtkNew<vtkRenderWindowInteractor> interactor;
    interactor->SetRenderWindow(renderWindow);

    // Camera setup
    renderer->ResetCamera();
    renderer->GetActiveCamera()->Elevation(-90);

    renderWindow->Render();
    interactor->Start();

    return EXIT_SUCCESS;
}

```

And this is the result with and without depth peeling:

 ![image](https://discourse.vtk.org/uploads/default/original/2X/e/e8c88c1f60a04120660992a862f4466a45cedca7.jpeg) ![image](https://discourse.vtk.org/uploads/default/original/2X/d/d4d675ca5e083cd5ed61be24c08821d2af34f0ec.jpeg)

Any clue on what is wrong with my configuration ?

Thanks a lot,

Clément

---

<div class="post-metadata">

### Author: ![ctroesch](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/c/c0e974/32.png) [@ctroesch](https://discourse.vtk.org/u/ctroesch)
#### Post date: [June 27, 2025, 9:39am UTC](https://discourse.vtk.org/t/rendering-glitches-when-using-vtkssaopass-and-vtkdepthpeelingpass/15762/5 "2025-06-27T09:39:26Z")

</div>

Alright, I managed to make it work by using a custom `vtkRenderPassCollection` and a dedicated SSAO camera pass.

Someone had a similar issue in python:

> [@SSAO peculiar effect with translucent geometry](https://discourse.vtk.org/t/ssao-peculiar-effect-with-translucent-geometry/4410/2):
>
> The odd color behavior is related to an internal color buffer that you are not supposed to see. Note that you will be able to enable SSAO without render passes in VTK 9.1. In the mean time, you can try something equivalent to [F3D render passes](https://gitlab.kitware.com/f3d/f3d/-/blob/master/src/vtkF3DRenderPass.cxx#L125): lightsP = vtk.vtkLightsPass() opaqueP = vtk.vtkOpaquePass() translucentP = vtk.vtkTranslucentPass() volumeP = vtk.vtkVolumetricPass() collection = vtk.vtkRenderPassCollection() collection.AddItem(lightsP) # opaque passes …

For anyone interested this is my final setup to make SSAO & Depth Peeling work together:

```c++
    vtkNew<vtkOpaquePass> opaque;

    vtkNew<vtkCameraPass> ssaoCameraPass;
    ssaoCameraPass->SetDelegatePass(opaque);

    vtkNew<vtkSSAOPass> ssaoPass;
    ssaoPass->SetDelegatePass(ssaoCameraPass); // SSAO applies to opaque geometry
    ssaoPass->SetRadius(20);
    ssaoPass->SetKernelSize(256);

    // Depth peeling for translucent geometry
    vtkNew<vtkDepthPeelingPass> peelingPass;
    peelingPass->SetMaximumNumberOfPeels(16);
    peelingPass->SetOcclusionRatio(0.01);

    vtkNew<vtkTranslucentPass> translucentPass;
    peelingPass->SetTranslucentPass(translucentPass);

    vtkNew<vtkLightsPass> lights;

    // Compose the sequence
    vtkNew<vtkRenderPassCollection> passes;
    passes->AddItem(lights);
    passes->AddItem(ssaoPass); // SSAO for opaque geometry
    passes->AddItem(peelingPass); // Depth peeling for translucent

    vtkNew<vtkSequencePass> sequence;
    sequence->SetPasses(passes);

    // Wrap it into a camera pass
    vtkNew<vtkCameraPass> cameraPass;
    cameraPass->SetDelegatePass(sequence);

    // Set the final pass
    renderer->SetPass(cameraPass);

```

 ![image](https://discourse.vtk.org/uploads/default/original/2X/5/5982b32f1c91c08456b0f7a44bb4a9db22785807.jpeg)

Thanks for the help,

Clément

---

<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: [June 27, 2025, 11:14am UTC](https://discourse.vtk.org/t/rendering-glitches-when-using-vtkssaopass-and-vtkdepthpeelingpass/15762/6 "2025-06-27T11:14:29Z")

</div>

Nice, thanks for sharing!
