- 将volume分别加入renderer中,渲染效果如下
可以看到,渲染中没有层次感。
#include "vtkAxesActor.h"
#include "vtkCamera.h"
#include "vtkColorTransferFunction.h"
#include "vtkCommand.h"
#include "vtkConeSource.h"
#include "vtkGPUVolumeRayCastMapper.h"
#include "vtkImageResample.h"
#include "vtkImageResize.h"
#include "vtkInteractorStyleTrackballCamera.h"
#include "vtkMultiVolume.h"
#include "vtkNew.h"
#include "vtkPiecewiseFunction.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkTestUtilities.h"
#include "vtkVolume16Reader.h"
#include "vtkVolumeProperty.h"
#include "vtkXMLImageDataReader.h"
#include "vtkAbstractMapper.h"
#include "vtkImageData.h"
#include "vtkOutlineFilter.h"
#include "vtkPolyDataMapper.h"
#include "vtkMath.h"
#include <chrono>
int main(int argc, char* argv[])
{
// Load data
vtkNew<vtkVolume16Reader> reader;
reader->SetDataDimensions(64, 64);
reader->SetImageRange(1, 93);
reader->SetDataByteOrderToLittleEndian();
reader->SetFilePrefix(R"(D:\VTK-9.2.6\Testing\Data\headsq\quarter)");
reader->SetDataSpacing(3.2, 3.2, 1.5);
vtkNew<vtkXMLImageDataReader> vaseSource;
vaseSource->SetFileName(R"(D:\VTK-9.2.6\Testing\Data\vase_1comp.vti)");
vtkSmartPointer<vtkXMLImageDataReader> xmlReader = vtkSmartPointer<vtkXMLImageDataReader>::New();
xmlReader->SetFileName(R"(D:\VTK-9.2.6\Testing\Data\hncma-atlas.vti)");
xmlReader->Update();
// Volume 0 (upsampled headmr)
// ---------------------------
vtkNew<vtkImageResize> headmrSource;
headmrSource->SetInputConnection(reader->GetOutputPort());
headmrSource->SetResizeMethodToOutputDimensions();
headmrSource->SetOutputDimensions(128, 128, 128);
headmrSource->Update();
vtkNew<vtkColorTransferFunction> ctf;
ctf->AddRGBPoint(0, 0.0, 0.0, 0.0);
ctf->AddRGBPoint(500, 1.0, 0.5, 0.3);
ctf->AddRGBPoint(1000, 1.0, 0.5, 0.3);
ctf->AddRGBPoint(1150, 1.0, 1.0, 0.9);
vtkNew<vtkPiecewiseFunction> pf;
pf->AddPoint(0, 0.00);
pf->AddPoint(500, 0.15);
pf->AddPoint(1000, 0.15);
pf->AddPoint(1150, 0.85);
vtkNew<vtkPiecewiseFunction> gf;
gf->AddPoint(0, 0.0);
gf->AddPoint(90, 0.1);
gf->AddPoint(100, 0.7);
vtkNew<vtkVolume> vol;
vol->GetProperty()->SetScalarOpacity(pf);
vol->GetProperty()->SetColor(ctf);
vol->GetProperty()->SetGradientOpacity(gf);
vol->GetProperty()->SetInterpolationType(VTK_LINEAR_INTERPOLATION);
// Volume 1 (vase)
// -----------------------------
vtkNew<vtkColorTransferFunction> ctf1;
ctf1->AddRGBPoint(0, 0.0, 0.0, 0.0);
ctf1->AddRGBPoint(500, 0.1, 1.0, 0.3);
ctf1->AddRGBPoint(1000, 0.1, 1.0, 0.3);
ctf1->AddRGBPoint(1150, 1.0, 1.0, 0.9);
vtkNew<vtkPiecewiseFunction> pf1;
pf1->AddPoint(0, 0.0);
pf1->AddPoint(500, 1.0);
vtkNew<vtkPiecewiseFunction> gf1;
gf1->AddPoint(0, 0.0);
gf1->AddPoint(550, 1.0);
vtkNew<vtkVolume> vol1;
vol1->GetProperty()->SetScalarOpacity(pf1);
vol1->GetProperty()->SetColor(ctf1);
vol1->GetProperty()->SetGradientOpacity(gf1);
vol1->GetProperty()->SetInterpolationType(VTK_LINEAR_INTERPOLATION);
vol1->RotateX(-55.);
vol1->SetPosition(80., 50., 130.);
// Volume 2 (brain)
// -----------------------------
vtkNew<vtkPiecewiseFunction> pf2;
pf1->AddPoint(0, 0.0);
pf1->AddPoint(5022, 0.09);
vtkNew<vtkColorTransferFunction> ctf2;
ctf2->AddRGBPoint(0, 1.0, 0.3, 0.2);
ctf2->AddRGBPoint(2511, 0.3, 0.2, 0.9);
ctf2->AddRGBPoint(5022, 0.5, 0.6, 1.0);
vtkNew<vtkPiecewiseFunction> gf2;
gf2->AddPoint(0, 0.0);
gf2->AddPoint(550, 0.5);
vtkNew<vtkVolume> vol2;
vol2->GetProperty()->SetScalarOpacity(pf2);
vol2->GetProperty()->SetColor(ctf2);
vol2->GetProperty()->SetGradientOpacity(gf2);
vol2->GetProperty()->SetInterpolationType(VTK_LINEAR_INTERPOLATION);
vol2->SetScale(0.8, 0.8, 0.8);
vol2->SetPosition(210., 200., -90.);
vol2->RotateX(90.);
vol2->RotateY(-95.);
vol2->RotateZ(-5.);
// Rendering context
vtkNew<vtkRenderWindow> renWin;
renWin->SetSize(512, 512);
renWin->SetMultiSamples(0);
vtkNew<vtkRenderer> ren;
vtkNew<vtkGPUVolumeRayCastMapper> mapper;
mapper->SetInputConnection(headmrSource->GetOutputPort());
vol->SetMapper(mapper);
ren->AddVolume(vol);
vtkNew<vtkGPUVolumeRayCastMapper> mapper1;
mapper1->SetInputConnection(vaseSource->GetOutputPort());
vol1->SetMapper(mapper1);
ren->AddVolume(vol1);
vtkNew<vtkGPUVolumeRayCastMapper> mapper2;
mapper2->SetInputConnection(xmlReader->GetOutputPort());
vol2->SetMapper(mapper2);
ren->AddVolume(vol2);
ren->UseDepthPeelingOn();
ren->UseDepthPeelingForVolumesOn();
renWin->AddRenderer(ren);
ren->SetBackground(0.0, 0.0, 0.0);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
vtkNew<vtkInteractorStyleTrackballCamera> style;
iren->SetInteractorStyle(style);
auto cam = ren->GetActiveCamera();
cam->SetFocalPoint(41.9596, -17.9662, 78.5903);
cam->SetPosition(373.891, 619.954, -53.5932);
cam->SetViewUp(-0.0358384, -0.184856, -0.982112);
renWin->Render();
Multi volume instance
---------------------
//vtkNew<vtkMultiVolume> overlappingVol;
//vtkNew<vtkGPUVolumeRayCastMapper> mapper;
//mapper->SetUseJittering(0);
//overlappingVol->SetMapper(mapper);
Parameters that are global to all of the inputs are currently
set through the vtkVolumeProperty corresponding to the required
input port (port 0)
//vol->GetProperty()->SetInterpolationType(VTK_LINEAR_INTERPOLATION);
//mapper->SetInputConnection(4, xmlReader->GetOutputPort());
//overlappingVol->SetVolume(vol2, 4);
//mapper->SetInputConnection(0, headmrSource->GetOutputPort());
//overlappingVol->SetVolume(vol, 0);
//mapper->SetInputConnection(2, vaseSource->GetOutputPort());
//overlappingVol->SetVolume(vol1, 2);
//ren->AddVolume(overlappingVol);
//renWin->Render();
Remove / add
//mapper->RemoveInputConnection(4, 0);
//overlappingVol->RemoveVolume(4);
//renWin->Render();
//mapper->RemoveInputConnection(2, 0);
//overlappingVol->RemoveVolume(2);
//renWin->Render();
//mapper->SetInputConnection(4, xmlReader->GetOutputPort());
//overlappingVol->SetVolume(vol2, 4);
//renWin->Render();
iren->Start();
return 0;
}
- 采用vtkMultiVolume来渲染
#include "vtkAxesActor.h"
#include "vtkCamera.h"
#include "vtkColorTransferFunction.h"
#include "vtkCommand.h"
#include "vtkConeSource.h"
#include "vtkGPUVolumeRayCastMapper.h"
#include "vtkImageResample.h"
#include "vtkImageResize.h"
#include "vtkInteractorStyleTrackballCamera.h"
#include "vtkMultiVolume.h"
#include "vtkNew.h"
#include "vtkPiecewiseFunction.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkTestUtilities.h"
#include "vtkVolume16Reader.h"
#include "vtkVolumeProperty.h"
#include "vtkXMLImageDataReader.h"
#include "vtkAbstractMapper.h"
#include "vtkImageData.h"
#include "vtkOutlineFilter.h"
#include "vtkPolyDataMapper.h"
#include "vtkMath.h"
#include <chrono>
int main(int argc, char* argv[])
{
// Load data
vtkNew<vtkVolume16Reader> reader;
reader->SetDataDimensions(64, 64);
reader->SetImageRange(1, 93);
reader->SetDataByteOrderToLittleEndian();
reader->SetFilePrefix(R"(D:\VTK-9.2.6\Testing\Data\headsq\quarter)");
reader->SetDataSpacing(3.2, 3.2, 1.5);
vtkNew<vtkXMLImageDataReader> vaseSource;
vaseSource->SetFileName(R"(D:\VTK-9.2.6\Testing\Data\vase_1comp.vti)");
vtkSmartPointer<vtkXMLImageDataReader> xmlReader = vtkSmartPointer<vtkXMLImageDataReader>::New();
xmlReader->SetFileName(R"(D:\VTK-9.2.6\Testing\Data\hncma-atlas.vti)");
xmlReader->Update();
// Volume 0 (upsampled headmr)
// ---------------------------
vtkNew<vtkImageResize> headmrSource;
headmrSource->SetInputConnection(reader->GetOutputPort());
headmrSource->SetResizeMethodToOutputDimensions();
headmrSource->SetOutputDimensions(128, 128, 128);
headmrSource->Update();
vtkNew<vtkColorTransferFunction> ctf;
ctf->AddRGBPoint(0, 0.0, 0.0, 0.0);
ctf->AddRGBPoint(500, 1.0, 0.5, 0.3);
ctf->AddRGBPoint(1000, 1.0, 0.5, 0.3);
ctf->AddRGBPoint(1150, 1.0, 1.0, 0.9);
vtkNew<vtkPiecewiseFunction> pf;
pf->AddPoint(0, 0.00);
pf->AddPoint(500, 0.15);
pf->AddPoint(1000, 0.15);
pf->AddPoint(1150, 0.85);
vtkNew<vtkPiecewiseFunction> gf;
gf->AddPoint(0, 0.0);
gf->AddPoint(90, 0.1);
gf->AddPoint(100, 0.7);
vtkNew<vtkVolume> vol;
vol->GetProperty()->SetScalarOpacity(pf);
vol->GetProperty()->SetColor(ctf);
vol->GetProperty()->SetGradientOpacity(gf);
vol->GetProperty()->SetInterpolationType(VTK_LINEAR_INTERPOLATION);
// Volume 1 (vase)
// -----------------------------
vtkNew<vtkColorTransferFunction> ctf1;
ctf1->AddRGBPoint(0, 0.0, 0.0, 0.0);
ctf1->AddRGBPoint(500, 0.1, 1.0, 0.3);
ctf1->AddRGBPoint(1000, 0.1, 1.0, 0.3);
ctf1->AddRGBPoint(1150, 1.0, 1.0, 0.9);
vtkNew<vtkPiecewiseFunction> pf1;
pf1->AddPoint(0, 0.0);
pf1->AddPoint(500, 1.0);
vtkNew<vtkPiecewiseFunction> gf1;
gf1->AddPoint(0, 0.0);
gf1->AddPoint(550, 1.0);
vtkNew<vtkVolume> vol1;
vol1->GetProperty()->SetScalarOpacity(pf1);
vol1->GetProperty()->SetColor(ctf1);
vol1->GetProperty()->SetGradientOpacity(gf1);
vol1->GetProperty()->SetInterpolationType(VTK_LINEAR_INTERPOLATION);
vol1->RotateX(-55.);
vol1->SetPosition(80., 50., 130.);
// Volume 2 (brain)
// -----------------------------
vtkNew<vtkPiecewiseFunction> pf2;
pf1->AddPoint(0, 0.0);
pf1->AddPoint(5022, 0.09);
vtkNew<vtkColorTransferFunction> ctf2;
ctf2->AddRGBPoint(0, 1.0, 0.3, 0.2);
ctf2->AddRGBPoint(2511, 0.3, 0.2, 0.9);
ctf2->AddRGBPoint(5022, 0.5, 0.6, 1.0);
vtkNew<vtkPiecewiseFunction> gf2;
gf2->AddPoint(0, 0.0);
gf2->AddPoint(550, 0.5);
vtkNew<vtkVolume> vol2;
vol2->GetProperty()->SetScalarOpacity(pf2);
vol2->GetProperty()->SetColor(ctf2);
vol2->GetProperty()->SetGradientOpacity(gf2);
vol2->GetProperty()->SetInterpolationType(VTK_LINEAR_INTERPOLATION);
vol2->SetScale(0.8, 0.8, 0.8);
vol2->SetPosition(210., 200., -90.);
vol2->RotateX(90.);
vol2->RotateY(-95.);
vol2->RotateZ(-5.);
// Rendering context
vtkNew<vtkRenderWindow> renWin;
renWin->SetSize(512, 512);
renWin->SetMultiSamples(0);
vtkNew<vtkRenderer> ren;
//vtkNew<vtkGPUVolumeRayCastMapper> mapper;
//mapper->SetInputConnection(headmrSource->GetOutputPort());
//vol->SetMapper(mapper);
//ren->AddVolume(vol);
//vtkNew<vtkGPUVolumeRayCastMapper> mapper1;
//mapper1->SetInputConnection(vaseSource->GetOutputPort());
//vol1->SetMapper(mapper1);
//ren->AddVolume(vol1);
//vtkNew<vtkGPUVolumeRayCastMapper> mapper2;
//mapper2->SetInputConnection(xmlReader->GetOutputPort());
//vol2->SetMapper(mapper2);
//ren->AddVolume(vol2);
//
//ren->UseDepthPeelingOn();
//ren->UseDepthPeelingForVolumesOn();
renWin->AddRenderer(ren);
ren->SetBackground(0.0, 0.0, 0.0);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
vtkNew<vtkInteractorStyleTrackballCamera> style;
iren->SetInteractorStyle(style);
auto cam = ren->GetActiveCamera();
cam->SetFocalPoint(41.9596, -17.9662, 78.5903);
cam->SetPosition(373.891, 619.954, -53.5932);
cam->SetViewUp(-0.0358384, -0.184856, -0.982112);
renWin->Render();
// Multi volume instance
// ---------------------
vtkNew<vtkMultiVolume> overlappingVol;
vtkNew<vtkGPUVolumeRayCastMapper> mapper;
mapper->SetUseJittering(0);
overlappingVol->SetMapper(mapper);
// Parameters that are global to all of the inputs are currently
// set through the vtkVolumeProperty corresponding to the required
// input port (port 0)
vol->GetProperty()->SetInterpolationType(VTK_LINEAR_INTERPOLATION);
mapper->SetInputConnection(4, xmlReader->GetOutputPort());
overlappingVol->SetVolume(vol2, 4);
mapper->SetInputConnection(0, headmrSource->GetOutputPort());
overlappingVol->SetVolume(vol, 0);
mapper->SetInputConnection(2, vaseSource->GetOutputPort());
overlappingVol->SetVolume(vol1, 2);
ren->AddVolume(overlappingVol);
renWin->Render();
// Remove / add
mapper->RemoveInputConnection(4, 0);
overlappingVol->RemoveVolume(4);
renWin->Render();
mapper->RemoveInputConnection(2, 0);
overlappingVol->RemoveVolume(2);
renWin->Render();
mapper->SetInputConnection(4, xmlReader->GetOutputPort());
overlappingVol->SetVolume(vol2, 4);
renWin->Render();
iren->Start();
return 0;
}
参考: https://blog.csdn.net/qq_33598781/article/details/123037326?spm=1001.2014.3001.5502