1. 程式人生 > >VTK修煉之道7_三維場景基本要素:光照

VTK修煉之道7_三維場景基本要素:光照

1.VTK中的光照長得什麼樣?

劇場裡有各式各樣的燈光,三維渲染場景中也一樣,可以有多個光照存在。光照和相機是三維渲染場景必備的因素,如果沒有指定,vtkRenderer會自動地建立預設的光照和相機。VTK裡用類vtkLight來表示渲染場景中的光照。與現實中的燈光類似,VTK中的vtkLight例項也可以開啟、關閉,設定光照的顏色,照射位置(即焦點),光照所在的位置,強度等等。
vtkLight可以分為位置光照(Positional Light,即聚光燈)和方向光照(Direction Light)。位置光照是光源位置在渲染場景中的某個位置,可以指定光照的衰減值、錐角等;方向光照即光源位置在無窮遠,光線可以認為是平行的,比如自然界中的太陽光。光源的位置和焦點的連線定義光線的方向,預設的vtkLight即為方向光照。
vtkLight常的方法有:
SetColor() — 設定光照的顏色,以RGB的形式指定顏色。
SetPosition() — 設定光照位置。
SetFocalPoint() — 設定光照焦點。
SetIntensity() — 設定光照的強度。
SetSwitch() / SwitchOn()/ SwitchOff()— 開啟或關閉對應的光照。
vtkLight裡也有類似命名風格的方法:SetSwitch() /GetSwitch()/SwitchOn()/ SwitchOff()。不難發現,在VTK裡,某個屬性的設定都是採取這一類方法,以vtkLight為例,SwitchOn()跟SetSwitch(1)實現的效果是一樣,SwitchOff()則與SetSwitch(0)是一樣的,GetSwitch()則是用於獲取vtkLight物件關閉或開啟這個屬性的值。如果某個類有提供SetXXX()方法,一般也會提供GetXXX()方法來獲取相應的值,這個我們在前面的內容也已經有一些瞭解。再比如,vtkLight還提供:SetPositional() / GetPositional()/ PositionalOn()/PositionalOff()一類方法來設定位置光照。
在類vtkLight的標頭檔案vtkLight.h裡,找不到類似SetSwitch()/GetSwitch()等方法的原型,但是可以看到以下幾行:
vtkSetMacro(Switch,int);
vtkGetMacro(Switch,int);
vtkBooleanMacro(Switch,int);
顧名思義,vtkSetMacro/vtkGetMacro/vtkBooleanMacro都是巨集,展開這幾個巨集以後就是以上函式的原型。為了保證程式碼的整潔與複用性,VTK在檔案vtkSetGet.h裡定義了大量了巨集,當你找不到某個函式的原型時,可能這些函式就是由巨集展開以後所定義的,所以,在閱讀VTK原始碼的時候,不妨多右擊一下某個函式或者關鍵字,然後點選彈出選單中的“Go to Definition…”,也就一目瞭然了。

2.光照實驗

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
/////////////////////////////////////
#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()
{
	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, 0, 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,6);
	myLight->SetFocalPoint(
		renderer->GetActiveCamera()->GetFocalPoint());
	renderer->AddLight(myLight);

	vtkSmartPointer<vtkLight> myLight2 =
		vtkSmartPointer<vtkLight>::New();
	myLight2->SetColor(0,0,1);
	myLight2->SetPosition(0,0,-6);
	myLight2->SetFocalPoint(
		renderer->GetActiveCamera()->GetFocalPoint());
	renderer->AddLight(myLight2);

	iren->Initialize();
	iren->Start();

	return EXIT_SUCCESS;

}

3.執行結果

4.經驗總結

1.當我們設定舞臺上的光照引數時,要用到照相機Camera資訊以及屬性Property資訊。因此標頭檔案中不僅僅要包括#include<vtkLight.h>必須包括#include<vtkCamera.h>/#include<vtkProperty.h>。

2.我們設計的是燈光位置,通過一組實驗我們大概可以知曉vtk視窗內,XYZ軸的指向。

    

圖一:(-6,0,0)=藍光燈;(6,0,0)=綠光燈。  X軸

圖二:(0,-6,0)=藍光燈;(0,6,0)=綠光燈。  Y軸

圖三:(0,0,-6)=藍光燈;(0,0,6)=綠光燈。  Z軸