引擎设计跟踪 地形LOD的改进

虽然地形已经有LOD和形变(morphing)来进行LOD的渐变,从而避免bump, 但是如果LOD级别过多,远处的高山就会严重丢失细节,比如变成尖尖的凸起,非常丑陋,这是morphing无法解决的。

解决一种方式是使用强制的固定LOD (fixed LOD),如果一个block的高度(maxH)或者高度比率(dH/dX)超过一定阈值,就使用固定的高细节的LOD。

例如LOD 0为最高细节,aab为block的包围盒,那么:

1  if(aab.getSize().y / aab.getSize().x >= THRESOLD)
2      block.fixedLOD = 1;    //use the 2nd largest detail level. the most largest 0 is better.

之前我也考虑过类似的问题, 比如一个block如果是平的,那么就使用固定的最低细节的LOD。 这个想法我也是开的脑洞,看起来非常简单,但是实现起来有很多坑:

1.LOD链接问题

通常的LOD索引方法,只处理了相邻两级LOD的缝合链接: LODn--- LODn+1  (1:1),中间不会有2级以上的跳变。但是如果一个block是固定的级别f,那么对于所有的LOD级别,要处理LODf--LODn的缝合问题。

如果固定LOD级别f有n个,数量就是n:n(n对n),index buffer会呈指数级增长,非常浪费。如果固定LOD级别f比较少,比如只有两种: f=0 和 f=max(LOD),实际上index buffer的数量不会太多,

只需要生成2:n (2对n)的缝合。实际上1种或者两种就足够了,f=max(LOD)是针对平的地形block的优化,可有可无,一般地形里面纯平的地面比较少,除了像城市这种场景,里面可能会多点。

另外一种避免浪费的思路是,把中间和四个边的index buffer 拆开,因为中间是大部分index buffer的内容,边上的skirt缝合数据非常少,不管是1:1还是n:n,基本都可以忽略不计。这样每个block要分2个draw call,数量会double,但在开启批次合并时并没有损失。

2.LOD morhping的问题

如果一个block使用了固定LOD,顶点不会有任何改变,那么这个block的morphing已经没有意义了。原来的morhping数据反而会对固定LOD产生影响,导致一些不必要的高低起伏,表现为一些奇怪的凸起。

比如vertex buffer存储了morphing 高度, 就需要清除掉,使用原始高度,关闭morhping。同时,相邻的那些block, 如果不是固定LOD级别,也要清除掉一排边缘衔接顶点的morphing数据,否则一边没有morhping,另一边有,这样也有问题,会有裂缝。

3.LOD 索引生成的方式

假如有一个固定LOD级别f,那么对于f,要生成1对n的缝合。缝合的方式和正常的LODn--- LODn+1缝合方式类似,生成各个边的skirt。

主要问题是生成skirt的方式,可能会影响顶点插值效果。要尽量避免狭长的三角形,因为使用了fixed LOD的block,通常高度或者高度差很大,如果有狭长的三角形,那么他的两个顶点的高度可能差距很大,导致这个三角形的边非常突兀。

比如下面的这种就是不好的 (bad tesselation pattern of LOD skirt):

下面这种更好

最后发效果截图.。512x512地形, 6级LOD 从远处看:

下图是加载范围为1536x1536 (512x3)的地形,5级LOD。可以看到远处山的细节还在,近处纯平面的地形的三角形数量很低 (图中有bug已经修复)

另外,目前世界和地形的最大范围为16km(千米),因为原点在(0,0,0),范围为0~16km,损失了符号位的精度。如果将原点设置在-16km,范围为-16km~16km,世界最大范围就能达到32km。

关于最大范围的预估,可以根据IEEE754的浮点数来简单确认,float32的尾数位为23, 而游戏的最小精度大概要1毫米,即10-3,约等于1/1024 = 2-10, 要占用10位,剩下13位,就是8km,加上符号位是16km, 如果精度降低到2毫米,2-9,最大范围可以支持到32km。

如果要支持更大的范围,那么就需要用local坐标系或者类似的方法,或者再加上渲染前直接用物体和相机的相对位置,等等。工作太忙,暂时放后面有时间再做。

时间: 2024-12-09 20:32:47

引擎设计跟踪 地形LOD的改进的相关文章

引擎设计跟踪(九.14.2a) 导出插件问题修复和 Tangent Space 裂缝修复

由于工作很忙, 近半年的业余时间没空搞了, 不过工作马上忙完了, 趁十一有时间修了一些小问题. 这次更新跟骨骼动画无关, 修复了一个之前的, 关于tangent space裂缝的问题: 引擎设计跟踪(九) 3DS MAX 导出插件 引擎设计跟踪(九.10) Max插件更新,地形问题备忘 这里说明一下修复方法, 并且做一个总结. 之前的做法都不算错, 但是不完善. 这里有缝, 主要是因为那个战争机器3的模型本身已经复制了顶点( 左半部分和右半部分是不同的mesh, 有重合的顶点), 接缝处的顶点虽

