1.1 场景管理
把要绘制的元素分层,一层一层的绘制,每一层共享一些共有的属性,比如一排树,一块草丛
1.1.1 种植栅格
围绕摄像机,设定一个固定大小的栅格,这个值可以变化,然后每个栅格单元存储了要绘制的数据,比如顶点,材质等,随着摄像机的移动,动态的增加删除栅格单元,这个过程是动态的,所以数据要动态的解压,以保证在摄像机移动之前,数据就已经填充到了潜在的栅格单元当中。
1.1.2 种植策略
我们通过单元格中的数据,可以判断当前单元是否可以种植我们想要种植的元素,比如斜坡太抖的地方不能种植树木,所以在种植之前,我们就舍弃那些不能种植选择元素的单元,然后根据密度,向每个单元格发送射线。
1.2 草丛
首先不可能绘制草丛的每一片叶子,最简单的方法是绘制一个附有草丛纹理的方片,也叫公告板,实时的面向摄像机,我们的目的就是尽可能的少调用绘制API,然后每一个批次(batch)中绘制尽可能多的草,每一个公告板由四个顶点和6个索引组成,一个栅格单元可能有很多个公告板,为了这些草丛更有层次,在顶点着色器中,对公告板的顶点位置进行偏移,在x y 方向上随机偏移[-1,1]的值。然后这些顶点数据加载到显存中,每个栅格单元中的元素,调用一次绘制API。
1.2.1 通过溶解(disovle)模拟alpha 透明
为了表现草丛之间的透明关系,有三种种方法,一种是alpha混合,一种是alpha测试,一种是二者结合,草丛的alpha通道我们用一张噪声RT 来随机表示。
因为alpha 混合需要写入缓存,而且需要进行排序,性能不好,而alpha测试,不用排序,只是简单的比较,但是这个alpha测试的值,一般是根据栅格单元到摄像机的距离进行线性插值,为每个栅格单元选择不同的alpha测试的值,哪些距离摄像机很近的公告板,可以开启alpha混合,来达到羽化草丛边缘的效果,因为简单alpha测试,产生的边缘非常生硬,这也不可避免的增加了一些性能。
1.2.2 变化
为了让渲染的草丛附有层次感,可以为每个单元格使用一张大的草从纹理,里面包含多种草丛,然后在顶点着色器中,对顶点uv进行偏移,而且每个顶点还可以带有不同的颜色信息,绘制出不同颜色不同种类的草丛。
1.2.3 光照
为了使草丛和地面一样受光照的影响,可以在绘制草丛的时候,把地形的法线传入草丛的顶点数据当中
1.2.4 风
当风作用于草丛上时,我们对草丛上面的两个顶点进行偏移,技巧就是给上面的两个顶点添加一个权重1,为下面两个顶点添加权重为0,这样分别乘以一个风的系数,就能达到上面动下面不动的结果,为了让草丛运动的更平滑,我们给一个正弦曲线。类似于水平面。
1.3 地面杂物层
地面的杂物层和草丛的绘制一样,也是分层,在每个单元格中会分为好几个组,每个组都有相同的纹理和着色器,然后在同一个批次中绘制它们。
1.4 树木
树的主干和主要分支要建模来表示,而树叶可以用和草丛一样的方式,采用公告板的方式,同时一些小的树干,也可以使用公告板,并且最好使用LOD技术,在距离远的地方,使用较大的公告板,然后纹理上有很多小的树叶。最好多棵树的树叶的纹理都是一样的,这样就可以在同一个批次中绘制它们。
1.5 阴影
草丛的阴影是在绘制草丛的时候就已经决定了顶点的颜色,方法就是从单元格上个采样多个点向光源投射射线,如果射线有遮挡,证明该草丛在阴影当中,采样点越多,阴影越准确,然后在阴影过渡地带差值,形成阴影的模糊地带,当射线投射经过树的时候,可以采取近似遮挡的方法,把整个树干或者大的公告板当成一个遮挡物,而不是精确的计算每一个树叶的遮挡,这个真实的渲染肉眼看不出区别。
这对静态的场景和一些光源移动比较缓慢的场景很有用,或者离线把光照信息烘焙到光照贴图中,对light map采样。
1.6 后处理
使用RT 对屏幕的局部或者整体进行一个整体效果的调整