当前位置: 首页 > article >正文

vulkanscenegraph显示倾斜模型(5.3)-相机

 前言

     在Vulkan中,相机的概念并非由API直接提供,而是由应用程序实现。相机的核心功能包括视图变换和投影变换:视图变换将世界坐标系中的物体转换到相机坐标系,投影变换则将相机坐标系中的物体转换到投影空间。在VSG(Vulkan Scene Graph)框架中,vsg::Camera类封装了视图矩阵和投影矩阵,并提供了便捷的接口来管理相机。本章将深入探讨Vulkan中的矩阵变换原理,以及VSG对相机功能的封装与实现。


目录

  • 1 vsg::Camera
  • 2 vsg中的视图变换
  • 3 vsg中的投影变换

1 vsg::Camera

      本章将参照测试用例(写文章-CSDN创作中心)中的如下代码进行深入探讨。

	vsg::ComputeBounds computeBounds;
	vsg_scene->accept(computeBounds);
	vsg::dvec3 centre = (computeBounds.bounds.min + computeBounds.bounds.max)*0.5;
	double radius = vsg::length(computeBounds.bounds.max - computeBounds.bounds.min)*0.6;
	double nearFarRatio = 0.001;

	// set up the camera
	auto lookAt = vsg::LookAt::create(centre + vsg::dvec3(0.0, -radius * 3.5, 0.0), centre, vsg::dvec3(0.0, 0.0, 1.0));
	vsg::ref_ptr<vsg::ProjectionMatrix> perspective;
	if (vsg::ref_ptr<vsg::EllipsoidModel> ellipsoidModel(vsg_scene->getObject<vsg::EllipsoidModel>("EllipsoidModel")); ellipsoidModel)
	{
		perspective = vsg::EllipsoidPerspective::create(lookAt, ellipsoidModel, 30.0, static_cast<double>(vsg_window->extent2D().width) / static_cast<double>(vsg_window->extent2D().height), nearFarRatio, 0.0);
	}
	else
	{
		perspective = vsg::Perspective::create(30.0, static_cast<double>(vsg_window->extent2D().width) / static_cast<double>(vsg_window->extent2D().height), nearFarRatio*radius, radius * 4.5);
	}
	auto vsg_camera = vsg::Camera::create(perspective, lookAt, vsg::ViewportState::create(vsg_window->extent2D()));

      上述代码中1-5行,通过vsg::ComputeBounds计算得到场景的包围盒范围,进而计算得到场景中心点和半径,并设置远景裁剪面的比例。接着第7行,计算得到视图矩阵,第8-16行,计算得到投影矩阵。代码17行,由视图矩阵、投影矩阵、视口状态(Viewport)创建vsg::Camera。

    class VSG_DECLSPEC Camera : public Inherit<Node, Camera>
    {
    public:
        Camera();

        Camera(ref_ptr<ProjectionMatrix> in_projectionMatrix, ref_ptr<ViewMatrix> in_viewMatrix, ref_ptr<ViewportState> in_viewportState = {});

        std::string name;
        ref_ptr<ProjectionMatrix> projectionMatrix;
        ref_ptr<ViewMatrix> viewMatrix;
        ref_ptr<ViewportState> viewportState;

        VkViewport getViewport() const { return viewportState ? viewportState->getViewport() : VkViewport{}; }
        VkRect2D getRenderArea() const { return viewportState ? viewportState->getScissor() : VkRect2D{}; }

        void read(Input& input) override;
        void write(Output& output) const override;
    };

      vsg::Camera类提供了投影矩阵(ref_ptr<ProjectionMatrix>)、视图矩阵(ref_ptr<ViewMatrix>)以及视口设置(ref_otr<ViewportState>),这些共同控制着View在场景中所观察到的内容。

2 vsg中的视图变换

      在vsg中视图相关的矩阵基类为vsg::ViewMatrix,子类有vsg::LookAt、vsg::LookDirection、vsg::RelativeViewMatrix、vsg::TrackingViewMatrix。

auto lookAt = vsg::LookAt::create(centre + vsg::dvec3(0.0, -radius * 3.5, 0.0), centre, vsg::dvec3(0.0, 0.0, 1.0));
          Z (Up)
          |
          |
          |
          +--------> Y
         /
        /
       X

     其中vsg::LookAt,通过传入eyePosition、centerPositon、upDirection创建。上述代码,eyePosition位于负y轴上,centerPositon为上图的中心点、upDirection为Z轴。因此模型在视口中呈现的状态类似左视图的观察效果。

3 vsg中的投影变换

    在vsg中投影相关的矩阵基类为vsg::ProjectionMatrix,相应的子类有vsg::EllipsoidPerspective、vsg::Orthographic、vsg::Perspective、vsg::RelativeProjection。

     其中vsg::Perspective中的矩阵计算公式如下:

     相比 OpenGL,Vulkan 在投影空间中,x 轴从左到右、y 轴从上向下(与 OpenGL 相反),同时 z 的取值范围为 0 到 1(其中近平面为 0、远平面为 1,而在 OpenGL 中,z 的取值范围为 -1 到 1)。

    将(0,0,-zNear)、(0,0,-zFar)带入公式,分别计算得到的深度值为1和0,这与vulkan正好相反,这种深度值分布方式被称为 Reversed-Z,是一种常见的深度优化技术。 相应地,VKCompareOp默认取值为VK_COMPARE_OP_GREATER。

     在Vulkan中,相机的概念并非由API直接提供,而是由应用程序实现,应用程序中的矩阵可通过vkCmdPushConstants将矩阵直接推送到命令缓冲区,对应的代码如下。

文末:本章在上一篇文章的基础上,进一步深入探讨 Vulkan 中的矩阵变换,重点分析了视图矩阵(View Matrix)和投影矩阵(Projection Matrix)的作用及其数学原理,并详细介绍了 VSG 框架对相机的封装实现——vsg::Camera 类。此外,本章还深入探讨了视图矩阵与投影矩阵的计算公式,对比了 Vulkan 与 OpenGL 在投影空间中的差异,并解释了 VSG 中投影矩阵计算公式的设计考量-ReverseZ。下一章将在本章的基础上,深入探讨 VSG 中的相机操纵器(Camera Manipulator)。相机操纵器的本质是通过用户交互动态修改视图矩阵,从而改变模型在视口中的显示效果。下章将详细分析相机操纵器的工作原理及其实现方式,以更好地理解如何通过交互控制相机状态。


http://www.kler.cn/a/590205.html

相关文章:

  • 【eNSP实战】基本ACL实现网络安全
  • AI大模型本地化谷云科技全域集成能力重构企业数智化生态
  • Logo语言的链表插入
  • 全栈网络安全-渗透测试-3
  • 物联网(IoT)平台层中 大数据处理过程
  • android开发:android.graphics包的介绍
  • SQL注入:安全威胁的幽灵与防御体系的构建——从经典攻击到智能防护的演进
  • Spring 中使用代理的注解及机制分析
  • matlab 正态分布
  • Flink State 是处理有状态流计算的核心机制,其典型应用场景及具体说明
  • 正则表达式小结
  • Redis-锁-商品秒杀防止超卖
  • HTML深度解读
  • 视频转音频, 音频转文字
  • 物联网(IoT)架构中,平台层的应用与技术
  • Spring Security 教程:从入门到精通(含 OAuth2 接入)
  • 硬件驱动——51单片机:独立按键、中断、定时器/计数器
  • linux自律 第 40 天
  • docker可视化之dpanel
  • Android的消息机制