前言
大家好,作为博客开通后的第一篇技术类博文,我决定将前不久总结的一些关于如何在移动端开放大世界中高效渲染草海的心得做一下分享,内容比较多,主要是寻找和探讨阻碍我们实现目标的一些技术问题,以及整理应对思路。
那么在开始正式分享前,大家可以先概略的了解下接下来的主要内容:
1)首先,也是比较基础的,我们得明确实现所谓的“移动端开放世界草海”会遇到哪些挑战,引出几个主要的问题点;
2)接下来,在明确问题的前提下,我会花比较多的篇幅,来和大家一起设计一套可行的方案。期间我们会讨论许多内容,诸如,如何定义一株草,如何存储信息,如何在适宜的地方偷工减料,如何安排任务,充分利用起CPU和GPU的并行能力等等。
3)紧接着,我会简单过一下接口设计,大家此时已经对渲染草海的实现原理有了基本认识,因此对接口内容也应当能更好的理解了。
4)再之后是分享的一些,在工程搭建中,个人感觉比较重要的技术细节和实现。当然,由于我自身经验的局限,所选的技术实现不一定最适合当下的应用场景,所以随时欢迎大家指正问题。
5)在分享的最后,是一个简短的Demo展示和性能比对。
问题与挑战(渲染草海的基本概念,及其主要特点)
我们要做的是 移动端的 开放世界超大地图 上的 可交互的 草海。有3个定语修饰一个名词“草海”,我觉得首要问题还是要明白草海到底是什么,然后再来给它添加新特性以满足各项要求。
真实世界草海的2个特点
听到“草海”这个词,大家能想到什么。。。就我而言,我想到了遍布山丘的牧草,连片的金黄色麦田,或者密布在岸边的芦苇。这些景象给我的一个宏观感受是一个词“连绵不绝”,是一种在空间上由近及远铺排开来的那种连绵起伏的感觉,我们换一种朴实的说法就是:草是“海量”的;另一种给我的感受也可以总结为一个词“浑然一体”,意思是在色彩感官上,草海是相对统一和规律的,而不是杂乱琐碎的,就是说构成草海的草的个体种类具有同质性。所以“海量”和“同质”是我对这类自然景观的一种概括或抽象。也是草海的两点“特质”,后续我们的许多工作都是基于这两项认知的。
数字世界草海面临的挑战
基于对现实中草海的认识,来到移动数字端,我们发现这个绘制“海量”植被需求的本身,就是主要挑战。细分一下,主要有2个方面:
第一个是:草体本身的绘制压力,主要由CPU和GPU共同承担,可以预见,草的数量越多,代表草的几何面片数量自然越多,这样从CPU读取数据,预处理,合并上传GPU,再到渲染这套通用流程走下来,总耗时就越来越大了。
另一个是:存储草海信息的压力,简言之就是如何正确的记录下每一株草的位置、朝向等独有信息,并在需要的时候高效的获得到。
我们举个例子,不妨以一张10公里见方的世界地图为例,假设每平米生长有10株草,那么光存位置信息,我们需要占用:
10^4 * 10^4 * 10 * Vector3 = 10^9 * 12 byte > 10GB
10G就算是理论上限也已经很大了,何况不止一种草要处理。
综上所述,算起来压力大,存起来存不下,面对在移动端绘制海量草的需求,这就是我们需要面对的基本问题与挑战。
面片草 vs 模型草
我们刚刚提到过,绘制大量构成草的几何形状是有压力的,如果不能从草的数量上下手,那么就只能简化模型网格了。
主流的草模型有2类,既 面片草 和 模型草。
面片草是做得比较极端的例子,在这种模式下,草的颜色和轮廓只是一张带有alpha通道的纹理,草的几何构成(或者叫Mesh)被简化为一张或若干张面片(一般是矩形的)。如左上方的示例图,运行时GPU会在这块面片底板上,将美术同学绘制的2D贴图贴合上去,通过开启透明测试(也叫Alpha Test),让贴图纹理中不是草的部分透明,留下草本体的影像,以达到在3D空间中,绘制草效果。
模型草是另一种绘制流派,与面片草最主要的区别在于如何表现草的外轮廓,后者(也就是面片草)的轮廓是由美术同学在纹理上直接绘制出来的,而前者(模型草)则主要由模型网格本身来表现植被的轮廓。网格长成什么样子,草的形态就是什么样子。运行时GPU采样纹理,一般也只是简单的渐变色块。我们之前聊过,移动端草海中草的模型不能复杂,不然GPU受不了,所以这也限制了模型草的美术表现空间,我们常见的模型草样式是如上图右侧这般的长条状柳叶形态,就是这种限制的表现。
面片草优缺点:
->优点:绘制Mesh顶点少效率高,一片面片可以代表多株草,草的样式对美术发挥空间大(因为美术可以把草的纹理绘制得很复杂,却不用增加额外的GPU运行消耗),此外一般认为面片草在绘制密度较高,且较低矮的草丛时,效果不错。
->缺点:首先是依赖透明度测试,因为一些原因,这个开销在不少移动端设备上是相当昂贵的。其次每株草都在垂直于地面的2D平面上,近处观察和俯视效果都不佳,且受制于简陋的面片Mesh,无法做出复杂的动画,影响交互体验
模型草优缺点:
->优点:3D模型的草,不论上下远近观察,效果都很稳定;可以作出较复杂,较自然的动画,交互性好;此外还有暗含的一点:可以不依赖透明度测试(或者说草模型的轮廓就是草的轮廓,无需进行透明度测试)
->缺点:相对面片草Mesh多,每株模型草,一般只能表现一根草体,想要复杂草体,就得多上更多的顶点
综上,模型和面片各自都有优缺点,很多时候需要根据美术上的实际需求来权衡;在下面一篇博文中我会介绍草海信息的储存构思,之后再谈谈我对于绘制草海的技术选型(包括模型和面片草的选取)