一、灯光
剧场里有各式各样的灯光,三维渲染场景中也一样,可以有多个灯光存在。灯光和相机是三维渲染场景必备的要素,如果没有指定,vtkRenderer会自动创建默认的灯光和相机。VTK里用类vtkLight来表示渲染场景中的灯光。与现实中的灯光类似,VTK中的vtkLigth实例也可以打开、关闭,设置灯光的颜色,照射位置(焦点),灯光所在的位置、强度等。
vtkLigth可以分为位置灯光(Positional Ligth,也叫聚光灯)和方向灯光(Direction Ligth)。位置灯光时光源位置在渲染场景中的某个位置,可以指定灯光的衰减值、锥角等;方向灯光即光源位置在无穷远,可以认为光线是平行的,比如自然界中的太阳光。光源的位置和焦点的连线定义光线的方向,默认的vtkLigth为方向灯光。
vtkLigth的常用方法如下。
SetColor():设置灯光的颜色,以RGB的形式指定颜色。
SetPosition():设灯光照位置。
SetFocalPoint():设置灯光焦点。
SetIntensity():设置灯光的强度。
SetSwitch()/SwitchOn()/SwitchOff():打开或关闭对应的灯光。
vtkLigth里的方法SetSwitch()/GetSwitch()/SwitchOn()/SwitchOff()控制灯光的开或者关。不难发现,在VTK中属性的设置都是采取这一类方法,以vtkLigth为例,SwitchOn()与SetSwitch(1)实现的效果是一样的,而SwtichOff()则与SetSwitch(0)一样,GetSwitch()则是用于获取vtkLigth对象关闭或打开这个属性的值。如果某个类有提供SetXXX()方法,一般会提供相应的GetXXX()方法来获取该属性值。再如,vtkLigth还提供SetPositional()/GetPositional()/PositionalOn()/PositionalOff()这一类方法用来控制位置灯光的开关。
下述代码说明了灯光vtkLigth的使用方法。
#include <QtCore/QCoreApplication>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2)
#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 <vtkLight.h>
#include <vtkCamera.h>
#include <vtkProperty.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//cylinder:圆柱
vtkSmartPointer<vtkCylinderSource> cylinder = vtkSmartPointer<vtkCylinderSource>::New();
cylinder->SetHeight(3.0);
cylinder->SetRadius(1.0);
cylinder->SetResolution(10);
vtkSmartPointer<vtkPolyDataMapper> cylinderMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
vtkSmartPointer<vtkActor> cylinderActor = vtkSmartPointer<vtkActor>::New();
cylinderActor->SetMapper(cylinderMapper);
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(cylinderActor);
renderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
renWin->AddRenderer(renderer);
renWin->SetSize(640, 480);
renWin->Render();
renWin->SetWindowName("RenderCylinder-Lights");//设置窗口名字
vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin);
vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
iren->SetInteractorStyle(style);
vtkSmartPointer<vtkLight> myLight = vtkSmartPointer<vtkLight>::New();
myLight->SetColor(0, 1, 0); //绿
myLight->SetPosition(0, 0, 1); //Z轴正向
myLight->SetFocalPoint(renderer->GetActiveCamera()->GetFocalPoint());//焦点
renderer->AddLight(myLight);
vtkSmartPointer<vtkLight> myLight2 = vtkSmartPointer<vtkLight>::New();
myLight2->SetColor(0, 0, 1); //蓝
myLight2->SetPosition(0, 0, -1); //Z轴负向
myLight2->SetFocalPoint(renderer->GetActiveCamera()->GetFocalPoint());
renderer->AddLight(myLight2);
iren->Initialize();
iren->Start();
return a.exec();
}
运行结果如下:
分析:
灯光位置(0,0,1)——绿色灯光在前;灯光位置(0,0,-1)——蓝色灯光在后。
分析:
灯光位置(0,1,0)——绿色灯光在顶部;灯光位置(0,-1,0)——蓝色灯光在底部。
分析:
灯光位置(1,0,0)——绿色灯光在右边;灯光位置(-1,0,0)——蓝色灯光在左边。