链接 http://blog.csdn.net/xuxinhua/article/details/6853244
什么是模板缓冲(Stencil Buffer)
模板缓冲类似于深度缓冲。事实上,它使用深度缓冲的一部分(因此,深度缓冲常常被称做depth-stencil缓冲)。深度缓冲让程序员可以设置一个模板函数测试"reference(参考)"模板值-一个全局值 – 每次当这个值仍然在模板缓冲时像素才会被绘制。
模板测试的结果决定了像素的颜色值是否要被写入到渲染目标,像素的深度值是否要被写入深度缓冲。
例如,当参考模板值为0时将一些物体绘制到场景中,而此时模板缓冲已经清除为1,那么当绘制这些物体时模板缓冲就会为0。如果接着将参考值设置为1,而且StencilFunction设置为 CompareFunction.LessEqual,那么只有那些模板值不为0的对应区域的像素会被绘制。这是使用模板缓冲创建一个限制当前绘制区域的基本用法。
模板缓冲还有许多更高级的用法。指定StencilOperations除了可以进行替换或抛弃操作,还可以在每次模板测试后减少或增加模板缓冲,这可以和StencilMask值组合起来保证模板测试只作用在模板缓冲的一部分区域上。
要使用模板缓冲,DepthFormat必须保留一些字节用于模板缓冲。DepthFormat.Depth24Stencil8深度格式使用了8位用于一个模板缓冲。当你将这个格式与RenderState.StencilMask属性组合起来时,它可以提供8个不同的模板缓冲。Depth24Stencil4 深度格式使用4位用于模板缓冲,而DepthFormat.Depth15Stencil1格式只允许1位。可以将ClearOptions.StencilBuffer传递到GraphicsDevice.Clear方法单独清除模板缓冲。
你可以使用DepthStencilBuffer类创建自己的depth-stencil缓冲。当创建一个自定义渲染目标时你需要创建自己的depth-stencil缓冲。
深度缓冲是一个与你的渲染目标(render target)相同大小的缓冲,这个缓冲记录每个像素的深度。
当一个像素第二次被绘制时– 例如当一个物体在另一个物体之后被绘制- 深度缓冲要么保留前面的深度值,要么使用第二个像素的深度值替换当前深度值。那个深度保留哪个深度抛弃取决于你选择的深度函数。例如,如果当前深度函数是CompareFunction.LessEqual时,只有小于等于当前深度值的值才会被保留,而大于当前深度值的值会被抛弃。这叫做深度测试,每次绘制像素时都会进行深度测试。当对一个像素进行深度测试时,它的颜色会被写入渲染目标,而深度被写入深度缓冲。
像素的深度值是由视矩阵和投影矩阵决定的。在近裁平面上的像素深度值为0,在远裁平面上的像素的深度值为1。场景中的每个对象都需进行绘制,通常最靠近相机的像素会被保留,这些对象阻挡了在它们后面的对象的可见性。
深度缓冲通常还包含stencil bits – 所以深度缓冲又被叫做depth-stencil缓冲。深度格式(depth format)表示深度缓冲的构造。深度缓冲总是32 bits,但可以用不同的方式组合,类似于纹理格式。常用的深度格式是Depth32,这种格式中32 bits都用来存储深度信息。另一个常用格式是DepthFormat.Depth24Stencil8,这种格式中24 bits用于深度计算而8 bits用于模版缓冲(stencil buffer)。DepthFormat.Depth24Stencil8Single不常用,这种格式使用24 bits以浮点数计算深度缓冲。在PresentationParameters中使用AutoDepthStencilFormat属性可以设置默认深度格式。
使用RenderState.DepthBufferEnable可以打开或关闭深度缓冲。使用 RenderState.DepthBufferFunction可以改变用于深度测试的比较函数。将ClearOptions.DepthBuffer传递给GraphicsDevice.Clear方法可以清楚深度缓冲。使用 DepthStencilBuffer类可以创建自己的深度缓冲。可见示例How To: Create a Depth Texture 学习如何创建一个自定义DepthStencilBuffer。