D3D9 优化小技巧
此篇文章主要講一些小技巧,針對前面轉載的D3D9 GPU Hacks,我們可以做的一些優化。
在做延遲渲染或者其它需要深度的地方使用INTZ格式的紋理,這樣可以直接對紋理進行操作,節省了顯存和帶寬,這樣即使在前向渲染的時候也可以獲取深度,有了深度信息我們就可以做很多效果,如水的柔邊,水邊泡沫,景深等效果。
注:以下示例代碼均摘自http://developer.amd.com/wordpress/media/2012/10/Advanced-DX9-Capabilities-for-ATI-Radeon-Cards_v2.pdf
INTZ 紋理示例代碼:
Depth Texture Format: INTZ
Description: An additional texture format called INTZ is exposed that allows a 24-bit depth
buffer previously used for rendering to be bound as a texture. Any fetches from this texture
will return the depth values stored. Shadow mapping applications relying on PercentageCloser
Filtering should prefer the use of DX9 Depth Stencil Textures instead. INTZ
additionally exposes an 8-bit stencil buffer when used for depth buffering, allowing stencil
operation to be carried out when an INTZ surface is bound as the active depth stencil buffer.
However the contents of the stencil buffer will not be available as texture data when binding
the surface as a texture.
Note that an INTZ depth buffer may be used as a texture concurrently to the same INTZ
surface being used for depth buffering, as long as depth writes are disabled.
Supported hardware: ATI Radeon 4000 series and above.
Implementation details
A FourCC depth texture format is exposed:
#define FOURCC_INTZ ((D3DFORMAT)(MAKEFOURCC(‘I’,’N’,’T’,’Z’)))
To check support for this feature:
// Determine if INTZ is supported
HRESULT hr;
hr =pd3d->CheckDeviceFormat(AdapterOrdinal, DeviceType, AdapterFormat,
D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE,
FOURCC_INTZ);
BOOL bINTZDepthStencilTexturesSupported = (hr == D3D_OK);
To create an INTZ depth stencil texture:
// Create an INTZ depth stencil texture
IDirect3DTexture9 *pINTZDST;
pd3dDevice->CreateTexture(dwWidth, dwHeight, 1,
D3DUSAGE_DEPTHSTENCIL, FOURCC_INTZ,
D3DPOOL_DEFAULT, &pINTZDST,
NULL);
To bind the depth stencil texture as an active depth buffer:
// Retrieve depth buffer surface from texture interface
IDirect3DSurface9 *pINTZDSTSurface;
pINTZDST->GetSurfaceLevel(0, &pINTZDSTSurface);
// Bind depth buffer
pd3dDevice->SetDepthStencilSurface(pINTZDSTSurface);
Note that calling GetSurfaceLevel() increases the reference count of pINTZDST so you will
need to Release() it when no longer needed.
To bind an INTZ depth buffer texture as a texture:
// Bind depth buffer texture
pd3dDevice->SetTexture(0, pINTZDST);
注意:此處千萬不能使用D3DXCreateTexture 來創建這樣的紋理,因為D3DX并沒有對此提供支持,創建的返回的紋理類型并不是你需要的INTZ等格式,下面所講也同等適用。
在渲染陰影的時候我們一般使用D16或者D32,使用tex2dproj函數來利用硬件特性來采樣紋理,這樣直接返回的是一個陰影系數。渲染陰影的時候我們并不需要一張顏色紋理,但是D3D9必須要綁定一張顏色紋理。我們可以通過上面提到的NULL紋理來達到節省顯存的目的,當然使用之前也需要查詢當前硬件是否支持NULL紋理。
示例代碼如下:
Render Target Format: NULL
Description: A render target format called NULL is exposed. Render targets created with
this format will not have any memory allocated internally, but will satisfy validation
requirements imposed by the DX9 runtime. This functionality is useful when performing
rendering onto a depth buffer without wishing to update an actual color render target since
the DX9 runtime enforces the use of a valid color render target for all rendering operations.
Therefore common depth-only rendering applications like shadow mapping or depth pre-pass
can benefit from using this “dummy” format to save memory that would otherwise be
required to bind a valid color render target for this operation.
Supported hardware: ATI Radeon 4000 series and above.
Implementation details
A FourCC color render target format is exposed:
#define FOURCC_NULL ((D3DFORMAT)(MAKEFOURCC(‘N’,’U’,’L’,’L’)))
To check support for this feature:
// Determine if NULL is supported
HRESULT hr;
hr = pd3d->CheckDeviceFormat(AdapterOrdinal, DeviceType, AdapterFormat,
D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE,
FOURCC_NULL);
BOOL bNULLRenderTargetSupported = (hr == D3D_OK);
To create a NULL render target surface:
// Create a NULL render target with 4x multisampling
IDirect3DSurface9* pDummyRenderTarget;
pd3dDevice->CreateRenderTarget(dwWidth, dwHeight, FOURCC_NULL,
D3DMULTISAMPLE_4_SAMPLES, 0,
FALSE, &pDummyRenderTarget, NULL);
To bind a NULL render target surface:
// Bind a NULL render target at slot 0 so that we don’t have to bind
// a real color buffer; this allows memory savings
pd3dDevice->SetRenderTarget(0, pDummyRenderTarget);
這樣我們可以通過這些小技巧來達到節省顯存、帶寬等目的。還有一些小的技巧,比如Alpha to coverage, depth bound test等,我也會陸續把它們添加進來。
參考文章:
1. D3D9 GPU Hacks
2.Advanced DX9 Capabilities for ATI Radeon Cards
總結
以上是生活随笔為你收集整理的D3D9 优化小技巧的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GUPPY 3.1.5 安装
- 下一篇: 消息称苹果计划于 2024 年年中推出配