vtk depth peeling issue doing multiple renders

感情迁移 提交于 2019-12-08 06:40:47

问题


We recently encountered strange behavior of VTK (v7) after rendering a transparent object for the second time using depth peeling.

The first render looks nice, rendering transparency as it should. After closing the render window and creating another one (same set-up), vtk shows an empty render and the application/python crashes after closing that window.

Problem Event Name: APPCRASH
Application Name: Test.exe
Application Version: 0.0.0.0
Application Timestamp: 57be97a5
Fault Module Name: nvoglv64.DLL
Fault Module Version: 9.18.13.2762
Fault Module Timestamp: 526ed933
Exception Code: c0000005
Exception Offset: 000000000062e180

I included a small example below, both python (3.5) and C++ seem to behave similarly.

c++:

#include "vtkCylinderSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkProperty.h"
#include "vtkCamera.h"
#include "vtkSmartPointer.h"

int main()
{
    // This creates a polygonal cylinder model with eight circumferential facets
    // (i.e, in practice an octagonal prism).
    vtkSmartPointer<vtkCylinderSource> cylinder =
        vtkSmartPointer<vtkCylinderSource>::New();
    cylinder->SetResolution(8);

    // The mapper is responsible for pushing the geometry into the graphics library.
    // It may also do color mapping, if scalars or other attributes are defined.
    vtkSmartPointer<vtkPolyDataMapper> cylinderMapper =
        vtkSmartPointer<vtkPolyDataMapper>::New();
    cylinderMapper->SetInputConnection(cylinder->GetOutputPort());

    // The actor is a grouping mechanism: besides the geometry (mapper), it
    // also has a property, transformation matrix, and/or texture map.
    // Here we set its color and rotate it around the X and Y axes.
    vtkSmartPointer<vtkActor> cylinderActor =
        vtkSmartPointer<vtkActor>::New();
    cylinderActor->SetMapper(cylinderMapper);
    cylinderActor->GetProperty()->SetColor(1.0000, 0.3882, 0.2784);
    cylinderActor->RotateX(30.0);
    cylinderActor->RotateY(-45.0);
    cylinderActor->GetProperty()->SetOpacity(0.5);

    // The renderer generates the image
    // which is then displayed on the render window.
    // It can be thought of as a scene to which the actor is added
    vtkSmartPointer<vtkRenderer> renderer =
        vtkSmartPointer<vtkRenderer>::New();
    renderer->AddActor(cylinderActor);
    renderer->SetBackground(0.1, 0.2, 0.4);
    // Zoom in a little by accessing the camera and invoking its "Zoom" method.
    renderer->ResetCamera();
    renderer->GetActiveCamera()->Zoom(1.5);

    // The render window is the actual GUI window
    // that appears on the computer screen
    vtkSmartPointer<vtkRenderWindow> renderWindow =
        vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->SetSize(200, 200);
    renderWindow->AddRenderer(renderer);

    // 1. Use a render window with alpha bits (as initial value is 0 (false)):
    renderWindow->SetAlphaBitPlanes(true);

    // 2. Force to not pick a framebuffer with a multisample buffer
    // (as initial value is 8):
    renderWindow->SetMultiSamples(0);

    // 3. Choose to use depth peeling (if supported) (initial value is 0 (false)):
    renderer->SetUseDepthPeeling(true);

    // 4. Set depth peeling parameters
    // - Set the maximum number of rendering passes (initial value is 4):
    renderer->SetMaximumNumberOfPeels(100);
    // - Set the occlusion ratio (initial value is 0.0, exact image):
    renderer->SetOcclusionRatio(0.1);

    // The render window interactor captures mouse events
    // and will perform appropriate camera or actor manipulation
    // depending on the nature of the events.
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow(renderWindow);

    // This starts the event loop and as a side effect causes an initial render.
    renderWindowInteractor->Start();




    // This creates a polygonal cylinder model with eight circumferential facets
    // (i.e, in practice an octagonal prism).
    vtkSmartPointer<vtkCylinderSource> cylinder2 =
        vtkSmartPointer<vtkCylinderSource>::New();
    cylinder2->SetResolution(8);

    // The mapper is responsible for pushing the geometry into the graphics library.
    // It may also do color mapping, if scalars or other attributes are defined.
    vtkSmartPointer<vtkPolyDataMapper> cylinderMapper2 =
        vtkSmartPointer<vtkPolyDataMapper>::New();
    cylinderMapper2->SetInputConnection(cylinder2->GetOutputPort());

    // The actor is a grouping mechanism: besides the geometry (mapper), it
    // also has a property, transformation matrix, and/or texture map.
    // Here we set its color and rotate it around the X and Y axes.
    vtkSmartPointer<vtkActor> cylinderActor2 =
        vtkSmartPointer<vtkActor>::New();
    cylinderActor2->SetMapper(cylinderMapper2);
    cylinderActor2->GetProperty()->SetColor(1.0000, 0.3882, 0.2784);
    cylinderActor2->RotateX(30.0);
    cylinderActor2->RotateY(-45.0);
    cylinderActor2->GetProperty()->SetOpacity(0.5);

    // The renderer generates the image
    // which is then displayed on the render window.
    // It can be thought of as a scene to which the actor is added
    vtkSmartPointer<vtkRenderer> renderer2 =
        vtkSmartPointer<vtkRenderer>::New();
    renderer2->AddActor(cylinderActor);
    renderer2->SetBackground(0.1, 0.2, 0.4);
    // Zoom in a little by accessing the camera and invoking its "Zoom" method.
    renderer2->ResetCamera();
    renderer2->GetActiveCamera()->Zoom(1.5);

    // The render window is the actual GUI window
    // that appears on the computer screen
    vtkSmartPointer<vtkRenderWindow> renderWindow2 =
        vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow2->SetSize(200, 200);
    renderWindow2->AddRenderer(renderer2);

    // 1. Use a render window with alpha bits (as initial value is 0 (false)):
    renderWindow2->SetAlphaBitPlanes(true);

    // 2. Force to not pick a framebuffer with a multisample buffer
    // (as initial value is 8):
    renderWindow2->SetMultiSamples(0);

    // 3. Choose to use depth peeling (if supported) (initial value is 0 (false)):
    renderer2->SetUseDepthPeeling(true);

    // 4. Set depth peeling parameters
    // - Set the maximum number of rendering passes (initial value is 4):
    renderer2->SetMaximumNumberOfPeels(100);
    // - Set the occlusion ratio (initial value is 0.0, exact image):
    renderer2->SetOcclusionRatio(0.1);

    // The render window interactor captures mouse events
    // and will perform appropriate camera or actor manipulation
    // depending on the nature of the events.
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor2 =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor2->SetRenderWindow(renderWindow2);

    // This starts the event loop and as a side effect causes an initial render.
    renderWindowInteractor2->Start();

    return 0;
}

