VTK004_vtk-灯光

VTK灯光:

灯光介绍:

      在生活中,我们能看见东西是因为有光照,光照分为很多类型,不同的光照会导致我们看见事物(看见的影像)也不同。同样的,光照是3D渲染中必备的因数之一(相机、事物也是)。

      VTK中的灯光与现实的灯光类似,在生活中,光源形式千变万化,例如太阳光,可以看成是一个平行光源,手电筒可以看成聚光(锥形光),普通灯泡可以看成点光源。在vtk中,光源为vtkLight,常用的有位置光源和方向光源:

      (1)位置光源:位置光源是处于某个位置的光源,可以指定其空间坐标、光照颜色、光照衰减值、锥形角等。

      (2)方向光源:方向光源不需要指定光源位置,光源处于无穷远,类似与太阳光(平行光)

      vtkLight默认为方向光照(平行光),光源的位置和照射焦点连线即为光照方向

示例:

class vtkMyCallback : public vtkCommand
{
public:
	static vtkMyCallback *New()
	{
		return new vtkMyCallback;
	}
	virtual void Execute(vtkObject *caller, unsigned long, void*) // 强制实现的方法
	{
		vtkRenderer *ren = reinterpret_cast<vtkRenderer*>(caller);
		cout << ren->GetActiveCamera()->GetPosition()[0] << " "
			<< ren->GetActiveCamera()->GetPosition()[1] << " "
			<< ren->GetActiveCamera()->GetPosition()[2] << "\n";
	}
};

int main()
{
	vtkSmartPointer<vtkRenderWindow> m_pRenderWin = vtkRenderWindow::New();
	vtkSmartPointer<vtkRenderWindowInteractor> m_pInteractor = vtkRenderWindowInteractor::New();
	vtkSmartPointer<vtkInteractorStyleTrackballCamera> m_pInteractorStyle = vtkInteractorStyleTrackballCamera::New();
	vtkSmartPointer<vtkActor> m_actor = vtkActor::New();
	vtkSmartPointer<vtkRenderer> m_render = vtkRenderer::New();
	vtkSmartPointer<vtkCylinderSource> m_cylinderSrc = vtkCylinderSource::New();
	vtkSmartPointer<vtkPolyDataMapper> m_cylinderMap = vtkPolyDataMapper::New();
	vtkSmartPointer<vtkTransform> m_trans = vtkTransform::New();
	vtkSmartPointer<vtkCamera> m_pCamera = vtkCamera::New();
	vtkSmartPointer<vtkLight> m_lightRed = vtkLight::New();
	vtkSmartPointer<vtkLight> m_lightGreen = vtkLight::New();
	vtkSmartPointer<vtkLight> m_lightBlue = vtkLight::New();

	m_cylinderSrc->SetHeight(10);
	m_cylinderSrc->SetRadius(5);
	m_cylinderSrc->SetResolution(36);	// 精度
	m_cylinderMap->SetInputConnection(m_cylinderSrc->GetOutputPort());
	//m_trans->Translate(0, 0, 0);
	m_trans->RotateX(45);		// 沿x轴正方向顺时针旋转

	m_actor->SetMapper(m_cylinderMap);
	m_actor->SetUserTransform(m_trans);
	m_actor->GetProperty()->SetDiffuse(0.6);        // 漫反射
	m_actor->GetProperty()->SetSpecular(0.3);        // 镜面反射
	m_actor->GetProperty()->SetSpecularPower(20);
//	m_actor->VisibilityOff();                        // 隐藏模型
	m_render->AddActor(m_actor);

	m_pCamera->SetPosition(0, 0, 50);
	m_pCamera->SetFocalPoint(0, 0, 0);
	m_render->SetActiveCamera(m_pCamera);

	m_render->SetViewport(0.0, 0.0, 1.0, 1.0);
	vtkMyCallback* mol = vtkMyCallback::New();
	m_render->AddObserver(vtkCommand::StartEvent, mol);	// 为渲染器添加观察器(回调函数)
	mol->Delete();
	m_lightRed->SetColor(1.0, 0.0, 0.0);
	m_lightRed->SetPosition(20, 0, 0);
	m_lightRed->SetFocalPoint(m_pCamera->GetFocalPoint());	// 光线照向相机聚焦点
	m_lightGreen->SetColor(0.0, 1.0, 0.0);
	m_lightGreen->SetPosition(0, 20, 0);
	m_lightGreen->SetFocalPoint(m_pCamera->GetFocalPoint());	// 光线照向相机聚焦点
	m_lightBlue->SetColor(0.0, 0.0, 1.0);
	m_lightBlue->SetPosition(0, 0, 20);
	m_lightBlue->SetFocalPoint(m_pCamera->GetFocalPoint());	// 光线照向相机聚焦点
	m_render->AddLight(m_lightRed);
	m_render->AddLight(m_lightGreen);
	m_render->AddLight(m_lightBlue);
	m_render->SetBackground(0.5, 0.3, 0.2);
	m_render->SetGradientBackground(true);		// 背景色渐变

	m_pRenderWin->AddRenderer(m_render);
	m_pRenderWin->SetSize(800, 600);
	m_pRenderWin->Render();

	m_pInteractor->SetInteractorStyle(m_pInteractorStyle);
	m_pInteractor->SetRenderWindow(m_pRenderWin);


	m_pRenderWin->Render();
	m_pInteractor->Start();

	return 0;
}

      上面,设置了三个灯光,分别位于世界坐标xyz轴上20的位置,x轴上为红色灯,y轴上为绿色灯,z轴上为蓝色灯,灯光方向均照向原点处(相机焦点)。上面,我们将模型旋转了45度,因此,顶面既可以接收到y轴的绿光,还可以接收到z轴的蓝光,以下为效果图:


      从这个效果图,以及render回调函数打印的相机位置,我们都可以很直观的看出vtk的坐标系系统是怎样的,为右手坐标系,默认情况下,屏幕右边为X正方向,屏幕上面为Y轴正方向,出屏幕方向(垂直屏幕向外)为Z正方向。

