问题
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