Camera Clipping with 2 Renderers

Current Setup:

  • I have 2 renderers, gridRenderer and geoRenderer, within 2 layers of a render window:
gridRenderer->SetLayer(0);
geoRenderer->SetLayer(1);
RenderWindow()->SetNumberOfLayers(2);
RenderWindow()->AddRenderer(geoRenderer);
RenderWindow()->AddRenderer(geoRenderer);
  • I then connect their interactor by setting both of their active cameras to the same one:
 gridRenderer->SetActiveCamera(geoRenderer->GetActiveCamera());

This successfully allows me to have a grid in the background, with a geometry in the foreground.

Problem:

  • The camera’s plane clipping is only focused on the geoRenderer, causing the much larger gridRenderer’s actor to be clipped out.

Similar Issue:

  • https://gitlab.kitware.com/vtk/vtk/issues/17107

  • The difference between my issue and this one is that I am updating both the gridRender’s and geoRenderer’s actors, sometimes removing all of the actors within a renderer entirely (empty renderer could mess up the clipping planes, not rendering anything, if the camera chooses it as the active renderer).

  • My assumption is that VTK is confused as to which renderer to use in order to set the shared camera’s clipping planes. I tried using vtkRenderer::ResetCameraClippingRange() on both of the renderer’s but cannot get the clipping planes to form properly

  • Is there someway I can tell VTK which renderer to look at when resetting the clipping planes/camera?

You might need to disable the automatic clipping range if you set it manually.
vtkInteractorStyle::AutoAdjustCameraClippingRange

1 Like

When calling ResetCameraClippingRange manually, you will have to compute the bounds for each renderer (using ComputeVisiblePropBounds method), combine the two bounds, and call ResetCameraClippingRange with the resulting bound as the argument.

1 Like

Thank you for the information, this is what I have tried along with turning off AutoAdjustCameraClippingRange:

double geoCB[6];
double gridCB[6];
geoRenderer->ComputeVisiblePropBounds(geoCB);
gridRenderer->ComputeVisiblePropBounds(gridCB);
double finalCB[6];
for (int i = 0; i < 6; i++) {
  if (i % 2 == 0) {
    // Even Index is Min
    if (geoCB[i] < gridCB[i]) {
      finalCB[i] = geoCB[i];
    } else {
      finalCB[i] = gridCB[i];
    }
  } else {
    // Odd Index is Max
    if (geoCB[i] > gridCB[i]) {
      finalCB[i] = geoCB[i];
    } else {
      finalCB[i] = gridCB[i];
    }
  }
}
geoRenderer->ResetCameraClippingRange(finalCB);

But the clipping ranges are now more crazy…

Perhaps my understanding of the bounding box is wrong?

I completely misunderstood how clipping planes work. To easily fix this you simply set the minRanges to a very small number, and the maxRanges to a very large one.

Be aware that doing this reduce precision of the depth buffer and you might have depth testing failures.

2 Likes

What would be the best way to remedy/mitigate this?

The code above is correct (you can simplify it using vtkBoundingBox methods though).
Do you reset the clipping range before each Render call?

Thank you for the information but I am confused with your question, are you asking if

I reset the clipping range before each Render call

in regards to the code above?

If so no, in that implementation I only did so when updating my vtkUnstructuredGrids (the meshes of actors). Should i do it before every Render call?

Yes indeed, clipping ranges should be updated each time the camera or the actors move.
One possibility is to override vtkRenderWindowInteractor::Render in order to add your code before the call to this->RenderWindow->Render()

1 Like

Thank you so much for this advice, I didn’t have the slightest idea that you would have to do this every single time before calling RenderWindow->Render().

I managed to make my own implementation of vtkRenderWindow, overriding Render(), calculating the new clipping planes before calling the standard Render() at the end of my override.

The depth filter literally started to die when I implemented some tessellation, and if it wasn’t for this I would of had no idea what was going wrong, so perfect timing :smile:

1 Like