D3D之多重采样

24 篇文章 0 订阅
9 篇文章 1 订阅

1 多采样 (抗锯齿)
       
全景抗混叠是一种减少在渲染多边形的边时所产生的参差不齐效果的方法。抗混叠物体也会对渲染后的整个场景产生负面影响,尤其是处理动画更是如此。通过实现对像素的本地模糊处理,并在屏幕上显示出一个平均结果而实现全景抗混叠。

 在Direct3D中启用多采样将实现程序中的抗混叠。多采样将对程序性能的影响很大。这种性能影响取决于所选的样本数,所以在考虑更多的样本数时,一定要牢记这一点。采样数越高,渲染的场景质量就越好。样本最大数取决于支持它的硬件。某些硬件根本不支持多采样,而有一些硬件也许可以支持多大4倍速率的采样,还有一些可以支持8倍速率或更高的采样率。在Direct3D 9.0中,多采样类型包含了D3DMULTISAMPLE_NONE、D3DMULTISAMPLE_NONMASKABLE、D3DMULTISAMPLE_2_SAMPLES以及D3DMULTISAMPLE_16_SAMPLES。默认情况下使用D3DMULTISAMPLE_NONE,这意味着并不使用任何类型的多采样。使用D3DMULTISAMPLE_2_SAMPLES和D3DMULTISAMPLE_16_SAMPLES或它们之间任意其他采样都会让Direct3D知道在对场景多采样时使用的样本数。

现在的问题是如何才能确定硬件支持哪种类型的多采样?调用CheckDeviceMultiSampleType()函数即可得到该问题的答案。该函数将确定是否支持某种采样类型直到最少采样类型循环,从而了解硬件支持哪些多采样类型,或不支持哪些多采样类型。然后利用该信息让用户选择想要用的多采样类型,或选择想要使用它们的最佳选项。在许多游戏中,通过选择界面就可以对此做出选择。程序清单6.1给出了CheckDeviceMultiSampleType()的函数原型。

复制代码
HRESULT CheckDeviceMultiSampleType(
UINT Adapter,
// 正在使用的显卡
D3DDEVTYPE DeviceType, // 将要创建的设备类型
D3DFORMAT SurfaceFormat, // 正在使用的渲染格式
BOOL Windowed, // 确定是否为全屏模式的标识符
D3DMULTISAMPLE_TYPE MultiSampleType, // 要查看的多采样类型
DWORD* pQualityLevels // 存储由MultiSampleType参数多采样类型支持的质量等级最大数的变量
);
复制代码

  CheckDeviceMultiSampleType()函数的参数包括正在使用的显卡、将要创建的设备类型、正在使用的渲染格式、确定是否为全屏模式的标识符、要查看的多采样类型以及存储由MultiSampleType参数多采样类型支持的质量等级最大数的变量。如果支持查看的多采样类型,该函数就返回D3D_OK。一旦确定想要使用的多采样类型,就可以在现有的参数对象中启用该多采样类型。到目前为止,本书只是设定了现有参数结构中的几个成员变量,并忽略了与多采样相关的成员变量。与多采样相关的成员变量分别是MultiSampleType和MultiSampleQuality。成员变量MultiSampleType的值可以设为D3DMULTISAMPLE_2_SAMPLES、D3DMULTISAMPLE_4_SAMPLES等。如果成员变量MultiSampleType的值设为D3DMULTISAMPLE_NONMASKABLE,就必须设定成员变量MultiSampleQuality的质量等级值。如果在设备启用程序的多采样功能之前想要让现有参数对象的采样类型参数MultiSampleType的变量值设为D3DMULTISAMPLE_NONMASKABLE,那么就只能使用成员变量MultiSampleQuality。

程序例子,只是改了初始D3D那部分的代码:

复制代码
bool InitializeD3D(HWND hWnd, bool fullscreen)
{
D3DDISPLAYMODE displayMode;

// Create the D3D object.
g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
if(g_D3D == NULL) return false;

// Get the desktop display mode.
if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))
return false;

// Set up the structure used to create the D3DDevice
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(
&d3dpp, sizeof(d3dpp));

// Default to none.
// 默认不使用多采样
D3DMULTISAMPLE_TYPE multiType = D3DMULTISAMPLE_NONE;

// Check if 4x AA is supported, if so use it.
// 检查是否支持4倍速率采样
if(g_D3D->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, displayMode.Format,
!fullscreen,
D3DMULTISAMPLE_4_SAMPLES,
NULL)
== D3D_OK)
{
// 保存多采样类型
multiType = D3DMULTISAMPLE_4_SAMPLES;
}

