I am working on transitioning legacy VTK code (5.6) to 9.1+ and am encountering rendering
artifacts when visualizing a triangulated, mostly flat, 3D surface. The artifact does not occur with
our legacy code but does with builds against VTK tags v9.1.0 and v9.2.0.rc1.
A very basic pipeline with mostly defaults (ie., lighting etc.) but with customize camera parameters
produces the artifact shown below. C++ code is provided. Any suggestions on mitigating or eliminating
this artifact ?
A close up view of a corner of the planar surface:
Overview of the planar surface in wireframe:
Source:
// plane_artifact_vtk.cpp : A demonstration of polydata rendering artifact not present
// in vtk 5.6 (post introduction of shader support in vtk)
//
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkPolyDataReader.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
using namespace std;
int main(int argc, char* argv[])
{
if (2 != argc)
{
std::cout << "Usage: plane_artifact_vtk <filename.vtp>" << std::endl;
return EXIT_SUCCESS;
}
std::string filename(argv[1]);
vtkNew<vtkRenderer> renderer;
vtkNew<vtkCamera> camera;
renderer->SetActiveCamera(camera);
renderer->SetBackground(1, 1, 1);
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer);
renderWindow->SetSize(800, 800);
renderWindow->SetWindowName("Plane Artifact VTK");
vtkNew<vtkRenderWindowInteractor> interactor;
interactor->SetRenderWindow(renderWindow);
vtkNew<vtkInteractorStyleTrackballCamera> style;
interactor->SetInteractorStyle(style);
vtkNew<vtkPolyDataReader> reader;
reader->SetFileName(filename.c_str());
reader->Update();
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(reader->GetOutputPort());
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
renderer->AddViewProp(actor);
double m_fAzimuth = 535;
double m_fDip = 271;
bool m_bParallelProjection = true;
double m_fEast_Offset = -2076927.0490000001;
double m_fNorth_Offset = -14599585.767999999;
double m_fDepth_Offset = -6113.5580000000000;
double m_fDistance = 40003208.092430003;
double m_fZoomFactor = 6499379.5999999996;
int m_nZCoordScale = 1;
// set view up and direction of projection based on document settings
double fAzim = m_fAzimuth / 720.0 * vtkMath::Pi();
double fDip = m_fDip / 720.0 * vtkMath::Pi();
double viewUp[3];
viewUp[2] = cos(fDip);
viewUp[0] = sin(fDip) * sin(fAzim);
viewUp[1] = sin(fDip) * cos(fAzim);
double focalPoint[3];
// set focal point according to offsets
focalPoint[0] = -m_fEast_Offset;;
focalPoint[1] = -m_fNorth_Offset;
focalPoint[2] = m_fDepth_Offset * m_nZCoordScale;
double directionOfProjection[3];
directionOfProjection[2] = -sin(fDip);
directionOfProjection[0] = cos(fDip) * sin(fAzim);
directionOfProjection[1] = cos(fDip) * cos(fAzim);
double position[3];
position[0] = focalPoint[0] - directionOfProjection[0] * m_fDistance;
position[1] = focalPoint[1] - directionOfProjection[1] * m_fDistance;
position[2] = focalPoint[2] - directionOfProjection[2] * m_fDistance;
double viewAngle = 180.0 / vtkMath::Pi() * 0.1 * 6400.0 / m_fZoomFactor;
double m_fParallelScale = 325 * m_fDistance / m_fZoomFactor;
std::cout << "parallel scale: " << m_fParallelScale << std::endl;
std::cout << " distance: " << m_fDistance << std::endl;
std::cout << " zoom factor: " << m_fZoomFactor << std::endl;
std::cout << " east offset: " << m_fEast_Offset << std::endl;
std::cout << " north offset: " << m_fNorth_Offset << std::endl;
std::cout << " depth offset: " << m_fDepth_Offset << std::endl;
std::cout << " azimuth: " << m_fAzimuth << std::endl;
std::cout << " dip: " << m_fDip << std::endl;
camera->SetViewUp(viewUp);
camera->SetPosition(position);
camera->SetFocalPoint(focalPoint);
camera->SetViewAngle(viewAngle);
camera->SetParallelProjection(m_bParallelProjection);
camera->SetParallelScale(m_fParallelScale);
camera->SetClippingRange(m_fDistance / 5, m_fDistance * 5);
interactor->Start();
return EXIT_SUCCESS;
}