文章目录
模板缓存(stencil buffer)
是一个用于获得某种特效(special effect)的离屏(off-screen)缓存
模板缓存的分辨率(resolution)
与后台缓存(back buffer)和深度缓存(depth buffer)的分辨率完全相同。所以模板缓存
中的像素与后台缓存
和深度缓存
中的像素是一一对应
的
像素
模板缓存
允许我们动态地、有针对性地
决定是否将某个像素写入后台缓存中
模板缓存的工作原理、创建模板缓存和对模板缓存进行控制
后台缓存——深度缓存——模板缓存
1、模板缓存的使用
为了启用模板缓存
,我们必须将绘制状态D3DRS_STENCILENABLE
设为true
DirectX 9.0中增加了双面模板(two-sided stencil)
的特性
Clear方法可以对模板缓存、目标缓存(后台缓存)和深度缓存进行清空操作
在现代硬件中
使用模板缓存可被认为是没有计算开销的
运算,当然前提是您已经在使用深度缓存了
模板缓存可与深度缓存一同创建。实际上,模板缓存和深度缓存共享同一个离屏的表面缓存
,而每个像素的内存段被划分为若干部分,分别与某种特定缓存相对应
各种显卡对模板缓存的支持情况都有差别
1.1、模板测试
判定是否将某个像素
写入后台缓存的决策过程称为模板测试(stencil test)
测试结果为真时,将该像素写入后台缓存
;测试结果为假时,阻止该像素写入后台缓存
当一个像素不被写入后台缓存时,也不会被写入深度缓存
1.2、模板测试的控制
为了增加灵活性
,D3D允许我们在模板测试中对
、
、
和比较函数
进行设定
ref
的默认值为0,我们可用绘制状态D3DRS_STENCILREF
来改变该值,倾向于使用十六进制来表示
mask
用于屏蔽
和
变量中的某些位。其默认值为0xffffffff
可以使用绘制状态D3DRS_STENCILMASK
来修改
的值
value
该值时当前待测试像素在模板缓存中的对应值
我们不能显式地单独设置value,但我们可以用模板的绘制状态
控制将要写入模板缓存的内容
比较运算
可通过绘制状态D3DRS_STENCILFUNC
来设置比较运算函数。待选比较函数列表
1.3、模板缓存的更新
模板相关的绘制状态
不知道为什么需要这个东西??????
除了决定一个具体像素是否应该被写入后台缓存,我们还可以基于3种可能的情形定义模板缓存中的值如何进行更新
1.4、模板写掩码
用于屏蔽我们将写入模板缓存的任何值的某些位
可用绘制状态D3DRS_STENCILWRITEMASK
来设定写掩码的值
2、镜面效果
需要解决两个问题:
- 1、对于任意平面物体如何成像:用向量几何解决
- 2、将平面的某一有限区域标记为镜面:用模板缓存解决
2.1、成像中的数学问题
创建相对于任意平面的镜像变换矩阵
D3DXMATRIX *D3DXMatrixReflect(
D3DXMATRIX *pOut,
const D3DXPLANE *pPlane
);
要能快速写出3个常用的,相对于3个标准坐标平面的镜像变换矩阵
2.2、镜面效果实现概述
实现镜面效果时,一个物体仅当位于镜面之前时才对其进行成像计算。我们不想进行空间测试以判断某物体是否位于镜面之前,因为这样会使问题变得复杂。为了简化这个问题,无论在何处,我们都计算其成像并进行绘制,然后再使用模板缓存来进行范围限制
具体实现步骤见代码
3、平面阴影
阴影体(shadow volume)比平面阴影(planer shadow)的效果更好,但其比较复杂
我们使用模板缓存
来防止平面阴影中的二次融合现象
的出现
- 1、平行光阴影:正交投影,也称为平行投影
- 2、点光源阴影:透视投影
使用该函数来生成阴影矩阵(shadow matrix)
D3DXMATRIX *D3DXMatrixShadow(
D3DXMATRIX *pOut,
const D3DXVECTOR4 *pLight,
const D3DXPLANE *pPlane
);
具体实现和其中之细节见相关代码