if(fullscreen)
{
d3dpp.Windowed
= FALSE;
d3dpp.BackBufferWidth
= WINDOW_WIDTH;
d3dpp.BackBufferHeight
= WINDOW_HEIGHT;
}
else
d3dpp.Windowed
= TRUE;
d3dpp.SwapEffect
= D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat
= displayMode.Format;
d3dpp.MultiSampleType
= multiType; // 这里应用该多采样类型

// Create the D3DDevice
if(FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING
|
D3DCREATE_PUREDEVICE,
&d3dpp, &g_D3DDevice))) return false;

// Initialize any objects we will be displaying.
if(!InitializeObjects()) return false;

return true;
}
复制代码

  

演示程序将测试硬件是否支持4倍速率采样。如果支持,那么就是当前参数中使用的内容。由于本书没有使用D3DMULTISAMPLE_NONMASKABLE,因此不需要设置当前参数的MultiSampleQuality。运行该演示程序就会看到场景中正在旋转的三角形的很大差异。这里没有参差不齐的边,而且总体质量得到了改善。



用像素距阵表示图像时往往会出现块状效应(blicky-looking)
多重采样技术(
multisampling)便是一项用于平滑块状图像的技术;
对表面进行多重采样常用于全屏反走样(full-screen antialiasing);


D3DMULTISAMPLE_TYPE
枚举类型包含了一系列常量;用来表示对表面进行多重采样的级别。这些值包括:

l         D3DMULTISAMPLE_NONE 禁用多重采样

l         D3DMULTISAMPLE_1_SAMPLE ...D3DMULTISAMPLE_16_SAMPLE 指定了16级的多重采样;

 

请大家先记得这个参数:D3DMULTISAMPLE_NONE,它在D3D初始化的过程中常用到,

如下代码段所示:

D3DPRESENT_PARAMETERS d3dpp;

ZeroMemory(&d3dpp,sizeof(D3DPRESENT_PARAMETERS));

其中的一个选项

d3dpp.MultiSampleType=D3DMULTISAMPLE_NONE;

我们常用D3DMULTISAMPLE_NONE表示我们禁用多重采样技术;

为什么要禁用多重采样呢?

这是因为该技术会显著降低程序的运行速度。

如果你希望采用多重采样技术,
请务必使用IDriect3D9::CheckDeviceMultiSampleType
方法来检查您的图形设备是否支持你所希望采用的多重采样类型,
并验证由该类型的多重采样得到的图形质量水平是否理想。




多重采样与dx11检查硬件多重采样能力的API

由于显示器是由离散的栅格组成的,所以在显示图形时候就会有“锯齿”产生。为了解决这个问题,人们想到了一个方法去“反走样(anti-aliasing)”。它叫“超级采样(supersampling)”,工作方式就如它的名字蕴含的一样,需要"超级"的能力才能工作的很好.当用这种技术时候,"后备缓冲(back buffer)"和"深度缓冲(depth buffer)"的大小被设定为屏幕分辨率的X倍.然后3D场景就渲染到后备缓冲,当要把后备缓冲的内容显示到屏幕上时,后备缓冲中的像素会进行混合操作,比如X个像素混合为一个像素的颜色.这种方法比较暴力,所以是比较吃硬件的.由于使用超级采样的代价比较大,Direct3D支持一种类似的技术叫做“多重采样(multisamping)”.它的思路很超级采样基本一样,但是工作方式是这样的:比如我们用4倍多重采样,同样后被缓冲和深度缓冲是屏幕分辨率的四倍,但是这个时候,不再是计算每一个像素,而是只计算一个像素,要计算的像素位于4个像素点的中心,这4个像素的颜色信息共享这个中间计算出来的像素的信息.ms比ss"高效"的一点就是他把原本要进行4次的像素信息计算降低到一次.当然有得必有失,ms没有ss那么精准.

在dx11中,可以使用ID3D11Device::CheckMultiSampleQualityLevels(...)去查询硬件的多重采样能力.

来段示例:

复制代码
1 UINT msaaQuality;
2 HR(pD3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &msaaQuality));
3 assert(msaaQuality > 0);
复制代码

由于quality这个指标不同硬件厂商会有细微差别,同时quality跟我们的期待采样数和纹理(texture)的格式有关.其实我们真正关注的是是否支持我们期望的采样数,示例中是4.


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值