天天看點

DirectX11 紋理和資源概述

紋理和資源概述

1. 為什麼需要紋理?

我們的示範程式正在變得越來越有趣,但是頂點顔色無法展現真實世界物體所具有的細節。紋理貼圖映射(texture mapping)是一種将圖像資料映射到三角形表面的技術,它可以顯著提高場景的細節和真實感。例如,我們可以建立一個立方體,然後将一

個闆條箱紋理映射到立方體的每個面上,使它看上去更像是一個闆條箱(參見下圖)。

DirectX11 紋理和資源概述

2. 紋理如何表示?

回顧我們自從第4章之後學習和使用過的一些紋理;尤其是深度緩沖區和背景緩沖區,它們都是通過ID3D11Texture2D接口描述的2D紋理對象。在本節中,我們将回顧第4章講過的一些有關紋理和材質的知識。

2D紋理是一種資料元素矩陣。2D紋理的用途之一是存儲2D圖像資料,在紋理的每個元素中儲存一個像素顔色。但這不是紋理的唯一用途;例如,在一種稱為法線貼圖映射(normal mapping)的進階技術中,紋理存儲的不是顔色,而是3D向量。是以,從通常意義上講,紋理用來存儲圖像資料,但是在實際應用中紋理可以有更廣泛的用途。1D紋理(ID3D11Texture1D)類似于一個1D資料元素數組,3D紋理(ID3D11Texture3D)類似一個3D資料元素數組。1D、2D、3D紋理接口都繼承自ID3D11Resource接口。

本章稍後會讨論紋理的更多特性。紋理比資料數組要複雜的多;紋理可以帶有多級漸近紋理層(mipmap level),GPU可以在紋理上執行特殊運算,比如使用過濾器(filter)和多重采樣(multisampling)。

3. 紋理内部的資料可以是什麼?

并非所有資料塊都能存入紋理;紋理隻支援特定格式的資料存儲,這些格式由DXGI_FORMAT枚舉類型描述。其中一些常用的格式如下:

1.DXGI_FORMAT_R32G32B32_FLOAT:每個元素包含3個32位浮點分量。

2.DXGI_FORMAT_R16G16B16A16_UNORM:每個元素包含4個16位分量,分量的取值範圍在[0,1]區間内。

3.DXGI_FORMAT_R32G32_UINT:每個元素包含2個32位無符号整數分量。

4.DXGI_FORMAT_R8G8B8A8_UNORM:每個元素包含4個8位無符号整數分量,分量的取值範圍在[0,1]區間内。

5.DXGI_FORMAT_R8G8B8A8_SNORM:每個元素包含4個8 位有符号整數分量,分量的取值範圍在[−1,1] 區間内。

6.DXGI_FORMAT_R8G8B8A8_SINT:每個元素包含4個8位有符号整數分量,分量的取值範圍在[−128, 127]區間内。

7.DXGI_FORMAT_R8G8B8A8_UINT:每個元素包含4個8位無符号整數分量,分量的取值範圍在[0, 255]區間内。

注意,字母R、G、B、A分别表示red(紅)、green(綠)、blue(藍)和alpha(透明度)。

不過,正如我們之前所述,紋理存儲的不一定是顔色資訊;例如,格式

DXGI_FORMAT_R32G32B32_FLOAT

包含3個浮點分量,可以存儲一個使用浮點坐标的3D向量(而不一定是顔色向量)。

另外,還有一種弱類型(typeless)格式,可以預先配置設定記憶體空間,然後在紋理綁定到管線時再指定如何重新解釋資料内容(這一過程與資料類型轉換頗為相似)。例如,下面的弱類型格式會為每個元素預留4個8位分量,且不指定資料類型(例如:整數、浮點數、無符号整數):

DXGI_FORMAT_R8G8B8A8_TYPELESS

紋理可以被綁定到渲染管線的不同階段。例如,比較常見的情況是将紋理作為渲染目标(即,Direct3D渲染到紋理)和着色器資源(即,在着色器中對紋理進行采樣)。當建立用于這兩種目的的紋理資源時,應使用綁定标志值:

D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE

指定紋理所要綁定的兩個管線階段。其實,資源不能被直接綁定到一個管線階段;我們隻能把與資源關聯的資源視圖綁定到不同的管線階段。無論以哪種方式使用紋理,Direct3D始終要求我們在初始化時為紋理建立相關的資源視圖。這樣有助于提高運作效率,正如SDK文檔指出的那樣:“運作時環境與驅動程式可以在視圖建立執行相應的驗證和映射,減少綁定時的類型檢查”。是以,當把紋理作為一個渲染目标和着色器資源時,我們要為它建立兩種視圖:渲染目标視圖(ID3D11RenderTargetView)和着色器資源視圖(ID3D11ShaderResourceView)。資源視圖主要有兩個功能:(1)告訴Direct3D如何使用資源(即,指定資源所要綁定的管線階段);(2)如果在建立資源時指定的是弱類型(typeless)格式,那麼在為它建立資源視圖時就必須指定明确的資源類型。對于弱類型格式,紋理元素可能會在一個管線階段中視為浮點數,而在另一個管線階段中視為整數。

注意:2008年8月的SDK文檔指出:“當建立資源時,為資源指定強類型(fully-typed)格式,把資源的用途限制在格式規定的範圍内,有利于提高運作時環境對資源的通路速度……”。是以,你隻應該在真正需要弱類型資源時,才建立弱類型資源;否則,應盡量建立強類型資源。

為了給一個資源建立特定的視圖,該資源在建立時必須帶有特定的綁定标志值。例如,在建立資源時如果沒有使用D3D11_BIND_SHADER_RESOURCE綁定标志值(該标志值表示紋理将作為一個着色器資源綁定到管線上),那麼我們就無法為這個資源建立ID3D11ShaderResourceView視圖。如果你嘗試一下就會發現 Direct3D會報告如下調試錯誤:

D3D11: ERROR: ID3D11Device::CreateShaderResourceView:A ShaderResourceView cannot be created of a Resource that did not specify the D3D11_BIND_SHADER_RESOURCE BindFlag.

繼續閱讀