VTK实现电影级渲染效果(CVR)

        目前vtk9.2.2版本中已经集成了ray marching(光线步进)算法实现的体渲染功能,官方博客中已经介绍为电影级体渲染了,如图:

 

7ee3210fa8054ea08c712772bcecc34e.png

        此效果是在3d显示器上的显示效果,就此效果来看说是电影级渲染效果也没什么问题,但是和光线追踪来实现的CVR还是差一些,下图为光线追踪的方法来实现的CVR。

a8e5325045734c5b916768491b7946a3.png

        首先可以先了解下这几个名词概念

Ray Marching 光线步进 基本只用于volumetric(体积绘制)

RayTracing 光线追踪 在与物体相交后会选一个随机方向继续跟踪,并根据BRDF计算颜色(全局照明 (GI),反射)

Ray Casting 光线投射 该算法的计算不会停留在物体的表面,而会沿着射线穿过物体内部进行采样,且不会产生二次射线。我们在VTK中使用的vtkGPUVolumeRayCastMapper就是光线投射原理。

        VTK实现Ray Marching也是基于光线投射的mapper,只是加了两个接口控制。并且最好自己加上灯光,且控制灯光的旋转等。

    vtkNew<vtkGPUVolumeRayCastMapper> mapper;
	mapper->SetAutoAdjustSampleDistances(0);
	mapper->SetSampleDistance(0.5);
	//mapper->UseJitteringOn();
	mapper->SetInputData(reader->GetOutput());
	mapper->SetGlobalIlluminationReach(0.75);
	mapper->SetVolumetricScatteringBlending(1.0);

SetGlobalIlluminationReach 控制着射向光线的次级光线的范围/范围。值0.0表示只渲染局部阴影(但它更快),值1.0表示渲染所有阴影(但它更慢)。

SetVolumetricScatteringBlending 控制散射模型混合的效果。

 效果实现:

                    25eb9a6eee244abf9b6cfbfafe1fd7d2.png

 代码:

#include <vtkNew.h>
#include <vtkNIFTIImageReader.h>
#include <vtkFixedPointVolumeRayCastMapper.h>
#include <vtkImageGaussianSmooth.h>
#include <vtkVolumeProperty.h>
#include <vtkPiecewiseFunction.h>
#include <vtkColorTransferFunction.h>
#include <vtkVolume.h>
#include <vtkRenderer.h>
#include <vtkCamera.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkGPUVolumeRayCastMapper.h>
#include <vtkPiecewiseFunction.h>
#include <vtkColorTransferFunction.h>
#include <vtkWindowToImageFilter.h>
#include <vtkLight.h>
using namespace std;