and python:

import vtk

###
# First Render
###

ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
ren.SetBackground([1., 1., 1.])
ren.SetUseDepthPeeling(1)
ren.SetOcclusionRatio(0.1)
ren.SetMaximumNumberOfPeels(100)
renWin.SetMultiSamples(0)
renWin.SetAlphaBitPlanes(1)

# create a renderwindowinteractor
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)

# create source
source = vtk.vtkCylinderSource()
source.SetCenter(0, 0, 0)
source.SetRadius(5.0)
source.SetHeight(7.0)
source.SetResolution(100)
source.Update()

# mapper
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputData(source.GetOutput())

# actor
actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor.GetProperty().SetOpacity(0.5)
# assign actor to the renderer
ren.AddActor(actor)
ren.ResetCamera()
# enable user interface interactor
iren.Initialize()
renWin.Render()
# print(ren)
iren.Start()
# close_window(iren)
# del renWin, ren


###
# Second Render
###

ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
ren.SetBackground([1., 1., 1.])
ren.SetUseDepthPeeling(1)
ren.SetOcclusionRatio(0.1)
ren.SetMaximumNumberOfPeels(100)
renWin.SetMultiSamples(0)
renWin.SetAlphaBitPlanes(1)

# create a renderwindowinteractor
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)

# create source
source = vtk.vtkCylinderSource()
source.SetCenter(0, 0, 0)
source.SetRadius(5.0)
source.SetHeight(7.0)
source.SetResolution(100)
source.Update()

# mapper
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputData(source.GetOutput())

# actor
actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor.GetProperty().SetOpacity(0.5)
# assign actor to the renderer
ren.AddActor(actor)
ren.ResetCamera()
# enable user interface interactor
iren.Initialize()
renWin.Render()
iren.Start()

来源:https://stackoverflow.com/questions/39138909/vtk-depth-peeling-issue-doing-multiple-renders

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!