您的位置:首页 > 其它

DirectX11 深度模板视图(depth-stencil)

2015-09-24 13:19 351 查看

深度模板视图(depth/stencil)

1. 什么是深度测试?

深度测试, 如我们再第二章所主意的那样,用于确保物体表面以正确的顺序来绘制和显示,而不需要进行多边形排序。 例如,如果我们有两个三角形,它们有相同的 X 和 Y 坐标,但是在 Z 轴上相差 100 个单位,那么这两个三角形并没有接触或重复,如果我们先绘制较近的三角形再绘制较远的那个,则较远的那个三角形的颜色数据将会覆盖较近靠近照相机的那个三角形的颜色数据。 这一般不是我们想要的结果,如果我们想正确绘制这些三角形,即较近的三角形比较远的三角形显示得更靠前,则我们必须花费一些性能开销进行这些多边形排序(译者注:依深度排序)以使得我们可以按正确的顺序渲染。

但是排序多边形并不是一种低开销的操作,一个场景中通常有成千上万的多边形,并且需要在每一帧都渲染。深度缓存是一个相对简单的概念,用来消除在输出这些多边形到图形硬件之前的预排序操作。 每次一个表面需要渲染时,它的顶点都需要通过模型-视图投影矩阵进行变换。 表面的每一个顶点的深度以及位于表面的像素的内插值深度,都通过硬件进行计算。 深度缓存存储着每一个已经被渲染的像素的深度,通过这些深度来决定(通过硬件完成)当前正在渲染的像素是否比之前已经渲染的像素更靠近观察者。如果当前正在渲染的像素深度比之前已经渲染的像素深度更靠近,则该位置的颜色缓存将被更新显示。 换句话说, 最后渲染到屏幕上的颜色缓存,深度缓存,和其他附加的目标对象都是由这些通过深度测试的像素来更新。 如果像素没有通过深度测试,则只需简单的丢弃即可。

2. 什么是模板(stencil)?

一块模板缓存主要用于渲染目标,这里你可以增加或减少通过模板测试的像素在缓存中的值。 这些内容牵扯到一个更高级的渲染主题,即模板阴影卷积(stencil shadow volumes)。本文不对模板进行更深的讨论。

3. 如何表示深度模板缓存视图?

我们可以通过一个 ID3D11DepthStencilView 对象来表示深度/模板视图。正如我们已经知道的那样, Direct3D 视图以一种简单的方式用于硬件来访问资源。 这种情况下,深度缓存资源表示一个 2D 贴图,这也就意味着在我们的基类中需要添加一个 ID3D11DepthStencilView 对象,并且还需要创建一个 ID3D11Texture2D 对象来存储深度缓存的内容 。

代码实例:


ID3D11Texture2D* depthTexture_;
ID3D11DepthStencilView* depthStencilView_;


3. 如何创建深度贴图?

我们创建的 2D 贴图实际上是简单的填充一个有深度缓存必须性质的 D3D11_TEXTURE2D_DESC 对象,来作为深度缓存。深度缓存必须与我们渲染的宽度和高度相匹配,有一个绑定标识 D3D11_BIND_DEPTH_STENCIL,允许默认用法,和有格式 DXGI_FORMAT_D24_UNORM_S8_UINT。此格式说明我们使用 24 位作为一个单一的部分来存储深度。因为深度是一个单一的值,我们不需要 RGB 或 RGBA 贴图图像,只需要创建一个单一分量(R)的贴图即可。


//创建深度缓存贴图
    D3D11_TEXTURE2D_DESC depthTexDesc;
    ZeroMemory( &depthTexDesc, sizeof( depthTexDesc ) );
    depthTexDesc.Width = width;
    depthTexDesc.Height = height;
    depthTexDesc.MipLevels = 1;
    depthTexDesc.ArraySize = 1;
    depthTexDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    depthTexDesc.SampleDesc.Count = 1;
    depthTexDesc.SampleDesc.Quality = 0;
    depthTexDesc.Usage = D3D11_USAGE_DEFAULT;
    depthTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    depthTexDesc.CPUAccessFlags = 0;
    result = d3dDevice_->CreateTexture2D( &depthTexDesc, NULL, &depthTexture_ );
    if( FAILED( result ) )
    {
        DXTRACE_MSG( "Failed to create the depth texture!" );
        return false;
    }


4. 如何创建深度模板视图?

一旦我们创建好深度贴图,就可以创建深度/模板视图。可以通过填充一个有定义好我们视图所需的性质的D3D11_DEPTH_STENCIL_VIEW_DESC 对象来完成,这种情况下,我们需要设置一些格式来匹配深度贴图(例子中使用格式DXGI_FORMAT_D24_UNORM_S8_UINT)和设置视图维度标识为 D3D11_DSV_DIMENSION_TEXTURE2D。深度/模板目标对象可以通过调用函数 CreateDepthStencilView 来完成,该函数参数有深度贴图对象,视图描述对象,和将要存储深度/模板视图对象的指针。

代码示例:


// 创建深度缓存视图
    D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
    ZeroMemory( &descDSV, sizeof( descDSV ) );
    descDSV.Format = depthTexDesc.Format;
    descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
    descDSV.Texture2D.MipSlice = 0;
    result = d3dDevice_->CreateDepthStencilView( depthTexture_, &descDSV, &depthStencilView_ );
    if( FAILED( result ) )
    {
        DXTRACE_MSG( "Failed to create the depth stencil target view!" );
        return false;
    }
    d3dContext_->OMSetRenderTargets( 1, &backBufferTarget_, depthStencilView_ );
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: