回想四叉树LOD地形(上)
为什么要用LOD地形?
这样一来。不管是CPU或者是GPU的开销都非常大,地形略微变大,机器要做的工作就要多非常多,实时程序随时变成播放幻灯片。
况且,假设地形比較大,那么在远处的地形三角形被投影到屏幕上时或许已经变成了几个像素点。甚至不可见了。
既然远处的地形对我们的视觉贡献不大。那么为什么还要辛辛苦苦地让硬件做那么多的无用功呢?
那就是LOD地形。LOD的全称是“Level Of Detail”(细节层级),主要的要求是:在近处的地形渲染得尽可能具体,在远处的地形渲染得尽可能简单。
通常。LOD地形除了“远粗近细”的功能外。一般还加上了“视锥体可见性剔除”功能,即仅仅考虑在视野范围内的地形三角形是否渲染,而绝不渲染在视野外的。这种“简化”+“剔除”机制能够大幅度减少机器的开销。听起来是挺有吸引力的,可是到底怎么实现呢?
地形是由 (2^n+1) X (2^n+1) 个顶点组成,当中n>0,n到底要多大?我认为跟n有关系的计算都不溢出就好。
左下图就是个9X9的地形样例。实际上的地形不会那么小。几百X几百甚至成千上万也不奇怪,这里仅仅是为了举例说明而已。另外。组成地形的基本单元也不再像龙书中那样使用一个个的独立三角形。而是使用三角形扇为地形基本单位,这里的三角形扇事实上也是由8个三角形组成,在渲染API中使用9个顶点和10个索引表示。
我们最好还是把这样组成的三角形扇称为一个地形结点。如右下图表示:
一个地形结点
说起来非常抽象。后面看代码就清楚了。
因为有些结点须要切割有些不须要。所以最后得到的结果不会像上面三幅图那么规则,或许像这样:
须要切割的结点将切割后得到的子结点压入第二条队列中,自己弹出第一条队列。不须要切割的结点直接弹出第一条队列并送入渲染API。
在第一条队列中全部结点都被处理完成后,两条队列交换身份,第二条队列变成第一条,然后反复之前处理步骤。直到两条队列中都没有结点为止。
由于有可能一个结点大得离谱但却远在天边。若该结点不切割又会造成地形细节大量损失;又或者一个结点小得可怜却近在眼前,本来已经能够表示足够的地形细节了但却依旧被切割了。所以。为了处理好这两种情况,我们还要考虑结点的大小。把两个因素放在一起考虑,由此得出潘大神的第一条评价公式:
这个公式表示,当结点离视点越来越远,且地形结点越来越小时。两者的比值超过C。地形结点就不须要切割。这个调节因子是要依据地形显示的结果来确定的。也就是要在地形系统实现后,在測试阶段进行该因子的调整。
比方左上图中。底下的平面代表简化后的地形结点,上面笼罩着的是实际的地形结点。
直观上,我们会发现有5个误差,在图中显示为结点边上的dh1、dh2、dh3、dh4以及中心处的dh0。为保证误差測量结果尽量准确。我们还要考虑大地形结点被切割成4个子地形结点后,每一个子节点的粗糙度。在右上图中表示为dh5、dh6、dh7、dh8。
那子节点的粗糙程度怎么算?我们仅仅须要反复地像计算大结点粗糙度那样即可了,非常easy发现这是个递归的过程。那假设一个地形结点已经切割到没有子节点时怎么办?那就忽略dh5~8,仅仅考虑前5个误差仅仅即可了。
这是由于将地形进行平滑处理之后。地形的粗糙度R降低了。直观上看。简化显示和实际显示的误差不会太大。于是“突”现象就不那么明显了。从公式上看,R值小,地形结点被简化的几率增高了。于是相对显示的三角形就少了。
这句话不理解没关系,先记住。该标志数组的作用是:在当前结点进行切割时提供四周结点的存在信息。若四周的结点都存在则当前结点能够切割,否则,仅仅要四周随意一个结点不存在。当前结点就不能切割。这一步推断是在前面的评价系统之后才运行的,也就是说,评价系统的推断优先于这一步推断,仅仅有两个阶段的推断都通过了,结点才干算真正地能够被切割。
怎样更新?当一个结点能够切割时。将自身相应的标志位设为1,同一时候将四个子结点相应的标志位也设为1。当一个结点不能切割时,将自身相应的标志位也设为1,但同一时候将四个子结点相应的标志位设为0。
我想大家一定会对“结点相应的标志位”这个说法非常不解,事实上在代码实现的时候。一个结点仅仅须要用中心顶点的索引以及所属级别来表示即可了,仅仅是送入渲染API时才转换成10个索引表示的三角形扇,到时看代码就知道了。非常抽象是吧?以下我来用9X9的样例演示一下。
一開始地形块太大,如果被评估为须要切割,那么标志数组修改就像以下左中两幅图:
话说回来,中间那幅图的大地形结点在切割时需不须要考虑四周的标志位?当然要,但是去哪找?道理同前。如今看看推断四周标志后不可分的情况。
所以,即使左方结点后来通过了评价系统的切割评估,但在查看四周结点标志时。发现右方结点不存在,所以左方结点切割失败。分析完成。
前面提到过。在地形进行切割时,地形结点能够用结点中心顶点所在的索引和结点所属的级别表示,在送到渲染API时再转换成10个顶点索引表示的三角形扇。嘿!我们就是要在结点转换成10个索引的过程中消除裂缝。
怎么做?请看下图:
我们从左图能够发现,高分辨率级别的结点(即小结点)的正右方的标志位是0,代表正右方同等级别的结点不存在,依据这一信息。我们就能够把中间那幅图中的三角形扇的4号结点给忽略,这就导致0、3、5结点能够组成一个大点的三角面,而不再须要分别显示0、3、4和0、4、5组成的三角形。这个操作就消除掉了由4号结点引起的高度差,T型裂缝就是这样被消除掉了。如右上图。也就是说,我们能够依据一个结点四周相邻同等级别的结点相应的标志位是否为1来确定中间节点四条边中点的顶点是否參与渲染,从而消除裂缝。
~四叉树LOD的回想就差点儿相同这样了。感觉有必要做个重要代码回想,还是改天有时间写个下篇吧。本文不作为个人技术的创新展示,仅仅是学习心得的分享,全部知识都来自大神们的研究成果。
关于潘李亮的论文和曾涛的代码实现,改天再补上链接,如今得歇息············
回想四叉树LOD地形(上)的更多相关文章
- [转]基于四叉树(QuadTree)的LOD地形实现
实现基于四叉树的LOD地形时,我遇到的主要问题是如何修补地形裂缝. 本段我将描述使用LOD地形的优势,我实现LOD地形的思路,实现LOD地形核心模块的详细过程,以及修补地形裂缝的思路. 首先,LOD地 ...
- Ogre代码学习之1——Ogre中地形lod的基础:deltaHeight的计算
Ogre的地形系统中的重要概念:高度差,英文HeightDeltas,表示某个完整细节中的顶点,在某个它被隐去的lod中被插值之后的高度和原始高度(即高度图中的高度)之差. DeltaHeight = ...
- CesiumJS 2022^ 原理[4] - 最复杂的地球皮肤 影像与地形的渲染与下载过程
目录 API 回顾 1. 对象层级关系 1.1. Scene 中特殊的物体 - Globe 1.2. 地球 Globe 与椭球 Ellipsoid 1.3. 瓦片四叉树 - QuadtreePrimi ...
- 【SSH2(实用文章)】--Struts2文件上传和下载的例子
回想一下,再上一篇文章Struts2实现机制,该步骤做一步一步来解决,这种决心不仅要理清再次Struts2用法.映射机制及其在深入分析.最后一个例子来介绍Struts2一种用法,这里将做一个有关文件上 ...
- Unity3D LOD Group
今天下了一个4.0破解版,然后看到一个Demo Level of Detail 就研究了一下 以前用的是Unity3.5 free版本,没有这个功能,真实泪奔....... As your s ...
- 记一次线上 OOM 和性能优化
大家好,我是鸭血粉丝(大家会亲切的喊我 「阿粉」),是一位喜欢吃鸭血粉丝的程序员,回想起之前线上出现 OOM 的场景,毕竟当时是第一次遇到这么 紧脏 的大事,要好好记录下来. 1 事情回顾 在某次周五 ...
- 🏆【Alibaba中间件技术系列】「Nacos技术专题」配置中心加载原理和配置实时更新原理分析(上)
官方资源 https://nacos.io/zh-cn/docs/quick-start.html Nacos之配置中心 动态配置管理是 Nacos的三大功能之一,通过动态配置服务,可以在所有环境中以 ...
- PVS BSP
作者:韦易笑链接:https://www.zhihu.com/question/38060533/answer/84432973来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...
- 剖析虚幻渲染体系(14)- 延展篇:现代渲染引擎演变史Part 1(萌芽期)
目录 14.1 本篇概述 14.1.1 游戏引擎简介 14.1.2 游戏引擎模块 14.1.3 游戏引擎列表 14.1.3.1 Unreal Engine 14.1.3.2 Unity 14.1.3. ...
随机推荐
- 0x66 Tarjan算法与无向图联通性
bzoj1123: [POI2008]BLO poj3694 先e-DCC缩点,此时图就变成了树,树上每一条边都是桥.对于添加边的操作,相当于和树上一条路径构环,导致该路径上所有边都不成为桥.那么找这 ...
- CodeForces 660A
Description You are given an array of n elements, you must make it a co-prime array in as few moves ...
- WCF WEB HTTP请求 WCF REST FUL
首先上点概念WCF 很好的支持了 REST 的开发, 而 RESTful 的服务通常是架构层面上的考虑. 因为它天生就具有很好的跨平台跨语言的集成能力,几乎所有的语言和网络平台都支持 HTTP 请求, ...
- 2.TinkPHP入门----控制器
1.控制器创建 命名规则:控制器名称+Controller+.class.php, 例如GoodsController.class.php UserController.class.php 控制器结 ...
- 创建一个netcore2.0和angular的项目并运行起来
netcore2.0发布了,喜大普奔. 我们先下载SDK,请看张善友老师的这篇博客 http://www.cnblogs.com/shanyou/p/7363037.html 下载完之后 我用的vs2 ...
- 前端-JQ思维导图
看不清的朋友右键保存或者新窗口打开哦!喜欢我可以关注我,还有更多前端思维导图笔记
- bootstrap3-dialog:更强大、更灵活的模态框
用过bootstrap框架的同学们都知道,bootstrap自带的模态框用起来很不灵活,可谓鸡肋的很.但nakupanda开源作者封装了一个更强大.更灵活的模态框——bootstrap3-dialog ...
- MVC 入口
1.在 Global.asax public class MvcApplication : System.Web.HttpApplication { protected void Applicatio ...
- 【seo】title / robots / description / canonical
1.title title,就是浏览器上显示的那些内容,不仅用户能看到,也能被搜索引擎检索到(搜索引擎在抓取网页时,最先读取的就是网页标题,所以title是否正确设置极其重要. 1)title一般不超 ...
- 理解Faster-RCNN 中的Anchor
先上图看一下Faster R-CNN操作流程: 图片说明:Faster R-CNN=Fast R-CNN+RPN,其中Fast R-CNN结构不变:RPN负责生成proposals,配合最后一层的f ...