基于UE4/Unity绘制地图 - 确定展示区域

2023-11-02

前言

基于UE4/Unity绘制地图基础元素-线

基于UE4/Unity绘制地图基础元素-面和体

基础知识

在研究清楚如何绘制地图的线面体之后,接下来需要确定需要展示的地图区域了。

地图可以看成是一个巨型的开放世界游戏场景,因此为了便于数据存储和查找,传统的做法是将地球根据墨卡托投影转换为平面地图,再将地图分级分块进行切片,通过索引获取到对应的数据。

image.png

以OSM的地图为例,导出数据是以当前视口的大小,查询对应级别的切片得到的。Google的卫星图、地形图等也都是按照分级分块的规则进行管理。

image.png

基于视口展示

传统的地图展示方式,展示区域的确定通常是与视口绑定的,即地图切片只加载摄像机视锥体与地图所在平面相交的部分,并在摄像机移动时动态进行切片的更替。

image.png

这种方式对于查看全世界全量地图数据的场景非常合适,但对于希望使用游戏引擎构建一个更精细的世界来说,有一些不足:

  • 视锥体动态计算切片的前提是,一定要保证其与地图所在平面一定有四个交点,因此摄像机的FOV(竖直方向的张开角度)不能太大,否则当摄像机俯仰角变化时,视锥体的上下两个面可能与地图所在平面平行,从而导致无法计算切片。
  • 在平行之前,同样也会因为角度问题,导致计算得到的切片数量过大,无法进行加载;或因为设置了一些切片数量的限制,导致看到的世界有所缺失。

因此视椎体动态计算的方式,通常会固定一个较小的FOV,并且限制俯仰角。同时因为性能的限制,对于大俯仰角的情况,通过一些手段进行切片的数量优化。以腾讯的JS API GL为例,为了减少大俯仰角造成切片数量过大带来的性能瓶颈,采用雾化的方式将较远处的场景进行剔除,使得可以无缝衔接查看整个世界。

image.png

UE4和Unity都有能够获得视椎体的接口。以UE4为例,ULocalPlayer中存储了Viewport相关的信息,根据矩阵变换的信息可以得到存储视椎体信息的FConvexVolume。

ULocalPlayer* LocalPlayer = GetWorld()->GetFirstPlayerController()->GetLocalPlayer();

FSceneViewProjectionData ProjectionData;

LocalPlayer->GetProjectionData(LocalPlayer->ViewportClient->Viewport, eSSP_FULL, ProjectionData);
    
FMatrix ViewProjectionMatrix = ProjectionData.ComputeViewProjectionMatrix();
    
FConvexVolume ViewFrustum;
    
GetViewFrustumBounds(ViewFrustum, ViewProjectionMatrix, true);

FConvexVolume的Planes数组中依次存储了左右上下四个平面的方程FPlane,比较特殊的是FPlane是以Xx+Yy+Zz=W的形式存储了(X,Y,Z,W)值。同时,地图所在平面也可以使用一个方程表示,因此,视锥体与地图的一个交点就是三个平面的相交点。(以左上交点为例,将视椎体的左、上平面方程与地图所在平面方程联立,即可得到交点)

其中的联立求交,可以使用矩阵运算快速求得:

image.png

若联立有解,则矩阵可逆,那么行列式不为0可以作为判断有解的快速验证方式。当确定有解后,则可使用逆矩阵快速求解:

image.png

基于行政区划展示

基于视口展示方案理论上完全可行,但对于有高性能显卡支撑的游戏引擎来说远远不够:

  • 地图至少要像GTA那样,目之所及都有元素,不能将远裁剪面如此提前。
  • 摄像机需要自由度,可以随心所欲的进行移动。

因此,比较直接的想法是,如果想展示一个城市,那就一次性渲染出城市的所有数据。

image.png

城市的数据可以借助于现有的服务获取,以腾讯位置服务的WebService API为例,可以通过行政区划服务获取到对应的行政区划点串信息,依托于地图数据的切片存储形式,因此只需要确定这个行政区划点串覆盖的切片集合就可以了。

// 行政区划线点串以连续的经纬度进行表示
"polygon": [ [116.809403,39.61482,116.790175,39.610555,116.780286,39.593196....],]

根据基础知识所说,每一个切片都是一个小正方形,而行政区划点串信息代表的是一个大多边形,因此转化为使用小正方形切片去近似一个多边形的问题。

是不是听起来十分像光栅化

image.png

因此顺着这个思路,借助于光栅化的方式求切片集合:

1、光栅化的基本单位是三角形,因此对于行政区划的多边形,先调用三角剖分算法分解为三角形的集合。
2、对于一个三角形,最经典的方式就是拆为两个更容易绘制的三角形,一个底边平行,一个顶边平行,再使用水平扫线法求得所有的切片。

image.png

具体算法可以参考这篇TriangleRasterization的文章,其中还有Bresenham算法和重心坐标算法等其他光栅化的算法。

获取到所有切片数据后,就可以进行行政区划的展示了。

基于位置的动态展示方法

借助于光栅化算法可以得到切片集合进行渲染展示,但基于行政区划的方式展示也有弊端,即CPU/GPU资源有限,对于几千平方公里的城市可能无法粗暴的直接支持。

和开放大世界游戏一样,比较合理的方式就是随着当前位置动态载入/载出场景,使得感官上构建出一个无缝衔接的大世界。

以UE4为例,Epic提供了World Composition这个利器去支持游戏开发者制作开发大世界游戏,开发者可以方便的并行编辑每个子关卡。运行时根据游戏角色所在的位置,可以异步加载/卸载子关卡,达到无缝衔接的效果。

image.png

而对于不适合使用World Composition的场景,可以退一步使用Level Streaming去进行手动管理,初步的使用方法,可以参考之前的文章,对于Level Streaming的一些初步的学习

基于位置的动态展示方法需要做更多的额外工作去达到完美的沉浸效果,目前这部分依旧还在摸索中,希望有朝一日可以完全解决。这篇文章权当是抛砖引玉,希望给大家带来一些思考。

作者:程序员阿Tu

链接:https://zhuanlan.zhihu.com/p/353203619

