作者:clayman
仅供个人学习使用,请勿转载,勿用于任何商业用途。
由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。
Blog:http://blog.csdn.net/soilwork
clayman_joe@yahoo.com.cn
虽然内容有所变动,但我的xna教程还会继续^_^
本文图片和部分文字来自XNA Diaries,参考了其中两篇关于sprite alpha blend的文章
SpriteBatch.begin
通过接受几个参数,来控制如何渲染
sprite
。参数
BlendMode
表示进行哪种模式的混合。
Xna
只提供了三种,也是最常见的混合模式:AlphaBlend
、
Additive
以及
InverseColor
。这里,我们主要讨论
AlphaBlend
。
AlphaBlend
根据当前
sprite alpha
通道中的值,对
sprite
颜色和帧缓冲中已存在的颜色进行混合。计算的公式为
finalColor = spriteColor * alpha + backgroundColor * alpha
。由于要查询缓冲中的当前颜色,因此,
alpha
混合是一个相对较昂贵的操作。
单有
SpriteBlendMode
并不能完全达到我们所希望的效果,当绘制多个图形时,还需按照一定的顺序绘制
sprite
才行。
上面这张图片掩饰了
5
个半透明的环,按照不同顺序绘制时,所得到的结果,其中,后者是我们所期望的效果。左图中,我们最先绘制了中间的圆形,因此,它将和蓝色的背景混合,导致最终的效果有一条蓝边。而右图中,我们最后才绘制中央的圆形。
有两种方法来控制
sprite
绘制顺序。第一种,使用
SpriteBatch.Draw
带
depth
参数的重载,让计算机在绘制图形时根据
depth
值,为我们排序;第二种则是在我们自己编写代码来控制。
当场景中有大量
sprite
时,第一种方法是不错的解决方案。为每个
sprite
都指定一个
depth
,当物体移动时,简单的改变它的深度,就能获得正确的效果,比如
2D
游戏中,让玩家从树后移动到树前。使用
SpriteBatch.begin
的
sortMode
参数来指定从后到前,还是从前到后排序,通常情况下我们选择前者。
另一种方法,侧需要我们自己安排绘图顺序,比如先绘制背景,然后游戏对象,接下来再绘制前方的遮挡物,
UI
等等。当大量物体相互遮挡时,决定绘图顺序的逻辑可能会很复杂。但是,当场景不太复杂时,这是一种很高效的方法。
到这里,就需要讨论一下几种混合模式下的效率:
Y
轴表示帧速率,
X
轴表示
sprite
数量
图中,红色是
SpriteBlendMode.None
,绿色是
SpriteBlendMode.AlphaBlend
,蓝色是
AlphaBlend
以及
SpriteSortOptions.BackToFront
,灰色是
SpriteSortOptions.FrontToBack
。
可以看到,如果自己排序,那么在有大量(
>500
)个
sprite
的时候,能获得相当不错的收益(当然,这里并未考虑我们手动排序的代价)。
而如果使用
SpriteBatch
来进行排序,那么
sprite
数量最好不要超过
400
个。当然,如果不使用
alpha
混合,效率又会提高很多。
当然,也许你还注意到了
SpriteSortOptions.FrontToBack
状态下性能异常的好,但不幸的是,这种方法通常不能创建正确的效果。