第8章 模板

版权声明:转载请注明出处 https://blog.csdn.net/weixin_39918693/article/details/88722226

模板缓存(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)

( r e f   &   m a s k )   C o m p a r i s o n O p e r a t i o n   ( v a l u e   &   m a s k ) (ref\ \&\ mask)\ ComparisonOperation\ (value\ \&\ mask)

测试结果为真时,将该像素写入后台缓存;测试结果为假时,阻止该像素写入后台缓存

当一个像素不被写入后台缓存时,也不会被写入深度缓存

1.2、模板测试的控制

为了增加灵活性,D3D允许我们在模板测试中对 r e f ref m a s k mask v a l u e value 比较函数进行设定

ref

r e f ref 的默认值为0,我们可用绘制状态D3DRS_STENCILREF来改变该值,倾向于使用十六进制来表示

mask

m a s k mask 用于屏蔽 r e f ref v a l u e value 变量中的某些位。其默认值为0xffffffff

可以使用绘制状态D3DRS_STENCILMASK来修改 m a s k mask 的值

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
);

具体实现和其中之细节见相关代码

猜你喜欢

转载自blog.csdn.net/weixin_39918693/article/details/88722226
今日推荐