case1 forest
在一些大型的游戏场景中,会渲染数量庞大的内容到屏幕上,比如,一片有着成千上万棵树的森林,如果我们为每棵树都创建一份数据,然后发送给GPU 处理,就会带来严重的性能问题。如此多的数据在几毫秒之内从内存中发送给渲染程序,不仅可能会引起明显的卡顿丢帧,更是从理论上就浪费了大量的性能。原因在于,这些数量庞大的模型,其材质与几何框架几乎都是一样的,区别只在于颜色、位置、方向等属性。
因此对于树,材质和几何图形数据只需要存在一份即可,所有的树只维护自身独特的数据,而材质、几何图形都以共享的方式重复利用。这项技术在硬件层面已经得到了支持。
Fortunately, today’s graphics APIs and cards support exactly that. The details are fiddly and out of the scope of this book, but both Direct3D and OpenGL can do something called instanced rendering.
case2 ground
森林我们以这样的方式解决了,那么土地呢,土地同样也是由许许多多的小单元格组成的,与森林不同,土地包含的数据种类或许更加丰富,比如,有草地、河流、沙地等等,伴随着这些类型的不同,土地也具备不同的属性,比如行走速度,能否通过等。 如果我们使用一个矩阵将每一个坐标的瓦片保存起来,首先,内存占用会随着地图面积呈线性方式增加,其次也同时面临着上面森林一样的问题:将大量重复数据发送给渲染设备是不科学的。 预示我们再次将数据中可以共享的部分抽取出来进行复用:
这样一来,我们只需要在矩阵中的不同区域使用不同类型的对象引用来表示不同地貌。
总结
享元模式既是一种设计模式,也是一种性能优化手段。同时,性能的具体表现会受到整个系统所有部分的综合影响。