【Overload游戏引擎】源码分析之十一:OvRendering函数库(九)

2021SC@SDUSC

目录

Camera

1.矩阵计算

1.1CalculateProjectionMatrix

1.2CalculateViewMatrix

2.Cache函数


本节我们来讨论游戏引擎中一个很重要的内容camera(摄像机),在了解相关的代码时,我们需要用到OvTools函数库中的工具,可点击ReferenceOrValue 前往了解。

Camera

Camera类中包含的成员变量较多,大多数数据类型都已在前文提到,例如m_frustum(视锥体对象)、m_viewMatrix(观察矩阵)、m_projectionMatrix(投影矩阵)、m_projectionMode(投影模式,分为ORTHOGRAPHIC(正交投影)与PERSPECTIVE(透视投影),见OvRendering::Settings::EProjectionMode 文件)。

    class Camera
	{
	private:
		OvRendering::Data::Frustum m_frustum;
		OvMaths::FMatrix4 m_viewMatrix;
		OvMaths::FMatrix4 m_projectionMatrix;
        OvRendering::Settings::EProjectionMode m_projectionMode;

		float m_fov;
        float m_size;
		float m_near;
		float m_far;

		OvMaths::FVector3 m_clearColor;

		bool m_frustumGeometryCulling;
		bool m_frustumLightCulling;
	};

除了以上特殊类型的变量外,还有m_fov(视角范围)、m_size(正交投影时视角立方体的边长)、m_near\m_far(摄像机到近\远平面)、m_几何集合剔除)、m_frustumLightCulling(是否进行视锥体灯光剔除)。

接下来大致浏览一遍相关的函数:

	public:
		Camera();

		void CacheMatrices(uint16_t p_windowWidth, uint16_t p_windowHeight, const OvMaths::FVector3& p_position, const OvMaths::FQuaternion& p_rotation);

		void CacheProjectionMatrix(uint16_t p_windowWidth, uint16_t p_windowHeight);

		void CacheViewMatrix(const OvMaths::FVector3& p_position, const OvMaths::FQuaternion& p_rotation);

		void CacheFrustum(const OvMaths::FMatrix4& p_view, const OvMaths::FMatrix4& p_projection);

		float GetFov() const;
        float GetSize() const;
		float GetNear() const;
		float GetFar() const;
		const OvMaths::FVector3& GetClearColor() const;
		const OvMaths::FMatrix4& GetProjectionMatrix() const;
		const OvMaths::FMatrix4& GetViewMatrix() const;
		const OvRendering::Data::Frustum& GetFrustum() const;

		bool HasFrustumGeometryCulling() const;

		bool HasFrustumLightCulling() const;

        OvRendering::Settings::EProjectionMode GetProjectionMode() const;

		void SetFov(float p_value);
        void SetSize(float p_value);
		void SetNear(float p_value);
		void SetFar(float p_value);
		void SetClearColor(const OvMaths::FVector3& p_clearColor);
		void SetFrustumGeometryCulling(bool p_enable);
		void SetFrustumLightCulling(bool p_enable);
        void SetProjectionMode(OvRendering::Settings::EProjectionMode p_projectionMode);

	private:
		OvMaths::FMatrix4 CalculateProjectionMatrix(uint16_t p_windowWidth, uint16_t p_windowHeight) const;
		OvMaths::FMatrix4 CalculateViewMatrix(const OvMaths::FVector3& p_position, const OvMaths::FQuaternion& p_rotation) const;

以上函数中包含着大量set与get函数,即对成员变量赋值与取值,这里就不作介绍,接下来我们一一来看几个关键的函数。

1.矩阵计算

1.1CalculateProjectionMatrix

OvMaths::FMatrix4 OvRendering::LowRenderer::Camera::CalculateProjectionMatrix(uint16_t p_windowWidth, uint16_t p_windowHeight) const
{
    using namespace OvMaths;
    using namespace OvRendering::Settings;

    const auto ratio = p_windowWidth / static_cast(p_windowHeight);

    switch (m_projectionMode)
    {
    case EProjectionMode::ORTHOGRAPHIC:
        return FMatrix4::CreateOrthographic(m_size, ratio, m_near, m_far);

    case EProjectionMode::PERSPECTIVE: 
        return FMatrix4::CreatePerspective(m_fov, ratio, m_near, m_far);

    default:
        return FMatrix4::Identity;
    }
}

CalculateProjectionMatrix函数用于计算当前摄像机的投影矩阵,需要传入的参数是投影窗口的宽度和高度。

首先我们利用窗口的宽高计算宽高比,这里为了使比值的结果为浮点数,需要对宽高做强制类型转换。接下来根据自身的m_projectionMode变量进行分类,对应不同的投影模式调用创建函数,创建函数详见【Overload游戏引擎】源码分析之二:OvMaths函数库(下)。

1.2CalculateViewMatrix

OvMaths::FMatrix4 OvRendering::LowRenderer::Camera::CalculateViewMatrix(const OvMaths::FVector3& p_position, const OvMaths::FQuaternion& p_rotation) const
{
	const auto& up = p_rotation * OvMaths::FVector3::Up;
	const auto& forward = p_rotation * OvMaths::FVector3::Forward;

	return OvMaths::FMatrix4::CreateView
	(
		p_position.x, p_position.y, p_position.z,												// Position
		p_position.x + forward.x, p_position.y + forward.y, p_position.z + forward.z,			// LookAt (Position + Forward)
		up.x, up.y, up.z																		// Up Vector
	);
}

观察矩阵的计算与上述类似,需要传入当前摄像机的世界坐标以及对应的旋转变量,这里需要使用OvMaths中定义的默认摄像机的up向量与forward向量,并对其进行旋转变换,最后调用创建函数获得观察矩阵。

2.Cache函数

void OvRendering::LowRenderer::Camera::CacheMatrices(uint16_t p_windowWidth, uint16_t p_windowHeight, const OvMaths::FVector3& p_position, const OvMaths::FQuaternion& p_rotation)
{
	CacheProjectionMatrix(p_windowWidth, p_windowHeight);
	CacheViewMatrix(p_position, p_rotation);
	CacheFrustum(m_viewMatrix, m_projectionMatrix);
}

void OvRendering::LowRenderer::Camera::CacheProjectionMatrix(uint16_t p_windowWidth, uint16_t p_windowHeight)
{
	m_projectionMatrix = CalculateProjectionMatrix(p_windowWidth, p_windowHeight);
}

void OvRendering::LowRenderer::Camera::CacheViewMatrix(const OvMaths::FVector3& p_position, const OvMaths::FQuaternion& p_rotation)
{
	m_viewMatrix = CalculateViewMatrix(p_position, p_rotation);
}

void OvRendering::LowRenderer::Camera::CacheFrustum(const OvMaths::FMatrix4& p_view, const OvMaths::FMatrix4& p_projection)
{
	m_frustum.CalculateFrustum(p_projection * p_view);
}

以上函数完成了对摄像机的所有变换矩阵的赋值,包括投影矩阵、观察矩阵与视锥体变换矩阵,其中涉及的图形学原理已在前文讨论过,相关内容详见【Overload游戏引擎】源码分析之二:OvMaths函数库(下)。

你可能感兴趣的:(游戏引擎)