02-三维场景的基本要素(灯光)

一、灯光

剧场里有各式各样的灯光,三维渲染场景中也一样,可以有多个灯光存在。灯光和相机是三维渲染场景必备的要素,如果没有指定,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)——蓝色灯光在左边。

发布了40 篇原创文章 · 获赞 1 · 访问量 1781

猜你喜欢

转载自blog.csdn.net/piaoguo60/article/details/94413813