来源:知乎

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于UE4/Unity绘制地图 - 确定展示区域 的相关文章

  • 手把手教你搭建使用NuGet私有源

    文章目录 前言 Who 什么是NuGet Why 为什么用NuGet How 怎么使用NuGet 搭建Nuget私有源 打包Nuget包 发布到私有源 不开启密钥验证 开启密钥验证 测试 总结 前言 相信写过 net的小伙伴应该都用过NuG
  • 时序动作定位

    ActivityNet 下载地址 https github com UCASUSTC ActivityNet Dataset Download 目前最大的数据库 同样包含分类和检测两个任务 数据集地址为Activity Net 这个数据集仅
  • ASCII表

    http office microsoft com zh cn assistance HA011331362052 aspx ASCII 打印字符 数字 32 126 分配给了能在键盘上找到的字符 当您查看或打印文档时就会出现 数字 127
  • 软件测试大赛之移动测试练习题-全能计算器

    1 环境准备 确保以下环境全部开启 1 1 查看设备是否连接成功 以管理员运行cmd窗口 输入adb devices 1 2 开启UI Automator Viewer 通常都在tools文件夹下面的bin目录 点击 开启成功 1 3 ap
  • Qt 程序不重启实现自动翻译 -- 多语言切换

    在做应用程序的过程中 多语言的切换是必不可少的功能 今天看一看怎么用Qt自带的翻译类 QTranslator 进行多语言之间的无缝切换 并且不会重启程序 首先我们看下实现效果 1 传统的设置语言的方法 Qt的语言翻译主要是针对使用 Qtde
  • Maven环境变量的配置(详细教程)

    一 下载Maven 1 浏览器搜索 2 官网Maven 不要进错哟 3 4 5 下载完成后 解压放入创建一个新的文件夹下 路径不要有中文和空格 二 环境变量配置 1 点击我的电脑 gt 属性 gt 高级环境变量配置 2 新增加两条 M2 H
  • python 求2的倍数

    if n 2 0
  • 如何做好软件项目策划

    作为一个刚刚入门的程序员 当接到一个新的项目时 我往往会有一筹莫展的感觉 不知道如何去下手 设计数据库 设计程序结构 设计功能结构 设计用户权限 预留功能扩展等等 当想不出东西的时候 我的做法是 先静一静 好好捋一捋 假如说我要盖个房子 那
  • 浅谈LOG日志的写法

    文章来源于公司的大牛 1 Log的用途 不管是使用何种编程语言 日志输出几乎无处不再 总结起来 日志大致有以下几种用途 l 问题追踪 通过日志不仅仅包括我们程序的一些bug 也可以在安装配置时 通过日志可以发现问题 l 状态监控 通过实时分
  • Http传输协议介绍

    HTTP简介 HTTP协议是Hyper Text Transfer Protocol 超文本传输协议 的缩写 是用于从万维网 WWW World Wide Web 服务器传输超文本到本地浏览器的传送协议 HTTP是一个基于TCP IP通信协
  • mes管理系统php原码,MES系统_MES车间管理系统_轻量化定制方案

    信息化管理系统介绍 依据信息化管理目标不同 企业信息化系统的内容差异较大 一般地 企业信息化系统由以下三个主要层次组成 各层次中包含有用途各异 功能各异的业务处理子系统或功能组件 包括企业经营管理系统 过程管理系统 过程控制系统 信息化管理
  • 微软Hololens 2开发指南

    微软Hololens 2开发指南 1 首先来介绍一下这款混合现实MR产品 这是微软在2019年向市场发布的 内部拥有win10系统 很方便用户操作 而且手势简单易上手 相较于第一代产品来说整体提升了不少 结构上解决了第一代压鼻梁的问题 这次
  • mobile footer nav

    item 数量可变 图片可变 高亮颜色可变 tabbar vue
  • stable diffusion webui升级bug问题解决思路(纯干货)

    个人网站 https tianfeng space 文章目录 一 前言 二 个人方案 1 扼杀在萌芽中 A 解压后点击启动器运行依赖 然后点击A启动器 B 更新本体和扩展 全部到最新版本 C 把controlnet1 1放入stable d
  • 由React Router引起的组件重复渲染谈Route的使用姿势

    React Router 4 把Route当作普通的React组件 可以在任意组件内使用Route 而不再像之前的版本那样 必须在一个地方集中定义所有的Route 因此 使用React Router 4 的项目中 经常会有Route和其他组
  • VMware虚拟机搭建 ESXI-8.0环境并且安装Mac OS13系统,

    官方下载地址 https customerconnect vmware com en evalcenter p free esxi8 下载完成大小如下 打开VMware虚拟机 新建虚拟机 导入镜像 选择下载VMware VMvisor In
  • Alibaba Arthas 3.1.1版本:trace支持行号/小幅改进

    Arthas是Alibaba开源的Java诊断工具 深受开发者喜爱 Github https github com alibaba arthas 文档 https alibaba github io arthas Arthas 3 1 1版
  • JPA在ddl-auto=update时,首次执行报错Cant DROP; check that column/key exists

    背景 在一个新的数据库上启动项目 报了一堆Can t DROP xxx check that column key exists的错误 虽然不影响系统正常启动 也不影响建表 但是影响心情 因此上网查询原因 发现大部分都没提到这个问题 要么就
  • 微信青蛙和会员让消费者看得见优惠

    双面屏的设计可以及时地建立收银员于消费者的沟通关系 通过背屏 收银员可以把许多智慧营销的内容及时地推送到前屏 提高商户的复购率以及店铺管理效率 比如选择推送商户公众号的二维码 消费者可以在支付时直接完成关注 关注后可以推送新品 也可以查看消

随机推荐