int main()
{
	vtkNew<vtkNIFTIImageReader> reader;
	reader->SetFileName(R"(./00001741.nii.gz)");
	reader->Update();

	vtkNew<vtkGPUVolumeRayCastMapper> mapper;
	mapper->SetAutoAdjustSampleDistances(0);
	mapper->SetSampleDistance(0.5);
	//mapper->UseJitteringOn();
	mapper->SetInputData(reader->GetOutput());
	mapper->SetGlobalIlluminationReach(0.75);
	mapper->SetVolumetricScatteringBlending(1.0);

	vtkNew<vtkVolume> volume;
	volume->SetMapper(mapper);


	vtkNew<vtkVolumeProperty> volumeProperty;
	volumeProperty->SetInterpolationTypeToLinear();
	volumeProperty->ShadeOn();  //打开或者关闭阴影测试
	volumeProperty->SetAmbient(0.55);
	volumeProperty->SetDiffuse(0.85);  //漫反射
	volumeProperty->SetSpecular(0.54); //镜面反射
	volumeProperty->SetSpecularPower(69); //镜面反射

	//设置不透明度
	vtkNew<vtkPiecewiseFunction> compositeOpacity;
	compositeOpacity->AddPoint(-1000, 0.00);
	compositeOpacity->AddPoint(100, 0.00);
	compositeOpacity->AddPoint(300, 0.879);
	compositeOpacity->AddPoint(478, 0.879);
	compositeOpacity->AddPoint(1500, 0.901);
	volumeProperty->SetScalarOpacity(compositeOpacity); //设置不透明度传输函数

	vtkNew<vtkColorTransferFunction> color;
	color->AddRGBPoint(-1000, 0.00, 0.00, 0.00);
	color->AddRGBPoint(100, 220/255., 21/255., 3/255.);
	color->AddRGBPoint(300, 250/255., 1.00, 189/255.);
	color->AddRGBPoint(478, 224/255., 1, 249/255.);
	color->AddRGBPoint(1500, 1, 1, 1);
	volumeProperty->SetColor(color);

	volume->SetProperty(volumeProperty);

	vtkNew<vtkRenderer>	ren;
	ren->AddActor(volume);
	ren->SetBackground(0, 0, 0);
	ren->ResetCamera();
	vtkCamera* camera = ren->GetActiveCamera();
	camera->Elevation(-70);

	ren->ClearLights();
	ren->RemoveAllLights();

	double* lightPosition = camera->GetPosition();
	double lightPositions[3] = { lightPosition[0], lightPosition[1], lightPosition[2]-100 };
	vtkNew<vtkLight> light;
	light->SetLightTypeToSceneLight();
	light->SetPosition(lightPositions);
	light->SetPositional(true);
	light->SetAmbientColor(0.3, 0.2, 0.1);
	light->SetConeAngle(60);
	light->SetFocalPoint(camera->GetFocalPoint());
	light->SetIntensity(1.2);
	ren->AddLight(light);

	vtkNew<vtkRenderWindow> renWin;
	renWin->AddRenderer(ren);

	vtkNew<vtkRenderWindowInteractor> iren;
	vtkNew<vtkInteractorStyleTrackballCamera> style;
	iren->SetRenderWindow(renWin);
	iren->SetInteractorStyle(style);
	renWin->SetSize(1024, 768);
	renWin->Render();

	iren->Start();

	return 0;
}

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
VTK(Visualization Toolkit)是一个用于可视化和图形处理的开源软件包,可用于创建各种光滑、渐变和复杂的3D图形。要使用VTK实现草图绘制,可以按照以下步骤进行: 1. 导入所需的VTK库: 通过在代码开始部分添加必要的VTK库导入语句,如“import vtk”来导入VTK相关的库函数。 2. 创建绘制窗口和渲染器: 使用vtkRenderWindow类创建一个绘制窗口,并使用vtkRenderer类创建一个渲染器对象。将渲染器与绘制窗口相关联,以便可以在窗口中显示渲染结果。 3. 创建草图绘制工具: 使用VTK的一些基本几何图元(如线段、圆等)和交互操作类来创建绘制工具。例如,可以使用vtkLineSource类创建直线,使用vtkCircleSource类创建圆等。 4. 连接绘制工具和渲染器: 将绘制工具添加到渲染器中,以便可以在渲染器中显示绘制的草图。使用vtkActor类将绘制工具与渲染器关联起来,并设置绘制工具在渲染器中显示的属性,例如颜色和线宽等。 5. 设置交互操作: 使用vtkRenderWindowInteractor类创建一个交互操作对象,以便用户可以与绘制窗口进行交互。例如,用户可以使用鼠标或触摸屏输入来绘制草图。 6. 更新渲染: 在设置好交互操作后,调用vtkRenderWindow类的Render方法,更新渲染器并在绘制窗口中显示草图。 通过上述步骤,就可以使用VTK实现草图绘制了。当用户在绘制窗口中进行绘制时,草图绘制工具会生成相应的几何图元,并在渲染器中显示出来。用户可以根据需要修改绘制结果,也可以保存草图为文件,以便后续使用或分析。绘制过程中,交互操作还可以提供一些功能,如平移、缩放和旋转等操作,以便更方便地绘制草图。总之,使用VTK实现草图绘制可以为用户提供一个简单易用、灵活多样的绘图工具。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

混元太极马保国

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值