前言
上次学习了vtk中一个简单的例子,涉及到圆锥模型(vtkConeSource)、映射器(vtkPolyDataMapper)、对象(vtkActor)、场景(vtkRenderer)、渲染窗口(vtkRenderWindow),交互器(vtkWindowInteractor),一种交互风格(vtkInteractorStyleTrackballCamera),这次在其基础上学习了灯光、相机、和vtk中颜色属性。
灯光
在上个例子中以舞台剧来理解VTK,在舞台剧中灯光肯定不是唯一的,是可以存在多个的。首先我们先实例化一个灯光,灯光颜色设置为绿色、位置在(0,0,1)。
//加入灯光
vtkSmartPointer<vtkLight> light1 = vtkSmartPointer<vtkLight>::New();
light1->SetColor(0, 1, 0);//设置灯光颜色为绿色
light1->SetPosition(0, 0, 1);//设置灯光的位置
light1->SetFocalPoint(renderer->GetActiveCamera()->GetFocalPoint());//设置灯光的焦点
renderer->AddLight(light1);//将其添加到渲染场景中
将这段代码添加到渲染场景之后,运行可以查看效果如下
灯光是可以多个存在的,那我们可以再添加一个灯光,颜色设置为红色,位置放在(0,0,-1)
vtkSmartPointer<vtkLight>light2 = vtkSmartPointer<vtkLight>::New();
light2->SetColor(1, 0, 0);
light2->SetPosition(0, 0, -1);
light2->SetFocalPoint(renderer->GetActiveCamera()->GetFocalPoint());
renderer->AddLight(light2);
运行效果如下:
我们可以明显看到物体受到两个灯光的照射,展现出两种不同的颜色。
相机
观众的眼睛就像是VTK中的相机,每个人看到的场景都是唯一的,所以相机是唯一的。在VTK中相机用类vtkCamera表示,在电脑屏幕上显示都是二维的所以需要利用相机将三维场景投影变换到二维平面。
实例化一个相机对象
vtkSmartPointer<vtkCamera>camera = vtkSmartPointer<vtkCamera>::New();
从上图可以看出相机的几个关键要素:
- 相机位置:相机的位置,SetPosition()方法设置
- 相机焦点:SetFocusPoint()
- 相机朝向:相当于正着看还是倒着看,SetViewUp()设置
- 投影方向:相机到焦点的向量方向
- 投影方法:确定Actor如何映射到像平面,VTK中提供了两种方法:正交投影和透视投影,正交投影也称平行投影,进入相机的光线是平行的;透视投影中所有的光线相交于一点
- 视角:SetViewAngle()设置,默认30°
前后裁剪平面:裁剪平面与投影方向相交,一般是垂直的。用于评估Actor与相机距离的远近,只有在裁剪平面之间的Actor才是可见的,用SetClippingRange()设置
下面这两张图片是展示相机绕焦点运动和焦点绕相机运动的方向示意图,图中展示了大量的控制相机运动的方法如Roll()、Yaw()、Pitch()等,具体的细节可以查看https://vtk.org/doc/nightly/html/classvtkCamera.html#a24f20bd3d0d94309af789aa2c3f4da32
图a相机绕焦点运动 图b焦点绕相机运动
例子
下面这段代码是具体实例化一个相机设置其参数,并添加到渲染场景中。
vtkSmartPointer<vtkCamera>camera = vtkSmartPointer<vtkCamera>::New();
camera->SetPosition(0,5,0);
camera->SetFocalPoint(0,0,0);
camera->SetViewUp(0,0,0.5);
renderer->SetActiveCamera(camera);
结果
另一种方法
其实vtkRenderer中自带有一个相机,我们也可以获取它的相机进行参数的设定
renderer->GetActiveCamera()->SetPosition(0,5,0);
renderer->GetActiveCamera()->SetFocalPoint(0, 0, 0);
renderer->GetActiveCamera()->SetViewUp(0, 0, 0.5);
renderer->ResetCamera();
结果
颜色
颜色是每个Actor重要的属性之一。VTK中采用的是RGB和HSV两种颜色系统来描述。
RGB颜色系统
RGB颜色系统由三个颜色分量:红色(R)、绿色(G)、蓝色(B),这三个分量在VTK中的取值范围都是0~1,(0,0,0)表示黑色,(1,1,1)表示白色。可以采用vtkProperty::GetColor(double & r, double & g, double & b)设置Actor的颜色。
HSV颜色系统
HSV同样是采用三个分量来设置颜色:色相(Hue)、饱和度(Saturation)、值(Value)。色相就是颜色的基本属性也就是颜色的名称,如红色、绿色、蓝色等;饱和度就是颜色的纯度,其值越高则越纯;值也就是强度Intensity或者Bright,值为0表示黑色,值为1表示最亮的颜色。这三个分量在VTK中取值范围也是0~1。
全部的代码
//***********************************
//说明:灯光、相机
//时间:2020.08.11
//作者:BOO
//********************************
#include<vtkSmartPointer.h>
#include<vtkConeSource.h>
#include<vtkPolyDataMapper.h>
#include<vtkActor.h>
#include<vtkRenderer.h>
#include<vtkRenderWindow.h>
#include<vtkRenderWindowInteractor.h>
#include<vtkInteractorStyleTrackballCamera.h>
#include<vtkLight.h>
#include<vtkCamera.h>
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType)
int main()
{
//圆锥模型
vtkSmartPointer<vtkConeSource> cone = vtkSmartPointer<vtkConeSource>::New();
cone->SetHeight(3.0);
cone->SetRadius(1.0);
cone->SetResolution(10);
//映射器
vtkSmartPointer<vtkPolyDataMapper> coneMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
coneMapper->SetInputConnection(cone->GetOutputPort());
//对象
vtkSmartPointer<vtkActor> coneActor = vtkSmartPointer<vtkActor>::New();
coneActor->SetMapper(coneMapper);
//渲染场景
vtkSmartPointer<vtkRenderer>renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(coneActor);
renderer->SetBackground(0.0, 1.0, 1.0);
//加入灯光
//**灯光1
vtkSmartPointer<vtkLight> light1 = vtkSmartPointer<vtkLight>::New();
light1->SetColor(0, 1, 0);//设置灯光颜色为绿色
light1->SetPosition(0, 0, 1);//设置灯光的位置
light1->SetFocalPoint(renderer->GetActiveCamera()->GetFocalPoint());//设置灯光的焦点
renderer->AddLight(light1);//将其添加到渲染场景中
//**灯光2
vtkSmartPointer<vtkLight>light2 = vtkSmartPointer<vtkLight>::New();
light2->SetColor(1, 0, 0);
light2->SetPosition(0, 0, -1);
light2->SetFocalPoint(renderer->GetActiveCamera()->GetFocalPoint());
renderer->AddLight(light2);
//相机
//**方法一
vtkSmartPointer<vtkCamera>camera = vtkSmartPointer<vtkCamera>::New();
camera->SetPosition(0,5,0);
camera->SetFocalPoint(0,0,0);
camera->SetViewUp(0,0,0.5);
renderer->SetActiveCamera(camera);
//**方法二
//renderer->GetActiveCamera()->SetPosition(0,5,0);
//renderer->GetActiveCamera()->SetFocalPoint(0, 0, 0);
//renderer->GetActiveCamera()->SetViewUp(0, 0, 0.5);
//renderer->ResetCamera();
//渲染窗口
vtkSmartPointer<vtkRenderWindow>renWin = vtkSmartPointer<vtkRenderWindow>::New();
renWin->AddRenderer(renderer);
renWin->SetSize(600, 400);
//交互
vtkSmartPointer<vtkRenderWindowInteractor>renderInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderInteractor->SetRenderWindow(renWin);
//交互风格
vtkSmartPointer<vtkInteractorStyleTrackballCamera>style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
renderInteractor->SetInteractorStyle(style);
renderInteractor->Initialize();
renderInteractor->Start();
return 0;
}
参考
《VTK图形图像开发进阶》
study VTK Together 一起学习VTK教程--水灵