Realtime Grass Rendering on Mobile Platform| 移动端实时草地渲染

有很多很多不同的技术了。

题图是一个人的demo,Real-Time Grass Rendering,跟我没啥关系

要渲草的话,OpenGL ES2.0/DX9及以下就不用考虑了。至少要支持GPU Instancing,有Compute Shader更好。

理想平台:OpenGL ES3.1/Metal/Vulkan

1. Rendering Countless Blades of Waving Grass

GPU Gem上的文章,链接在这里

主要思路:

1. 贴图

一张alpha-test的贴图

2. 插片
3. 风

为了避免变形扭曲和减少drawcall,定点要记录每个草的中心位置,根据中心位置做随机偏移

主要意义在于提出了草插片,不过其他都没啥考虑。

 

2. Rendering Grass in Real Time with Dynamic Lighting

2006年SIGGRAPH的文章,戳这里

主要思路如下:

1. LOD

第一级是几何体草,第二级是插片草,第三级是平面图

第一级草就是实时生成的,8个面,alpha-test的贴图

中距离是插片,用了一个bidirectional texture funtion,定义了五个灯光和两个视角方向的贴图,中间的插值spherical barycentric

2. 密度

用了一张density-map

3. 阴影

近距离的用shadowmap太费了, 所以预先烘焙了一张occluder,每个草旁边一个圆柱体,用光线去采样

思路上可以借鉴的:
  • LOD
  • 插片BTF
  • density map的思想
没啥意义的:
  • alphatest草,mobile上毕竟太费了
  • 实时投影计算,预先计算的话也太耗了,128*128的occuluder话,单通道一张图ETC5压缩,2kb,10k草就是20mb啊,而且drawcall没法batch

3. Rendering Fields of Grass using DirectX11 in GRID Autosport (RFGinAutosport)

2014年的游戏,PS3/XBox 360平台。

主要要点如下:

1. 密度与颜色控制

美术制作densitymap,rgb记录颜色,alpha记录高度。整个地图一张2k

2. 位置生成

主相机上方架一个垂直向下正交的相机拍地面,渲RenderTexture,用这张RT,Compute Shader取每个像素作为草的底坐标。当然会做一些随机,根据相机视野做一下裁剪。还会生成LOD。

Compute Shader输出草信息的struct到一个AppendStructuredBuffer。这个buffer交给shader,用instanceID取信息。一个trick是drawindirect时候,避免高instance低顶点数,CPU里调相当于unity的DrawProcedurallyIndirect渲染

3. 几何信息

hardcode进vertexshader的(为什么不是geom-shader呢?)

4. 阴影

screen-space shadow去采样投影,一个instance一个投影,不考虑一棵草被部分投影了

5. 变形

车轮轧过应该草高度会降低,变形方法是:渲一个F32高度图,每帧更新车轮位置,然后放进生成阶段,compute shader里计算高度

优点:
  • 没有alpha-test,mobile上可以考虑
  • 美术流程完整
  • 裁剪和LOD非常有新意
缺点:
  • 没啥,这个笔者基本在unity移动端能复现
  • 没考虑地形起伏,笔者经验是要做高度差值
  • 顶视相机连续移动的话,采样率高于densitymap分辨率,单草还好,如果两个densitymap混合 一个草一个石头 就会抖动

4. ADAM

Unity官方demo,asset store有下载

和RFGinAutosports比较相似
  1. 直接用的unity terrain系统,不过terrian分成了一个个patch,每次会渲染主相机周边一些patch上的草,没有扇面裁剪
  2. densitymap之类的是写进terrain的control map的,有意思的是每层数据可能就2-4位,用mask编码到16位里
  3. 和RFGinAutosports一样,用compute shader生成草的位置信息
  4. 不过不是渲染草blade,而是AlphaToMask的插片草,不用geom shader
优点:
  • density-map采样比较稳定,因为直接是按patch了
  • control-map用掩码编码成16位的方式比较有意思
  • 美术流程比较完整
缺点:
  • 没考虑移动端,alpha-test会挂

5. 利用GPU实现无尽草地的实时渲染

知乎上的文章

1. LOD

三级LOD按面数分,hardcode进geom shader

2. 贴图

AlphaToMask贴图

3. 位置生成

CPU按mesh顶点生成草位置

4. 风

正弦顶点运动,高度相关

优点:
  • 考虑了LOD,但这个lod基本没啥用
缺点
  • 其实只有渲染用了gpu,位置生成没用gpu
  • alphatest在移动平台不太能接受
  • 没考虑美术流程
  • 只是花拳绣腿没啥用

6. Zelda

很厉害就是了,不知道怎么做的

7.  自己的实践

  1. terrain系统自带detail数据,这样就可以直接美术刷density,渲染时候再换成其它mesh
  2. 直接用低模型草。另外两种方法呢,alpha-test移动端比较费,要不hardcode进vertex/geom shader美术又不好控制
  3. 地形有起伏的话,高度要插值。如果compute shader插得话,bilinear interpolation就有很好的效果了。
  4. 我的经验是,就算是用5.5,没有compute shader,A9上也完全无压力。

参考文献:

Rendering Grass in Real Time with Dynamic Lighting

Rendering Countless Blades of Waving Grass

Rendering Fields of Grass using DirectX11 in GRID Autosport

利用GPU实现无尽草地的实时渲染

发表评论

电子邮件地址不会被公开。 必填项已用*标注