vtk光照详解:

      vtkLight是vtk中用于3D渲染的虚拟灯,它提供了设定光源位置、光源颜色、光源亮度、光源属性以及打开关闭光源的方法:

      (1)SetColor:设置灯光颜色,以0~1之间的小数指定RGB强度。

      (2)SetPosition:设置灯光位置。

      (3)SetFocalPoint:设置灯光焦点。

      (4)SetIntensity:设置光照强度(0~1)。

      (5)SetSwitchSwitchOnSwitchOff:打开/关闭光照。

      同样,Set方法一般都会有对应的Get方法,例如:GetPosition可以获取灯光位置,GetSwitch可以获取灯光是否打开,GetFocalPoint可以获取灯光焦点。

      实际上,我们在vtkLight中,找不到GetSet这些方法,实际上,vtk里面做了宏定义,如下:

vtkSetMacro(Switch,int);
vtkGetMacro(Switch,int);

      在里面,就定义了对应的Get和Set方法。这样做为了代码的整洁与统一,更有益于团队开发。

vtkLight其他方法:一般Set方法都会有对应的Get方法

      (1)SetAmbientColor:设置环境光照颜色。

      (2)SetDiffuseColor:设置漫反射光颜色。

      (3)SetSpecularColor:设置镜面反射光颜色。

      (4)SetColor:设置上面三种光照为同一种颜色。

      (5)SetPositional:设置是否为位置照明(位置光),此外有对应的On和Off版本。

      (6)SetExponent:设置位置照明中使用的余弦参数。

      (7)SetConeAngle:设置光源锥度(单位为度°)。

      (8)SetAttenuationValues:设置光源二次衰减常数。

      (9)SetTransformMatrix:设置光源的变换矩阵。

      (10)GetTransformPosition:获取灯光世界空间坐标(由变换矩阵得来)。

      (11)GetTransformFocalPoint:获取灯光焦点(有变换矩阵得来)。

      (12)SetDirectionAngle:根据高程和方位角设置灯光位置和焦点。

      (13)DeepCopy:深层复制相机。

      (14)SetLightType:设置灯光类型。

      (15)SetLightTypeToHeadlight:设置灯光类型为前照灯(始终位于相机处,指向相机焦点)。

      (16)SetLightTypeToSceneLight:设置灯光类型为世界坐标灯光。

      (17)SetLightToCameraLight:设置灯光类型为相机灯(并不一定位于相机处)

      (18)SetShadowAttenuation:设置阴影强度,光被阻挡的强度(0~1),1为完全阻挡

      例如,在上面程序的灯光设置中,加入以下代码:

	m_lightRed->SetPositional(1);
	m_lightGreen->SetPositional(1);
	m_lightBlue->SetPositional(1);
// 	m_lightRed->SetExponent(0.5);
// 	m_lightGreen->SetExponent(0.5);
// 	m_lightBlue->SetExponent(0.5);
	m_lightRed->SetConeAngle(15);
	m_lightGreen->SetConeAngle(15);
	m_lightBlue->SetConeAngle(15);
	m_lightRed->SetShadowAttenuation(0.5);
	m_lightGreen->SetShadowAttenuation(0.5);
	m_lightBlue->SetShadowAttenuation(0.5);

      其对应的效果如下图:


      对于其他的,例如相机坐标转换,转换矩阵等,可以在使用的时候再做具体测试。

      vtk中,相机也不只有vtkLight,还有vtkLightActor、vtkLightCollection等。



猜你喜欢

转载自blog.csdn.net/qq_31622605/article/details/80903752
今日推荐