Hierarchy 标签栏中,点击Create – >Tree 可以创建一个树的模型,设置自己的树木模型,这里我们先导入系统自带的树木模型,以后在讨论自定义模型的制作。
因为新建的工程中是没有树木和草地的贴图元素,可以在Unity3D 的标准资源库中导入,导入的方法和上一章介绍的一样。打开Unity3D 在Project标签栏中 鼠标右键 Import package – >Tree Creator 将标准树木资源模型导入工程。
点击Edit Textures 出现一个下拉列表
add Tree 添加一个树的模型
Edit Tree 编辑树的模型
Remove Tree删除树的模型
红框内是设置树木的一些关键重要参数
Brush Size : 画笔绘制一次树木添加数量,数值越大越多,越小则越少,取值范围0到100。
Tree Density:树之间的百分比,在一片树中间在放入量一片树就得修改这个数值了,取值范围0到100。
Color Variation:树之间颜色差的范围,取值范围0到1。
TreeHeight:树的高度,它是与场景模型有一定比例,越大树越高,取值范围0到200。
Variation:树与树之间的高度比例,取值范围0到30。
Tree Width:树的宽度,它是与场景模型有一定比例,越大树越宽,取值范围0到200。
Variation: 树与树之间的宽度比例,取值范围0到30。
有了这些参数,我们就可以创建一些更贴切的3D树的模型在场景中啦。
Tree None(Game Object) 添加树木的模型.
设置树木的模型完毕后,用鼠标在场景中点击添加树木把, 按住Shift点击鼠标可以消除之前场景中已有的树木。
画草模型:
起始它不仅能草,还能画一些自定义模型,可以处理一些零碎的小东西丰富游戏场景,如下图所示,Add Grass Texture为添加一个草的纹理图,Add Detail Mesh 添加一个自定义的模型。
Brush Size: 和上面一样,标志绘制的面积。
Opacity: 绘制的高度
Target Strength:绘制的密度。
具体绘制的方法与添加模型的方法和画树类似,这里就不贴图概述了,盆友们打开编辑器试一试就OK啦。。
看一看草绘制出来的效果
具体编辑 ,移动草,拖动,以及模型的方法和上面类似,快快构建场景中的小玩意吧。嘎嘎~~
可以百jjop度搜:编.程.回.忆.录.之.unity3d.都是从零基础开始讲解的
其他设置.
主要设置一些3D游戏地形的一些参数
一下面列出一些主要参数的介绍,盆友们可以自己拖动鼠标修改一下其中的具体数值就可以在游戏视图中清晰的看到效果。
Pixel Error:控制地形密度容差,数值越大越圆滑,越小地形角度越明显。
Base Map Dist:控制地形贴图的距离.
Case shadows: 是否显示地形阴影
Draw:是否绘制绘制场景模型,比如树,草等等。
Wind Settings 地形中风的设置
Speed:风速
Size:风的范围
Draw(是否绘制地形细节):如果取消这个选项,地形细节将全部都不显示,花草树木什么的都看不见。有时候,Unity中的场景里面,物体突然看不见了,可以这样做:
首先,在 Hierarchy 面板选择看不见的物体,按下快捷键 f。如果物体还是看不见,看看图中圈红的地方。如果,如果物体要看得见,需要图标是 “眼睛” 的图案。鼠标点击一下,如果图标已经是 “眼睛” 的图案,场景中还是看不见物体,那就要看看是不是 layer 设置的问题了。OnDrawGizmos() 画的线看不到,可能也是 右上角的 Layer 设置问题:让 Layer 设置为 Default 就可以了。
我们要求记录草海中草的位置信息是为了能够创造出一个尽可能" 确定 "和" 可控 "的世界,试想如果没有这条限制,我们不在某种程度上确切记录草的位置,那么一片草海位置信息是可以用 0 bit 的容量来记录的,毕竟只要写个随机函数,让草自己随地扎根就行了,不用浪费空间存储每一株草在哪里。然而我相信大多数项目中,策划和场景美术同学应该不同意这么干,他们会希望能精确绘制出地表植被的分布,规定哪儿有草,哪儿没有,甚至在哪里必须放上几株并设置好朝向等等。
可是,另一方面,想要 精确存储每一株草的位置信息似乎是一件不可能的事情 ,至少看起来很不划算。这点刚才已经算过,一个10公里的地形,每平方只种10根草,只记录位置一个信息,就要消耗掉数十GB的磁盘空间,更别提金贵的内存了。
余下能做的事情就是找出一种折中的办法来调和这对矛盾。这边我给出一种比较常用的解决思路:对于那些注定会成为草海的草(草海的主体),策划和美术同学放弃对每一株草的精确控制,转而控制一小块面积内草的各项属性。如果设置合理,我们能很轻易的降低整体信息量1到2个数量级,同时也能保持全局的草海分布趋势,达到效果和设备的平衡。按照这种思路,很自然的,我们想到使 用密度来表示一个单位面积的地皮上有多少草 ,这样原本需要记录的数值,已经不再是单株草的坐标了,而是这整块地皮的中心点坐标,以及地皮上草的密度值。
这种将单位地皮作为整体打包记录密度的做法,使我们就把原来10 ~ 100株草的数据量一下子压缩到了1株的数据量,当然这个密度转化的过程中是有信息丢失的,我们 丢失了单位面积内100株草的局部偏移信息 。这是一个问题,但也是一个相对容易处理的问题,比如我们可以赋予每株草一个单位面积内随机的偏移来补全/伪造因合并而丢失的信息,亦或者由美术同学直接指定这一平米面积内草的分布,规定他们的位置和朝向。更妙的是,借由密度化地块这个过程,我们其实也 离散化 了整个世界,现在的世界地图(至少密度地图)对我们来说是一个一个平铺开来的,拥有固定尺寸的单元格,为方便计量,不妨预设单元格尺寸是1米,这样密度的单位也就变成了"N株草每平方米"。离散化的好处有很多,之后会细讲,其中主要的一点是我们从此可以丢掉浮点数,专注于整型的计算和存储了,而且一些数据结构的运用也会变得更加高效。
一般而言草海的分布是具有连续性的,打个比方,只要不是草海的边缘,一块地皮的密度与它四周8块领域地块各自的密度有很大概率是相等的,这说明在不丢失信息量的前提下,还有压缩密度图的空间,所以不论是把密度图存成纹理格式,在编码成某种形式的图片,还是将密度图在平面上切分,编入四叉树结构,都能再次大幅降低草海信息的体积。
最后对于那些确实有需要精确到位置和朝向的植被,我们不妨将之梳理出来,再开个小灶。只要这部分需求的总量不大,就不会造成实质上的问题。之于如何开小灶,我想方法也有很多,比如我们可以针对这些特殊植被再生成一张密度图来渲染,只不过这次密度单位不是1米,而是0.1米或更小,只要特殊植被数量不多,这些密度图经过压缩后也挤占不了多少空间。
好了,到目前为止我们了解了渲染草海的基本特点,面对的挑战,以及一些重要概念和方案。是时候明确下基本技术选型了。
首先是草的几何表现形式,这里选择了 模型草 作为开发的基准。从技术实现角度出发,模型和面片草对程序来说区别其实不大,更多的是美术工作流的变化,以及视觉效果的转变。考虑到移动端对透明度测试的优化问题,以及植被与玩家交互作用的表现力等方面,暂时选择了模型草作为开发的基础,当然添加对面片草的支持相当容易,如果有需求的话,后续追加也不迟。
然后承接刚才密度的方案,我们需要将美术同学在世界空间中刷出来的草海, 以密度块为基本单元,存入某种数据结构中压缩起来 。这边选择支持简单的二维纹理编码(可以理解为压缩成图片),同时也支持四叉树编码密度,做四叉树这部分主要是基于个人兴趣,想尝试下构建一套快速范围搜索的算法,当然四叉树也是有别的好处的,之前也讲过,在内存中,四叉树理论上会比解压后的纹理密度图占用更少的体积。那么对于密度变化不复杂的地区,选用四叉树编码,就可能节约数兆字节的内存。
接下来是越来越为人所知的一个术语: GPU Instance 。 还记得我们在开篇研究了草海的基本特点么?它具有“海量”和“同质”的特点。而GPU Instance 可以理解为一般图像引擎会提供的一套接口组件,专门用来处理符合“同质”特点的“海量” 实例。处理时,我们只使用一套几何构造作为所有实例的标准“模板”,然后CPU会告知GPU:“需要复制多少份这样的模板,这些模板最后放置在哪儿”等很少的信息,余下的活就交给GPU去处理了。如此一来,虽然GPU的活没少干,但是CPU解放了,自然能提升不少性能。
规范得说,我们可以通过调用了基于 GPU Instance 技术的 DrawMeshInstancedIndirect(...)接口来消减CPU管理Mesh个数,同时也降低了和GPU之间的IO负载,提高Batch数。如果有的同学不理解,也不用担心,后续我们也还会结合示例来详细阐述。而且这些内容在Unity官方文档上都有详细介绍,有兴趣的同学可以去读一读。
此外还值得一提的是,我们选择了面向移动端的 URP 渲染管线,因为其底层的一些优化,特别是 srpBatch 可能会对降低开放世界整体的 DrawCall 消耗有所帮助,这里就不做展开了。
好了,今天我们先到这里,做一个总结:草海位置信息很多很头疼,我们选择用密度块方式,通过四叉树编码后存放起来;然后针对表现层面的需求,我们使用Mesh面数较高的模型草作为草海的主要载体;最后提了一点 GPU Instance 的信息。接下来的文章会进入所谓“绘制草海”的主要环节,即算法逻辑的实现。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)