两年前第一次下载speed tree demo运行时,立刻被精美的画面所震撼,场景中大片的树木尤其吸引我的眼球,speed tree使用何种技术来渲染大范围的植物一直令我不解。因为在很多游戏中对树木的渲染都可以很明显地看到多边形的痕迹,而在speed tree中你几乎看不到任何破绽,繁茂的树叶、精确的光照、shadow、self-shadow,这些元素构造起了一个完美的树木。 直到前几个月无意中玩完美世界时发现它使用了speed tree来渲染树木,由于洪恩丑陋的美工得以使我发现了其中的端倪。我立刻又拿起以前下载的demo仔细研究了几天,终于发现speed tree是如何渲染树木,下面就自己的看法和大家探讨一下。 1 植物模型 支干是指树木上较细的枝干,在真实的树木上枝干是非常多的,如果使用mesh来对这一部分建模,那么渲染的负担是非常可观的,因此对这一部分speed tree使用了一个简化模型,每一个支干由两个quad mesh构成,这两个quad形成一个V字型,然后将支干的贴图渲染到quad上,通常情况下支干的主枝位于两个quad的接缝处,这样做完alpha blend后会是一个V型的立体模型,不仔细观察很难发现这只是有一张纹理产生的支干。 对于树木的树叶speed tree处理起来更加简单,就是一个billboard加上树叶的纹理,这样大量渲染时负担也不是太重。 2 光照 3 阴影 4 优化 (1)对超过一定距离的树木使用billboard渲染,这种技术也被称为impostoring(替换体)技术,这在现在的游戏使用非常普遍,很多游戏对树木这样的物体都是使用一张预先作好的树木贴图,这样做的后果是看起来非常不真实(如涂鸦的引擎),在speed tree也是预先做好的贴图,但是使用的时候添加了过度的细节,最远的时候是一张贴图,随着距离的拉近在贴图的位置开始出现主干的mesh,接着是支干,接下来逐渐出现树叶,这时候树叶的billboard会比较大,随着距离接近开始变小,随着树叶增加billboard贴图开始消失。一个有趣的现象是speed tree使用了称为bumped billboard技术,也就是给billboard贴图附加了一个normal map,这样在billboard随着视角发生旋转时表面的光照也会出现变化。实际上也可以通过使用RTT技术直接将树木渲染到纹理上作为billboard的贴图,在far cry就是这样做的,由于是隔帧计算因此渲染负担也不是太重。 (2)限制场景中树木的种类,并且保证同一树种使用相同的方位。在speed tree的demo中可以看到同一场景中出现的树种也不过四五种,而且同一树种的方位和大小都是一样的。这样做的好处显而易见,可以避免过多的转换renderer的状态,如果同一树种的方位和大小相同,那么相应的lighting和shadow都是一样的,(只存在porjective shadow map的差别,可以将这一部分另开一个pass单独进行渲染),在sun position不变的情况下只需要计算一次,这样对树木分组渲染时几乎可以将batch装满(在现在的GPU上batch中顶点的最佳数量应当在16000左右,一般情况下树木主干的顶点不过200多,这样一个batch可以差不多渲染80棵树木,这样的效率是惊人的)。 (3)对于mesh做LOD这应当不需要再讨论了。 其他话题: speed tree还有一个令人感兴趣的地方是它的地形引擎,使用了细节纹理和静态lightmap,有趣的是它的lod,竟然只有两级LOD,有点象geomipmap,又存在不同,而且好象在terrain mesh下面还有一层细节较低的mesh,有点象cry engine的做法,但是具体的原因我不是太清楚。不过它的地形引擎的效率并不是太好,主要是同时渲染了太多的顶点,而且它的OC效果并不明显,在wireframe模式下看不出有哪些地方被剔除。 最后提供一张speed tree demo的截图,这张截图有些特殊,是我将树木纹理中alpha通道删除后得到的,可以非常清楚地看到speed tree中一个树木的模型到底是什么样,呵呵,非常有意思。 |
-
2006-09-15