有很多很多不同的技术了。
题图是一个人的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有下载
- 直接用的unity terrain系统,不过terrian分成了一个个patch,每次会渲染主相机周边一些patch上的草,没有扇面裁剪
- densitymap之类的是写进terrain的control map的,有意思的是每层数据可能就2-4位,用mask编码到16位里
- 和RFGinAutosports一样,用compute shader生成草的位置信息
- 不过不是渲染草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. 自己的实践
- terrain系统自带detail数据,这样就可以直接美术刷density,渲染时候再换成其它mesh
- 直接用低模型草。另外两种方法呢,alpha-test移动端比较费,要不hardcode进vertex/geom shader美术又不好控制
- 地形有起伏的话,高度要插值。如果compute shader插得话,bilinear interpolation就有很好的效果了。
- 我的经验是,就算是用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
