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。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/925334.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C知道】数据包捕获(wire shark)

请解释一下数据包捕获和分析工具&#xff08;如Wireshark&#xff09;的工作原理和用途。 数据包捕获和分析工具&#xff0c;例如Wireshark&#xff08;以前称为 Ethereal&#xff09;&#xff0c;是一种网络协议分析软件&#xff0c;它允许用户实时监控计算机网络中的数据传输…

浮点数计算,不丢失精度

在js中对于浮点数直接计算会存在精度丢失的情况&#xff0c;为了保证精度问题&#xff0c;可以做如下处理&#xff1a; 浮点数精度计算 主要流程如下&#xff1a; 浮点数转换成整数 示例代码如下 /** 将一个浮点数转成整数&#xff0c;返回整数和倍数。如 3.14 >> 314…

计算机网络八股整理(三)

目录 计算机网络八股&#xff08;三&#xff09;传输层1&#xff1a;说一下tcp的头部&#xff1f;2&#xff1a;tcp三次握手的过程说一下&#xff1f;拓展linux中查看tcp状态&#xff1a; 3:tcp为什么需要三次握手建立连接&#xff1f;4&#xff1a;tcp三次握手&#xff0c;如果…

C#基础控制台程序

11.有一个54的矩阵&#xff0c;要求编程序求出其中值最大的那个元素的值&#xff0c;以及其所在的行号和列号。 12.从键盘输入一行字符&#xff0c;统计其中有多少个单词&#xff0c;单词之间用空格分隔开。 13.输入一个数&#xff0c;判断它是奇数还是偶数&#xff0c;如果…

小程序-基于java+SpringBoot+Vue的微信小程序养老院系统设计与实现

项目运行 1.运行环境&#xff1a;最好是java jdk 1.8&#xff0c;我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境&#xff1a;IDEA&#xff0c;Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境&#xff1a;Tomcat 7.x,8.x,9.x版本均可 4.硬件环境&#xff1a…

LeetCode—74. 搜索二维矩阵(中等)

仅供个人学习使用 题目描述&#xff1a; 给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。 每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true…

命令行使用ssh隧道连接远程mysql

本地电脑A 跳板机B 主机2.2.2.2 用户名 B ssh端口号22 登录密码bbb 远程mysql C 地址 3.3.3.3 端口号3306 用户名C 密码ccc A需要通过跳板机B才能访问C; navicat中配置ssh可以实现在A电脑上访问C 如何实现本地代码中访问C呢? # 假设本地使…

海康VsionMaster学习笔记(学习工具+思路)

一、前言 VisionMaster算法平台集成机器视觉多种算法组件&#xff0c;适用多种应用场景&#xff0c;可快速组合算法&#xff0c;实现对工件或被测物的查找测量与缺陷检测等。VM算法平台依托海康威视在图像领域多年的技术积淀&#xff0c;自带强大的视觉分析工具库&#xff0c;可…

⭐️ GitHub Star 数量前十的工作流项目

文章开始前&#xff0c;我们先做个小调查&#xff1a;在日常工作中&#xff0c;你会使用自动化工作流工具吗&#xff1f;&#x1f64b; 事实上&#xff0c;工作流工具已经变成了提升效率的关键。其实在此之前我们已经写过一篇博客&#xff0c;跟大家分享五个好用的工作流工具。…

视频汇聚平台Liveweb国标GB28181视频平台监控中心设计

在现代安防视频监控领域&#xff0c;Liveweb视频汇聚平台以其卓越的兼容性和灵活的拓展能力&#xff0c;为用户提供了一套全面的解决方案。该平台不仅能够实现视频的远程监控、录像、存储与回放等基础功能&#xff0c;还涵盖了视频转码、视频快照、告警、云台控制、语音对讲以及…

安装SQL Server 2022提示需要Microsoft .NET Framework 4.7.2 或更高版本

安装SQL Server 2022提示需要Microsoft .NET Framework 4.7.2 或更高版本。 原因是&#xff1a;当前操作系统版本为Windows Server 2016 Standard版本&#xff0c;其自带的Microsoft .NET Framework 版本为4.6太低&#xff0c;不满足要求。 根据报错的提示&#xff0c;点击链接…

重塑视频新语言,让每一帧都焕发新生——Video-Retalking,开启数字人沉浸式交流新纪元!

模型简介 Video-Retalking 模型是一种基于深度学习的视频再谈话技术&#xff0c;它通过分析视频中的音频和图像信息&#xff0c;实现视频角色口型、表情乃至肢体动作的精准控制与合成。这一技术的实现依赖于强大的技术架构和核心算法&#xff0c;特别是生成对抗网络&#xff0…

Llama-2-7b:vocab size:32000;embeddings:4096;hidden_layers是什么意思

目录 Llama-2-7b:vocab size:32000;embeddings:4096 vocab size:模型能解析词汇数量==n_vocab num_hidden_layers: 32 nanogpt隐藏层4 "initializer_range": 0.02 Token Embed是什么 举例说明 不同Chat版本的Token Embed(Token Embeddings) 区别 Llama…

Spring Boot【三】

自动注入 xml中可以在bean元素中通过autowire属性来设置自动注入的方式&#xff1a; <bean id"" class"" autowire"byType|byName|constructor|default" /> byName&#xff1a;按照名称进行注入 byType&#xff1a;按类型进行注入 constr…

mysql之基本常用的语法

mysql之基本常用的语法 1.增加数据2.删除数据3.更新/修改数据4.查询数据4.1.where子句4.2.order by4.3.limit与offset4.4.分组与having4.5.连接 5.创建表 1.增加数据 insert into 1.指定列插入 语法&#xff1a;insert into table_name(列名1,列名2,....,列名n) values (值1,值…

【模电】整流稳压电源

1.整流稳压电源 主要由四大部分组成&#xff0c;分别是&#xff1a; 1&#xff09;电源变压器 2&#xff09;整流电路 3&#xff09;滤波电路 4&#xff09;稳压电路 2.整流电路 2.1半波整流 2.1.1工作原理 平均电压计算 结构最简单&#xff0c;但是只利用了了半个周期的…

ATTCK红队评估实战靶场(二)

http://vulnstack.qiyuanxuetang.net/vuln/?page2 描述&#xff1a;红队实战系列&#xff0c;主要以真实企业环境为实例搭建一系列靶场&#xff0c;通过练习、视频教程、博客三位一体学习。本次红队环境主要Access Token利用、WMI利用、域漏洞利用SMB relay&#xff0c;EWS re…

gitee:删除仓库

1、点击主页面设置 2、找到左侧导航栏-数据管理->仓库空间信息&#xff1b;找到需要删除的仓库->点击设置 3、点击左侧仓库设置->点击右侧删除仓库 4、输入提示内容->确认删除 5、输入密码验证 6、成功删除提示

【JavaEE初阶 — 网络编程】TCP流套接字编程

TCP流套接字编程 1. TCP &#xff06; UDP 的区别 TCP 的核心特点是面向字节流&#xff0c;读写数据的基本单位是字节 byte 2 API介绍 2.1 ServerSocket 定义 ServerSocket 是创建 TCP 服务端 Socket 的API。 构造方法 方法签名 方法说明 ServerS…

Scala入门基础(20)数据集复习拓展

一.Stack栈二.Queue 队列 一.Stack栈 Stack:栈&#xff0c;特殊的结构。它对元素的操作是在头部&#xff1a;栈顶 先进后出的队列。pop表示取出&#xff0c;push表示在栈中添加元素 二.Queue 队列 Queue 队列;先进先出.enqueue入队&#xff0c;dequeue出队。