VTK的基本概念(一)
文章目录
- 三维场景的基本要素
- 1.灯光
- 2.相机
- 3.颜色
- 4.纹理映射
三维场景的基本要素
1.灯光
在三维渲染场景中,可以有多个灯光的存在,灯光和相机是三维渲染场景的必备要素,如果没有指定的话,vtkRenderer会自动创建默认的灯光和相机。在VTK里用类vtkLight来表示渲染场景中的灯光,与现实中的灯光类似,VTK中的vtkLight实例也可以打开、关闭,设置灯光的颜色,照射位置(焦点)、灯光所在的位置、强度等。
vtkLight可以分为位置灯光(也叫聚光灯)和方向灯光。
位置灯光:即光源位置在渲染场景中的某个位置,可以指定灯光的衰减值、锥角等;
方向灯光:即指光源位置在无穷远,可以认为光线是平行的,比如自然界中的太阳光。光源的位置和焦点的连线定义光线的方向。默认的vtkLight为方向灯光。
vtkLight提供了一系列方法来设置光源的位置、颜色、类型和强度等。以下是 vtkLight 的一些常用方法。
位置与方向:
SetPosition(double x, double y, double z):设置光源的位置。
GetPosition():获取光源的位置,返回一个三元组(x, y, z)。
SetFocalPoint(double x, double y, double z):设置光源的焦点位置,即光线指向的方向。
GetFocalPoint():获取光源的焦点位置。
颜色与亮度:
SetColor(double r, double g, double b):设置光源的颜色,参数为 RGB 值(范围 0-1)。
GetColor():获取光源的颜色,返回 RGB 三元组。
SetIntensity(double intensity):设置光源的亮度(强度),值范围通常为 0 到 1。
GetIntensity():获取光源的亮度(强度)值。
光源类型:
SetLightTypeToHeadlight():将光源类型设置为“头灯”,光源总是朝向相机,无论位置如何变化。
SetLightTypeToCameraLight():将光源类型设置为“相机光源”,光源位置与相机位置一致,随相机移动。
SetLightTypeToSceneLight():将光源类型设置为“场景光源”,光源位于场景中的固定位置。
GetLightType():获取当前光源的类型。
衰减:
SetAttenuationValues(double constant, double linear, double quadratic):设置光源的衰减系数,分别控制常数、线性和二次衰减因子。
GetAttenuationValues():获取光源的衰减系数。
开关控制:
SwitchOn() / SwitchOff():开启或关闭光源。
SetSwitch(bool on):直接设置光源是否开启,true 表示开启,false 表示关闭。
GetSwitch():获取光源的开关状态,返回布尔值。
阴影设置:
SetShadowAttenuation(double attenuation):设置光源阴影的衰减值,用于控制阴影的强度。
GetShadowAttenuation():获取阴影的衰减值。
其他常用方法:
DeepCopy(vtkLight *light):复制另一个光源的属性到当前光源。
SetConeAngle(double angle):设置聚光灯的角度,仅在聚光灯模式下生效。
SetExponent(double exponent):设置聚光灯的光强指数,指数越大,光照越集中。
以下是一个使用 vtkLight 的示例,展示了如何在 VTK 场景中创建和设置光源的属性。该示例创建了一个简单的场景,包括一个立方体和一个自定义光源,并演示如何设置光源的位置、颜色、类型等。
#include <vtkSmartPointer.h>
#include <vtkCubeSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkLight.h>QtVTKDemo::QtVTKDemo(QWidget *parent): QMainWindow(parent)
{ui.setupUi(this);this->setFixedSize(800, 600);QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat());// 创建渲染器、渲染窗口和交互器vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(renderer);// 创建一个立方体vtkSmartPointer<vtkCubeSource> cubeSource = vtkSmartPointer<vtkCubeSource>::New();// 创建映射器并连接立方体数据vtkSmartPointer<vtkPolyDataMapper> cubeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();cubeMapper->SetInputConnection(cubeSource->GetOutputPort());// 创建演员并设置映射器vtkSmartPointer<vtkActor> cubeActor = vtkSmartPointer<vtkActor>::New();cubeActor->SetMapper(cubeMapper);// 将立方体添加到渲染器中renderer->AddActor(cubeActor);// 创建光源vtkSmartPointer<vtkLight> light = vtkSmartPointer<vtkLight>::New();// 设置光源的位置、焦点、颜色和亮度light->SetPosition(1.0, 1.0, 1.0); // 设置光源位置light->SetFocalPoint(0.0, 0.0, 0.0); // 设置光源焦点,使光源指向立方体中心light->SetColor(1.0, 1.0, 1.0); // 设置光源颜色为白色light->SetIntensity(0.8); // 设置光源强度为0.8// 设置光源类型为场景光源(固定在场景中的位置,不随相机移动)light->SetLightTypeToSceneLight();// 将光源添加到渲染器renderer->AddLight(light);// 设置渲染器背景颜色renderer->SetBackground(0.1, 0.1, 0.1); // 深灰色背景// 开始渲染和交互ui.openGLWidget->setRenderWindow(renderWindow);
}
注意:因为Render里可以有多个灯光,所以VTK提供的接口是AddLight()而不是SetLight()。
2.相机
在VTK中,相机(vtkCamera)是一个用于控制三维场景中视角的对象,相机在VTK的3D渲染中扮演着重要的角色,因为它决定了观察者如何看待场景。相机的位置、朝向和投影方式可以通过vtkCamera类来控制。相机投影示意图如下所示:
从上图可以看出与相机投影相关的要素主要有以下几个:
相机位置:相机所处的位置,用vtkCamera::SetPosition()方法设置。
相机焦点:用vtkCamera::SetFocusPoint()方法设置,默认的焦点位置在世界坐标系的原点。
朝上方向:朝上方向即哪个方向为相机朝上的方向。就好比直立看东西,方向为头朝上,看到的东西也是直立的。如果倒立看东西,这时方向为头朝下,看到的东西就是倒立的。相机位置、相机焦点和朝上方向三个因素确定了相机的实际方向,即确定相机的视图。
投影方向:相机位置到相机焦点的向量方向即为投影方向。
投影方法:该要素用于确定Actor是如何映射到像平面的。vtkCamera定义了两种投影方法;一种是正交投影,也叫平行投影,即进入相机的光线与投影方向是平行的;另一种是透视投影,即所有光线相交于一点。该投影方法最符合人类眼睛对于景物所产生的近大远小的视觉习惯。
视角:透视投影时需要指定相机的视角(View Angle),默认的视角大小为30度,可以用vtkCamera::SetViewAngle()方法设置。
前后裁剪平面:裁剪平面与投影方向相交,一般与投影方向也是垂直的,裁剪平面主要用于评估Actor与相机距离的远近,只有在前后裁剪平面之间的Actor才是可见的。裁剪平面的位置可以用vtkCamera:SetClippingRange()方法设置。
以下是一个使用 vtkCamera的示例
#include <vtkSmartPointer.h>
#include <vtkCubeSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkLight.h>
#include <vtkCamera.h>QtVTKDemo::QtVTKDemo(QWidget *parent): QMainWindow(parent)
{ui.setupUi(this);this->setFixedSize(800, 600);QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat());// 创建渲染器、渲染窗口和交互器vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();// 创建并设置相机vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();camera->SetPosition(10, 10, 10); // 设置摄像机的位置坐标。默认位置是 (0, 0, 1)。camera->SetFocalPoint(0, 0, 0); // 设置摄像机的焦点,即摄像机所看的目标点位置。camera->SetViewAngle(40); // 设置视角(视场角),角度以度数表示,通常在30到45度之间。视角决定了摄像机的视野范围。camera->SetClippingRange(0.1, 1000); // 设置近裁剪平面和远裁剪平面。该函数控制显示的最近和最远距离。(设置裁剪平面范围为 0.1 到 1000)camera->SetViewUp(0, 1, 0); // 设置视上方向,通常用于控制摄像机的“上”方向。(设置摄像机上方向为 (0, 1, 0))renderer->SetActiveCamera(camera);vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(renderer);// 创建一个立方体vtkSmartPointer<vtkCubeSource> cubeSource = vtkSmartPointer<vtkCubeSource>::New();// 创建映射器并连接立方体数据vtkSmartPointer<vtkPolyDataMapper> cubeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();cubeMapper->SetInputConnection(cubeSource->GetOutputPort());// 创建演员并设置映射器vtkSmartPointer<vtkActor> cubeActor = vtkSmartPointer<vtkActor>::New();cubeActor->SetMapper(cubeMapper);// 将立方体添加到渲染器中renderer->AddActor(cubeActor);// 创建光源vtkSmartPointer<vtkLight> light = vtkSmartPointer<vtkLight>::New();// 设置光源的位置、焦点、颜色和亮度light->SetPosition(1.0, 1.0, 1.0); // 设置光源位置light->SetFocalPoint(0.0, 0.0, 0.0); // 设置光源焦点,使光源指向立方体中心light->SetColor(1.0, 1.0, 1.0); // 设置光源颜色为白色light->SetIntensity(0.8); // 设置光源强度为0.8// 设置光源类型为场景光源(固定在场景中的位置,不随相机移动)light->SetLightTypeToSceneLight();// 将光源添加到渲染器renderer->AddLight(light);// 设置渲染器背景颜色renderer->SetBackground(0.1, 0.1, 0.1); // 深灰色背景renderWindow->SetSize(600, 600); // 设置渲染窗口大小// 开始渲染和交互ui.openGLWidget->setRenderWindow(renderWindow);
}
另外vtkCamera 类中的 Dolly()、Roll()、Azimuth()、Yaw()、Elevation()、Pitch() 和 Zoom() 函数提供了丰富的摄像机视角调整选项,允许你通过不同的方式调整摄像机的位置、旋转角度和缩放比例。
vtkCamera运动方向示意图
Dolly(double value): 用于沿视线方向拉近或拉远视图,值大于1会拉近,小于1会拉远。Dolly() 影响摄像机和焦点的相对距离,改变场景的纵深感。
Roll(double angle):沿摄像机视线方向旋转摄像机,使画面有“滚动”效果。通常用于模拟摄像机在视线方向上的滚动旋转。
Azimuth(double angle):绕摄像机的垂直轴(Y轴)旋转视角,相当于左右旋转视图。用于改变水平方向的视角。
Yaw(double angle):Yaw() 和 Azimuth() 类似,都是绕 Y 轴旋转,但它直接影响摄像机的方向而不是整个视图。通常用于改变摄像机的指向。
Elevation(double angle):绕 X 轴旋转摄像机视角,改变垂直方向的视角,类似于仰视或俯视场景。
Pitch(double angle):Pitch() 和 Elevation() 类似,绕 X 轴旋转摄像机,但直接影响摄像机的指向而非视图。
Zoom(double factor):用于缩放视图,影响摄像机的视角大小。factor 值大于1会放大,小于1会缩小。
以下示例展示如何结合使用这些函数来调整摄像机的视角
vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
camera->SetPosition(0, 0, 10); // 设置摄像机位置
camera->SetFocalPoint(0, 0, 0); // 设置摄像机焦点camera->Dolly(1.2); // 拉近视图
camera->Roll(45); // 视线滚动45度
camera->Azimuth(30); // 水平旋转30度
camera->Yaw(20); // 绕Y轴旋转20度
camera->Elevation(15); // 垂直旋转15度
camera->Pitch(10); // 绕X轴旋转10度
camera->Zoom(1.5); // 放大视图1.5倍
从上述可以看出,Dolly 和 Zoom 都用于拉近或拉远视图,但 Dolly 更适合产生真实的深度感;Roll 适合调整画面旋转感(滚动);Azimuth 和 Elevation 改变视角的水平方向和垂直方向,Yaw 和 Pitch 改变摄像机的方向而不影响场景整体视图。
3.颜色
颜色是Actor重要的属性之一。VTK采用RGB和HSV两种颜色系统来描述颜色。
RGB颜色系统由三个颜色分量:红色(R)、绿色(G)、和蓝色(B)的组合表示,在VTK里,这三个分量的取值范围都是0~1,(0, 0, 0)表示黑色,(1, 1, 1)表示白色。vtkProperty::SetColor(r, g, b)采用的就是RGB颜色系统设置颜色属性值。
HSV颜色系统同样也是由三个分量来决定颜色,它们分别是:色相(Hue),表示颜色的基本属性,就是通常所说的颜色名称,如红色、黄色;饱和度,是指颜色的纯度,其值越高则越纯;值(Value,也就是强度Intensity或者亮度Bright),值为0通常表示的是黑色,值为1表示的是最亮的颜色。这三个分量的取值范围0~1。类vtkLookupTable提供了HSV颜色系统设置的方法。
(1).设置颜色属性
可以直接在渲染的对象上设置颜色属性,包括:
Actor的颜色设置:通过actor->GetProperty()->SetColor()来设置一个对象的颜色。
边界颜色和透明度:使用SetEdgeColor()和SetOpacity()等方法对渲染物体的边界颜色和透明度进行控制。
环境光、漫反射和镜面反射颜色:通过SetAmbientColor()、SetDiffuseColor()、SetSpecularColor()等方法来设置材质的反射特性。
以下是一个简单的VTK示例,用于演示颜色属性设置,包括颜色、边界颜色、透明度、环境光、漫反射和镜面反射等:
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkSphereSource.h>
#include <vtkProperty.h>QtVTKDemo::QtVTKDemo(QWidget *parent): QMainWindow(parent)
{ui.setupUi(this);this->setFixedSize(800, 600);QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat());// 创建渲染器、渲染窗口和交互器vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(renderer);// 创建一个球体数据源vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();sphereSource->SetRadius(5.0);// 将球体数据映射到几何数据vtkSmartPointer<vtkPolyDataMapper> sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();sphereMapper->SetInputConnection(sphereSource->GetOutputPort());// 创建演员并设置映射器vtkSmartPointer<vtkActor> sphereActor = vtkSmartPointer<vtkActor>::New();sphereActor->SetMapper(sphereMapper);// 设置颜色属性sphereActor->GetProperty()->SetColor(0.1, 0.6, 0.8); // 设置球体颜色(RGB: 浅蓝色)sphereActor->GetProperty()->SetEdgeColor(0.0, 0.0, 0.0); // 设置边界颜色(黑色)sphereActor->GetProperty()->EdgeVisibilityOn(); // 开启边界显示sphereActor->GetProperty()->SetOpacity(0.7); // 设置透明度(0.0 = 全透明,1.0 = 不透明)sphereActor->GetProperty()->SetAmbientColor(0.2, 0.2, 0.2); // 设置环境光颜色sphereActor->GetProperty()->SetDiffuseColor(0.1, 0.6, 0.8); // 设置漫反射颜色sphereActor->GetProperty()->SetSpecularColor(1.0, 1.0, 1.0); // 设置镜面反射颜色(白色)sphereActor->GetProperty()->SetSpecular(0.5); // 镜面反射强度sphereActor->GetProperty()->SetSpecularPower(30.0); // 镜面反射的光泽度// 将立方体添加到渲染器中renderer->AddActor(sphereActor);// 设置渲染器背景颜色renderer->SetBackground(0.1, 0.1, 0.1); // 深灰色背景renderWindow->SetSize(600, 600); // 设置渲染窗口大小// 开始渲染和交互ui.openGLWidget->setRenderWindow(renderWindow);
}
(2).设置颜色映射
在VTK中,颜色映射是将标量数据映射到颜色的一种方式,常用于对科学数据的可视化。颜色映射可以使用vtkLookupTable或者vtkColorTransferFunction来实现。
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkSphereSource.h>
#include <vtkProperty.h>
#include <vtkFloatArray.h>
#include <vtkLookupTable.h>
#include <vtkPointData.h>QtVTKDemo::QtVTKDemo(QWidget *parent): QMainWindow(parent)
{ui.setupUi(this);this->setFixedSize(800, 600);QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat());// 创建渲染器、渲染窗口和交互器vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(renderer);// 创建一个球体数据源vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();/*作用:设置球体在水平(绕Z轴)方向的分段数量。参数:传入一个整数值,表示沿着球体赤道平分的分段数量。影响:增大 ThetaResolution 值会使球体在水平方向上更光滑细腻,但会增加计算量和渲染时间。*/sphereSource->SetThetaResolution(30); // 会将球体的水平方向分成 30 个分段。/*作用:设置球体在垂直方向的分段数量,从南极到北极。参数:传入一个整数值,表示沿着球体从底到顶(南极到北极)平分的分段数量。影响:增大 PhiResolution 值会使球体在垂直方向上更加平滑,同样会增加计算和渲染成本。*/sphereSource->SetPhiResolution(30); // 会将球体的垂直方向分成 30 个分段。/*低分辨率:SetThetaResolution(10) 和 SetPhiResolution(10) 将创建一个较粗糙的球体,因为分段少。高分辨率:SetThetaResolution(50) 和 SetPhiResolution(50) 会生成一个非常光滑的球体,但计算量和渲染成本也会增加。SetThetaResolution 和 SetPhiResolution 的值越大,球体的外观越平滑,细节越丰富,但会带来更高的计算开销。*/sphereSource->Update();// 创建一个标量数据数组,将标量数据与球体的顶点关联vtkSmartPointer<vtkFloatArray> scalars = vtkSmartPointer<vtkFloatArray>::New();for (vtkIdType i = 0; i < sphereSource->GetOutput()->GetNumberOfPoints(); ++i){scalars->InsertNextValue(static_cast<float>(i % 100) / 100.0); // 模拟生成标量数据}sphereSource->GetOutput()->GetPointData()->SetScalars(scalars);// 创建颜色映射表(Lookup Table)vtkSmartPointer<vtkLookupTable> lookupTable = vtkSmartPointer<vtkLookupTable>::New();lookupTable->SetNumberOfTableValues(256); // 设置颜色表的大小lookupTable->SetRange(0.0, 1.0); // 标量值的范围lookupTable->Build();// 设置颜色映射的渐变(如从蓝色到红色)for (int i = 0; i < 256; ++i) {double r = static_cast<double>(i) / 255.0;double b = 1.0 - r;lookupTable->SetTableValue(i, r, 0.0, b); // 渐变从蓝色到红色}// 将球体数据映射到几何数据vtkSmartPointer<vtkPolyDataMapper> sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();sphereMapper->SetInputConnection(sphereSource->GetOutputPort());sphereMapper->SetLookupTable(lookupTable); // 设置映射表sphereMapper->SetScalarRange(0.0, 1.0); // 设置标量数据的范围,映射到颜色表// 创建演员并设置映射器vtkSmartPointer<vtkActor> sphereActor = vtkSmartPointer<vtkActor>::New();sphereActor->SetMapper(sphereMapper);// 设置颜色属性sphereActor->GetProperty()->SetColor(0.1, 0.6, 0.8); // 设置球体颜色(RGB: 浅蓝色)sphereActor->GetProperty()->SetEdgeColor(0.0, 0.0, 0.0); // 设置边界颜色(黑色)sphereActor->GetProperty()->EdgeVisibilityOn(); // 开启边界显示sphereActor->GetProperty()->SetOpacity(0.7); // 设置透明度(0.0 = 全透明,1.0 = 不透明)sphereActor->GetProperty()->SetAmbientColor(0.2, 0.2, 0.2); // 设置环境光颜色sphereActor->GetProperty()->SetDiffuseColor(0.1, 0.6, 0.8); // 设置漫反射颜色sphereActor->GetProperty()->SetSpecularColor(1.0, 1.0, 1.0); // 设置镜面反射颜色(白色)sphereActor->GetProperty()->SetSpecular(0.5); // 镜面反射强度sphereActor->GetProperty()->SetSpecularPower(30.0); // 镜面反射的光泽度// 将立方体添加到渲染器中renderer->AddActor(sphereActor);// 设置渲染器背景颜色renderer->SetBackground(0.1, 0.1, 0.1); // 深灰色背景renderWindow->SetSize(600, 600); // 设置渲染窗口大小// 开始渲染和交互ui.openGLWidget->setRenderWindow(renderWindow);
}
上述代码中创建了一个vtkFloatArray并为球体的每个顶点设置了一个标量值。这里是模拟数据,将每个顶点的标量值设置为i % 100 / 100.0。vtkLookupTable:创建了一个颜色映射表,并为其设置范围为0.0到1.0。然后通过一个循环为颜色表中的每个值设置一个渐变颜色,从蓝色到红色。将颜色表设置到vtkPolyDataMapper的映射器上,并使用SetScalarRange方法来指定标量数据的范围,使其映射到颜色表中。最后创建渲染窗口和交互器,将颜色映射应用到的球体显示在窗口中。
在计算机图形学中,RGB颜色模型用于表示颜色,其中 R(红)、G(绿)、B(蓝) 三个通道的组合决定最终的颜色。
RGB每个通道的取值范围为:
0 到 255:通常用于8位色深的颜色表示(即0-255范围的整数)。这个范围是最常见的 RGB 表示法,适用于图像处理、计算机显示器、网页设计等。
0.0 到 1.0:用于归一化的浮点表示法(即0.0-1.0的浮点数)。在计算机图形学和许多绘图库(例如 OpenGL、VTK)中常用这种表示法。0.0表示最小强度(无光),1.0表示最大强度(全亮)。
通过不同强度的 RGB 值组合可以生成不同的颜色。例如:
(255, 0, 0) 或 (1.0, 0.0, 0.0):纯红色
(0, 255, 0) 或 (0.0, 1.0, 0.0):纯绿色
(0, 0, 255) 或 (0.0, 0.0, 1.0):纯蓝色
(255, 255, 255) 或 (1.0, 1.0, 1.0):白色(所有通道全亮)
(0, 0, 0) 或 (0.0, 0.0, 0.0):黑色(所有通道关闭)
在编程中,可以方便地将0-255范围的 RGB 值转换为0.0-1.0的归一化形式。例如:
double normalizedR = r / 255.0;
double normalizedG = g / 255.0;
double normalizedB = b / 255.0;
4.纹理映射
纹理映射是创建逼真效果的强大的图形工具,它的原理是渲染时把二维的图像贴到物体的表面上,根据二维图像渲染出丰富多彩的效果,所以叫纹理贴图。纹理映射需要三个要素:待贴图的表面、纹理映射以及纹理坐标。其中纹理映射在VTK中就是vtkImageData的数据集,而纹理坐标则用于控制纹理图在表面的位置。
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkPNGReader.h>
#include <vtkTexture.h>QtVTKDemo::QtVTKDemo(QWidget *parent): QMainWindow(parent)
{ui.setupUi(this);this->setFixedSize(800, 600);QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat());// 创建渲染器、渲染窗口和交互器vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(renderer);// 创建球体数据源vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();sphereSource->SetThetaResolution(30);sphereSource->SetPhiResolution(30);sphereSource->Update();// 加载纹理图像vtkSmartPointer<vtkPNGReader> pngReader = vtkSmartPointer<vtkPNGReader>::New();pngReader->SetFileName("VTKDemo.png");vtkSmartPointer<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New();texture->SetInputConnection(pngReader->GetOutputPort());// 创建映射器并连接立方体数据vtkSmartPointer<vtkPolyDataMapper> sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();sphereMapper->SetInputConnection(sphereSource->GetOutputPort());// 创建演员并设置映射器vtkSmartPointer<vtkActor> sphereeActor = vtkSmartPointer<vtkActor>::New();sphereeActor->SetMapper(sphereMapper);sphereeActor->SetTexture(texture);// 将立方体添加到渲染器中renderer->AddActor(sphereeActor);// 设置渲染器背景颜色renderer->SetBackground(0.1, 0.1, 0.1); // 深灰色背景// 开始渲染和交互ui.openGLWidget->setRenderWindow(renderWindow);
}
针对不同的图像格式,VTK 提供了不同的读取类:
JPEG 文件:使用 vtkJPEGReader。
PNG 文件:使用 vtkPNGReader。
TIFF 文件:使用 vtkTIFFReader。
相关文章:

VTK的基本概念(一)
文章目录 三维场景的基本要素1.灯光2.相机3.颜色4.纹理映射 三维场景的基本要素 1.灯光 在三维渲染场景中,可以有多个灯光的存在,灯光和相机是三维渲染场景的必备要素,如果没有指定的话,vtkRenderer会自动创建默认的灯光和相机。…...

error LNK2001: 无法解析的外部符号 memcpy strcmp strlen
0>LIBMY_static.lib(pixdesc.obj) : error LNK2001: 无法解析的外部符号 __imp_abort 10>LIBMY_static.lib(random_seed.obj) : error LNK2001: 无法解析的外部符号 __imp_abort 10>postprocess.obj : error LNK2001: 无法解析的外部符号 __imp_abort 10>LIBMY_sta…...

打造智能扩容新纪元:Kubernetes Custom Metrics深度解析
自定义指标:Kubernetes Auto Scaling的革命 1. 引言 1.1 Kubernetes与Auto Scaling Kubernetes作为当今容器编排的事实标准,提供了强大的自动化能力,其中Auto Scaling(自动扩缩容)是其核心特性之一。Auto Scaling允许Kubernetes集群根据当前负载动态调整资源,以应对不…...

【K8s】专题十五(4):Kubernetes 网络之 Calico 插件安装、切换网络模式、卸载
本文内容均来自个人笔记并重新梳理,如有错误欢迎指正! 如果对您有帮助,烦请点赞、关注、转发、订阅专栏! 专栏订阅入口 | 精选文章 | Kubernetes | Docker | Linux | 羊毛资源 | 工具推荐 | 往期精彩文章 【Docker】(全…...

Unity类银河战士恶魔城学习总结(P141 Finalising ToolTip优化UI显示)
【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/ UI部分暂时完结!!! 本章节优化了UI中物品描述的显示效果,技能描述的显示效果 并且可以批…...

c++(入门)
1. 引用 引用的定义 引用是另一个变量的别名,它在声明时必须被初始化,并且一旦初始化后,它就始终引用那个变量。 引用的语法 引用的声明方式是在变量名前加上&符号。 引用的特点 引用必须在声明时初始化。引用一旦初始化后&#x…...

【优选算法】前缀和
目录 一、[【模板】前缀和](https://www.nowcoder.com/practice/acead2f4c28c401889915da98ecdc6bf?tpId230&tqId2021480&ru/exam/oj&qru/ta/dynamic-programming/question-ranking&sourceUrl%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E7%25AE%2597%25E6%25B3%2595…...

Spring Bean 的生命周期详解
所谓万物皆对象,对于一个 bean 而言,从出生到死亡,他要经历哪些阶段呢? 生命周期 理解对象的生命周期,可以帮助我们更好的做一些扩展。 一个对象从被创建到被垃圾回收,可以大致分为这 5 个阶段:…...

MySQL【知识改变命运】12
视图 1:什么是视图2:创建视图使用视图(视图的好处)2.1.隐藏敏感字段2.2.对外提供统一访问3:视图和真实表进⾏表连接查询 4:修改视图数据4.1:通过真实表修改数据,会影响视图4.2&#…...

shell编程(完整版)
目录 一、shell脚本解释器 二、shell脚本的执行 三、变量的使用 四、永久环境变量 按用户设置永久环境变量 文件路径: 示例步骤: 删除永久环境变量 五、脚本程序传递参数怎么实现 六、用编程进行数学运算 shell中利用expr进行运算 运算与变量…...

数字逻辑(一)——导论
1.导论 1.1什么是数字逻辑? 数字逻辑是指在数字电路设计、计算机科学领域中对于离散的二进制信号进行逻辑处理、运算、存储和传输的基本原理和方法。 1.2数字量和模拟量的区别 数字量:在时间上和数量上都是离散的、不连续的物理量。模拟量࿱…...

量化交易系统开发-实时行情自动化交易-4.4.做市策略
19年创业做过一年的量化交易但没有成功,作为交易系统的开发人员积累了一些经验,最近想重新研究交易系统,一边整理一边写出来一些思考供大家参考,也希望跟做量化的朋友有更多的交流和合作。 接下来继续说说做市策略原理。 做市策…...

《线性代数的本质》
之前收藏的一门课,刚好期末复习,顺便看一看哈哈 课程链接:【线性代数的本质】合集-转载于3Blue1Brown官方双语】 向量究竟是什么 线性代数中最基础、最根源的组成部分就是向量,需要先明白什么是向量 不同专业对向量的看法 物理专…...

Gbase8s 允许内置用户创建用户以及创建只读权限用户以及利用角色管理普通用户权限
Gbase8s 允许内置用户创建用户以及创建只读权限用户以及利用角色管理普通用户权限 普通安装实例创建数据库以后,DBA权限只有gbasedbt用户。gbasdbt可以创建普通用户,并且给普通用户赋予库及权限或者表级权限。 但是gbasedbt用户口令和操作系统相关,所以想在不提供gbasedbt的…...

24/11/25 视觉笔记 深度传感器和手势识别
本章的目的是开发一个应用程序,使用深度传感器的输出实时检测和跟踪简单的手势。该应用程序将分析每个已捕捉的帧。并执行以下任务。 手部区域分割:通过分析Kinect传感器的深度图输出,在每一帧中提取用户的手部区域,这是通过阈值…...

迄今为止的排序算法总结
迄今为止的排序算法总结 7.10 迄今为止的排序算法总结复杂度和稳定性时间复杂度测试程序sortAlgorithm.hsortAlgorithm.cpptest.cpp 时间复杂度测试结果 7.10 迄今为止的排序算法总结 复杂度和稳定性 排序算法平均情况最好情况最坏情况稳定性空间复杂度选择排序O(n^2)O(n^2)O…...

HTML和CSS 表单、表格练习
HTML和CSS 表格练习 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>HTML表格练习</title>…...

H5流媒体播放器EasyPlayer.js网页直播/点播播放器如果H.265视频在播放器上播放不流畅,可以考虑的解决方案
随着流媒体技术的迅速发展,H5流媒体播放器已成为现代网络视频播放的重要工具。其中,EasyPlayer.js网页直播/点播播放器作为一款功能强大的H5播放器,凭借其全面的协议支持、多种解码方式以及跨平台兼容性,赢得了广泛的关注和应用。…...

Http 转 https 中 Nginx 的详细配置过程
摘要 本节将简要介绍从 HTTP 到 HTTPS 的配置过程,并完整展示 Nginx 的相关配置信息。 经过两天断断续续的调试,终于将 http 变成 https 了。现在说说这个安装 ssl 证书的过程。 服务器是在某云上。这个过程大致分为三个步骤:申请 ssl 证书、…...

【测试工具JMeter篇】JMeter性能测试入门级教程(二)出炉,测试君请各位收藏了!!!
上篇文章:CSDN 我们介绍了JMeter的一些原理介绍,以及安装配置和启动流程,本文我们就来讲讲JMeter如何使用。 一、JMeter目录结构组成 1. 根目录 Jmeter安装包解压后的根目录如下图: 1.1 backups目录:脚本备份目录&am…...

Otter 安装流程
优质博文:IT-BLOG-CN 一、背景 随着公司的发展,订单库的数据目前已达到千万级别,需要进行分表分库,就需要对数据进行迁移,我们使用了otter,这里简单整理下,otter 的安装过程,希望对…...

一文学会Golang里拼接字符串的6种方式(性能对比)
g o l a n g golang golang的 s t r i n g string string类型是不可修改的,对于拼接字符串来说,本质上还是创建一个新的对象将数据放进去。主要有以下几种拼接方式 拼接方式介绍 1.使用 s t r i n g string string自带的运算符 ans ans s2. 使用…...

【笔记】Linux下编译Python3.10.15为动态库同时正确处理OpenSSL3依赖
之前自己第一次编译Python后发现pip会提示无法使用SSL,后来了解到是自己编译时没有配置OpenSSL。这个过程有点曲折,里面有一个坑,怕忘记于是写博客记录一下。 首先是下载OpenSSL,Python3.10.15支持此时最新版的OpenSSL 3.4.0&…...

Go语言获取客户端真实IP
在一些需求中,服务器需要记录客户端的ip地址,要获取ip地址,则需要有http.Request的对象参数传入,以下代码直接放在util中使用。 文件名:ip_utils.go package utilsimport ("context""github.com/spf1…...

大模型论文速递(11.23-11.25)
BlueLM-V3B 关键词:动态分辨率,图像放大,适应性网格化方法 研究问题:如何改进现有的动态分辨率匹配方法以减少在模型训练和部署中的计算复杂度? 方法: 分析现有动态分辨率匹配算法(如LLaVA-…...

维护在线重做日志(二)
迁移和重命名 可以使用操作系统命令重新定位重做日志,然后使用ALTER DATABASE语句使数据库知道它们的新名称(位置)。这个过程是必要的,例如,如果当前用于一些重做日志文件的磁盘将被删除,或者如果数据文件…...

.net core MVC入门(一)
文章目录 项目地址一、环境配置1.1 安装EF core需要包1.2 配置数据库连接二、使用EF创建表2.1 整体流程梳理2.1 建表详细流程三、添加第一个视图3.1整体流程梳理3.1 添加视图,并显示在web里四、使用EF增加Catogory数据,并且读取数据到页面4.1整体流程梳理4.2 实现五、增加Cat…...

802.11协议
802.11协议是由美国电气和电子工程师协会(IEEE)制定的无线局域网(WLAN)标准。以下是关于802.11协议的详细介绍: 一、定义与背景 定义:IEEE802.11是美国电机电子工程师协会(IEEE)为…...

【Linux】线程ID与互斥、同步(锁、条件变量)
作者主页: 作者主页 本篇博客专栏:Linux 创作时间 :2024年11月24日 线程ID及进程地址空间布局 先看一下这段代码: 运行一下: 运行这个代码之后,我们看到的这个很大的数字就是线程id,然后…...

Android 13 编译Android Studio版本的Launcher3
Android 13 Aosp源码 源码版本 Android Studio版本 Launcher3QuickStepLib (主要代码) Launcher3ResLib(主要资源) Launcher3IconLoaderLib(图片加载,冲突资源单独新建) 需要值得注意的是: SystemUISharedLib.jar 有kotlin和java下的,在 Lau…...