引擎设计跟踪(九.14) 更新记录和骨骼动画导出

骨骼动画是去年打算写的部分, 但是中间因为工作太忙, 已经拖了一年了. 期间也加了其他东西, 比如对UI做了部分完善.UI对toolbar button添加了drop down 支持, 一种是dropdown menu, 一种是dropdown property sheet 实现这些控件不难, 但是要做抽象和复用, 接口设计稍微有点复杂. 现在可以把一个IConfig对象绑定到toolbar的button里了. 这样保存这些配置的时候,直接使用IConfig接口就可以了.贴一个编辑器的配置文件,

引擎设计跟踪(九.14.3.4) mile stone 2 - model和fbx导入的补漏

之前milestone2已经做完的工作, 现在趁有时间记下笔记. 1.设计 这里是指兼容3ds max导出/fbx格式转换等等一系列工作的设计. 最开始, Blade的3dsmax导出插件, 全部代码都是写在导出的DLL里面的, 后来考虑到FBX等等其他格式, 现在把模块分成两部分: Model/Anim Collector: 预定义的接口, 用于收集其他模型的相关数据. 用户负责扩展实现, 比如FBXCollector, MaxCollector, 或者其他格式. Model/Anim Bui

引擎设计跟踪 ShadowMap 细节和分析

之前在工作总汇总了shadowmap的各种问题 [工作积累] shadow map问题汇总 最近有点时间再仔细研究了shadowmap的一些算法.主要修复了LiSPSM(上面链接里后面有更新),实现了TSM和CSM阴影. 总的来说,CSM只是结构上的不同,多了拆分和几个pass,实现起来相对比较简单.LiSPSM和TSM调试至于为什么要研究LiSPSM和TSM,主要是在不能使用CSM的时候(比如低配,mobile之类),可以有更好的效果.另外,CSM和LiSPSM.TSM并不冲突,每个pass可

引擎设计跟踪(九.14.2 final) Inverse Kinematics: CCD 在Blade中的应用

因为工作忙, 好久没有记笔记了, 但是有时候发现还得翻以前的笔记去看, 所以还是尽量记下来备忘. 关于IK, 读了一些paper, 觉得之前翻译的那篇, welman的paper (http://graphics.ucsd.edu/courses/cse169_w04/welman.pdf  摘译:http://www.cnblogs.com/crazii/p/4662199.html) 非常有用, 入门必读. 入门了以后就可以结合工程来拓展了. 先贴一下CCD里面一个关节的分析: 当Pic的方

引擎设计跟踪(九.14.2f) 最近更新: OpenGL ES & tools

之前骨骼动画的IK暂时放一放, 最近在搞GLES的实现. 之前除了GLES没有实现, Android的代码移植已经完毕: [原]跨平台编程注意事项(三): window 到 android 的 移植 总的来说上次移植的改动不是很大, 主要是DLL与.so之间的调整和适配, 还有些C++标准相关的编译错误. 数据包的加载/初始化/配置文件和插件的加载测试可用了, 但GLES没有实现, 所以上次的移植只能在真机上空跑. 最近想在业余时间抽空把GLES的空白填上, 目前接口调整差不多了, GLES r

引擎设计跟踪(九.14.2i) Android GLES 3.0 完善

最近把渲染设备对应的GLES的API填上了. 主要有IRenderDevice/IShader/ITexture/IGraphicsResourceManager/IIndexBuffer/IVertexBuffer.都是体力活, 根据文档(https://www.khronos.org/opengles/sdk/docs/man3/)填上对应的API就可了.遇到的问题纪录在下面: Stick to the standard C++standard并没有要求char必须是unsignedtype

引擎设计跟踪(九.14.2d) [翻译] shader的跨平台方案之2014

Origin: http://aras-p.info/blog/2014/03/28/cross-platform-shaders-in-2014/ 简译 translation: 作者在2012年写过一篇shader跨平台的文章, 开始提到了并有链接. 1.手写或者宏替换 使用宏定义将 HLSL & GLSL 的不同之处封装, 并让每个开发人员了解他们的不同之处. 例子: Valve的Source 2引擎 优点: 简单,容易实现缺点: 每个开发者都必须熟悉使用宏定义库, 还有其他语法上的不同.

引擎设计跟踪(九.14.2b) 骨骼动画基本完成

首先贴一个介绍max的sdk和骨骼动画的文章, 虽然很早的文章, 但是很有用, 感谢前辈们的贡献: 3Ds MAX骨骼动画导出插件编写 1.Dual Quaternion 关于Dual Quaternion, 这里不做太详细的介绍了,贴出来几个链接吧: http://en.wikipedia.org/wiki/Dual_quaternion http://www.seas.upenn.edu/~ladislav/kavan08geometric/kavan08geometric.pdf http