文章目录
- VTK中的光照
- 1. vtkLight 的两种类型:位置光照和方向光照
- 2. vtkLight 的常用方法
- 3. 方法命名风格
- 4. vtkProp 的可见性与 vtkLight 的开关
- 示例
VTK中的光照
vtkLight: 用于定义一个或多个光源。每个光源可以有其颜色、位置、焦点等属性。
vtkActor: 每个vtkActor对象(代表场景中的一个对象)都有自己的属性,包括材质属性(material properties),这些属性决定了该对象如何响应光。
vtkRenderer: 负责管理场景中的所有元素,包括光源和actor,并且控制着场景的最终渲染。
1. vtkLight 的两种类型:位置光照和方向光照
位置光照 (Positional Light): 也称为聚光灯(Spotlight)。 光源的位置在渲染场景中的某个具体点。 可以指定光源的衰减值、锥角等参数,模拟现实世界中的灯光效果。 示例:台灯、手电筒等。 方向光照 (Directional Light): 光源位于无穷远处,光线被认为是平行的。 常用于模拟自然界的太阳光。 默认情况下,vtkLight 是方向光照。
关键点: 光源的方向由其位置 (SetPosition) 和焦点 (SetFocalPoint)
的连线决定。如果光源是方向光照,则它的位置可以看作是无穷远,而方向由焦点决定。
2. vtkLight 的常用方法
以下是 vtkLight 提供的一些常用方法及其作用: (1) 设置光照颜色
SetColor(double r, double g, double b): 设置光源的颜色,使用 RGB 格式。 参数范围通常是 [0.0, 1.0]。 示例:light->SetColor(1.0, 0.0, 0.0); 将光源颜色设置为红色。
(2) 设置光源位置
SetPosition(double x, double y, double z): 设置光源的位置。 对于位置光照,这是光源的具体坐标。 对于方向光照,这是光源的方向向量。
(3) 设置焦点
SetFocalPoint(double x, double y, double z): 设置光源的焦点。 光源的方向是从光源位置指向焦点。
(4) 设置光照强度
SetIntensity(double intensity): 设置光源的强度,默认值为 1.0。 强度越高,光照越亮。
(5) 打开或关闭光源
SetSwitch(int onOff) / SwitchOn() / SwitchOff(): 控制光源的开关状态。 SetSwitch(1) 或 SwitchOn() 表示打开光源。 SetSwitch(0) 或 SwitchOff() 表示关闭光源。 GetSwitch() 返回当前光源的开关状态。
3. 方法命名风格
VTK 中的方法命名遵循一定的模式,便于理解和使用。以下是常见的命名风格:
SetXXX() 和 GetXXX(): SetXXX() 用于设置某个属性的值。 GetXXX() 用于获取某个属性的当前值。
示例
light->SetIntensity(2.0); // 设置光照强度为 2.0
double intensity = light->GetIntensity(); // 获取当前光照强度
XXXOn() 和 XXXOff():
XXXOn() 等价于 SetXXX(1),表示开启某个属性。 XXXOff() 等价于 SetXXX(0),表示关闭某个属性。
示例
light->SwitchOn(); // 打开光源
light->SwitchOff(); // 关闭光源
SetPositional() 和 GetPositional():
SetPositional(int) 用于设置光源是否为位置光照。 SetPositional(1) 表示启用位置光照。 SetPositional(0) 表示禁用位置光照(即使用方向光照)。 GetPositional() 返回当前光源是否为位置光照。
示例:
light->SetPositional(1); // 启用位置光照
bool isPositional = light->GetPositional(); // 检查是否为位置光照
4. vtkProp 的可见性与 vtkLight 的开关
在 VTK 中,类似的命名风格不仅适用于 vtkLight,还适用于其他类,例如 vtkProp(所有可视化对象的基类)。以下是一些类比:
vtkProp 的可见性控制: SetVisibility(int) / GetVisibility() / VisibilityOn() / VisibilityOff()。
示例:
actor->VisibilityOn(); // 显示对象
actor->VisibilityOff(); // 隐藏对象
vtkLight 的开关控制:
SetSwitch(int) / GetSwitch() / SwitchOn() / SwitchOff()。
示例:
light->SwitchOn(); // 打开光源
light->SwitchOff(); // 关闭光源
示例
#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCylinderSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkAutoInit.h>
#include <vtkSphereSource.h>
#include <vtkLineSource.h>
#include <vtkPlaneSource.h>
#include <vtkLight.h>
#include <vtkNamedColors.h>
using namespace std;
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
int main()
{
vtkNew<vtkNamedColors> colors;
// 创建球体数据源
vtkNew<vtkSphereSource> sphereSource;
sphereSource->SetCenter(0.0, 0.0, 0.0);
sphereSource->SetRadius(1.0);
// 映射器
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(sphereSource->GetOutputPort());
// 创建演员
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
actor->GetProperty()->SetColor(colors->GetColor3d("MistyRose").GetData());
// 渲染器
vtkNew<vtkRenderer> renderer;
renderer->AddActor(actor);
renderer->SetBackground(0.0, 1.0, 0.0);
// 添加光源
vtkNew<vtkLight> light;
light->SetPositional(1); // 设置为位置光照
light->SetPosition(1, 1, 1);
light->SetFocalPoint(0, 0, 0);
light->SetConeAngle(30);
light->SetDiffuseColor(colors->GetColor3d("White").GetData());
light->SetSpecularColor(colors->GetColor3d("White").GetData());
light->SetIntensity(2.0); // 设置光照强度
light->SwitchOn(); // 打开光源
//light->SwitchOff();
renderer->AddLight(light);
// 渲染窗口
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer);
renderWindow->SetSize(640, 480);
renderWindow->SetWindowName("LightingExample");
// 渲染窗口交互器
vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
renderWindowInteractor->SetRenderWindow(renderWindow);
// style风格
vtkNew<vtkInteractorStyleTrackballCamera> style;
renderWindowInteractor->SetInteractorStyle(style); // 修正:通过交互器设置样式
// 开始渲染
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}