DirectX11--深入理解與使用2D紋理資源
DirectX11--HLSL語(yǔ)法入門(mén)
介紹
在VS2019中,選擇【使用C++的桌面開(kāi)發(fā)】會(huì)默認(rèn)選中一個(gè)叫做Windows 10 SDK的組件抽莱。這個(gè)SDK已經(jīng)集成DirectX的開(kāi)發(fā)庫(kù)允蚣。
XNA數(shù)學(xué)庫(kù)
縮放
XMMatrixScaling
// 調(diào)用 XMMatrixScaling() 函數(shù)用以生成縮放矩陣, 該函數(shù) 3 個(gè)參數(shù)分別表示
// 在 X, Y, Z 軸上的縮放量
// 在 X, Y, Z 軸上縮小到 1/5 (即 0.2), 然后將生成的縮放矩陣賦值給 mScal
XMMATRIX mScal = XMMatrixScaling(0.2f, 0.2f, 0.2f);
旋轉(zhuǎn)
XMMatrixRotation*
// 繞 Y 軸旋轉(zhuǎn) 45 度, 即 1/4 PI
// 調(diào)用 XMMatrixRotationY() 函數(shù)用以生成旋轉(zhuǎn)矩陣, 該函數(shù)的參數(shù)為旋轉(zhuǎn)的弧度
// XM_PIDIV4 為 XNA 庫(kù)定義的數(shù)據(jù)常量表示 1/4 PI
XMMATRIX mRota = XMMatrixRotationY(XM_PIDIV4);
平移
XMMatrixTranslation
// 在 X 軸平移 1 個(gè)單位, 在 Y 軸平移 2 個(gè)單位, 在 Z 軸平移 -3 個(gè)單位
// 調(diào)用函數(shù) XMMatrixTranslation() 生成平移矩陣
// 該函數(shù) 3 個(gè)參數(shù)分別表示在 X, Y, Z 軸上的平移量
XMMATRIX mTrans = XMMatrixTranslation(1.0f, 2.0f, -3.0f);
矩陣相乘
XMMatrixMultiply
變換向量
XMVector4Transform
通過(guò)矩陣變換一個(gè)4D向量被冒,并返回轉(zhuǎn)換后的向量勿负。
參考: 《基于 DirectX11 的 3D 圖形程序設(shè)計(jì)案例教程》學(xué)習(xí)二 MatrixTrans
Directx3D龍書(shū)記錄
輸入裝配階段
輸入裝配(Input Assembler公浪,簡(jiǎn)稱(chēng)IA)階段從內(nèi)存讀取幾何數(shù)據(jù)(頂點(diǎn)和索引)并將這些數(shù)據(jù)組合為幾何圖元(例如秆撮,三角形四濒、直線(xiàn))
圖元拓?fù)?/h4>
通過(guò)指定圖元拓?fù)鋪?lái)告訴Direct3D以何種方式組成幾何圖元。
void ID3D11Device::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topology);
頂點(diǎn)著色器階段
在完成圖元裝配后职辨,頂點(diǎn)將被送往頂點(diǎn)著色器(vertex shader)階段盗蟆。頂點(diǎn)著色器可以被看成是一個(gè)以頂點(diǎn)作為輸入輸出數(shù)據(jù)的函數(shù)。每個(gè)將要繪制的頂點(diǎn)都會(huì)通過(guò)頂點(diǎn)著色器推送至硬件舒裤;實(shí)際上喳资,我們可以概念性地認(rèn)為在硬件上執(zhí)行了如下代碼:
for(UINT i = 0; i < numVertices; ++i)
outputVertex[i] = VertexShader(inputVertex[i]);
頂點(diǎn)著色器函數(shù)由我們自己編寫(xiě),但是它會(huì)在GPU上運(yùn)行腾供,所以執(zhí)行速度非称偷耍快。
許多效果伴鳖,比如變換(transformation)宏赘、光照(lighting)和置換貼圖映射(displacement mapping)都是由頂點(diǎn)著色器來(lái)實(shí)現(xiàn)的。記住黎侈,在頂點(diǎn)著色器中察署,我們不僅可以訪(fǎng)問(wèn)輸入的頂點(diǎn)數(shù)據(jù),也可以訪(fǎng)問(wèn)在內(nèi)存中的紋理和其他數(shù)據(jù)峻汉,比如變換矩陣和場(chǎng)景燈光贴汪。
Direct3D也希望我們將深度坐標(biāo)映射到一個(gè)規(guī)范化區(qū)間[0,1]中。
規(guī)范化設(shè)備坐標(biāo)(NDC)
透視投影矩陣
透視投影矩陣可由如下XNA函數(shù)生成:
XMMATRIX XMMatrixPerspective FovLH(// returns projection matrix
FLOAT FovAngleY, // vertical field of view angle in radians
FLOAT AspectRatio, // aspect ratio = width / height
FLOAT NearZ, // distance to near plane
FLOAT FarZ); // distance to far plane
下面的代碼片段示范了XMMatrixPerspectiveFovLH函數(shù)的使用方法休吠。這里扳埂,我們將垂直視域角設(shè)為45°,近平面z設(shè)為1瘤礁,遠(yuǎn)平面z設(shè)為1000(這些長(zhǎng)度是在觀(guān)察空間中的)阳懂。
XMMATRIX P = XMMatrixPerspectiveFovLH(0.25f*MathX::Pi,
AspectRatio(),1.0f,1000.0f);
float D3Dapp::AspectRatio() const
{
return static_cast<float>(mClientWidth)/mClientHeight;
}
幾何著色器階段
幾何著色器以完整的圖元作為輸入數(shù)據(jù)。例如柜思,當(dāng)我們繪制三角形列表時(shí)岩调,輸入到幾何著色器的數(shù)據(jù)是構(gòu)成三角形的三個(gè)點(diǎn)。(注意赡盘,這三個(gè)點(diǎn)是從頂點(diǎn)著色器傳遞過(guò)來(lái)的号枕。)幾何著色器的主要優(yōu)勢(shì)是它可以創(chuàng)建或銷(xiāo)毀幾何體。例如陨享,輸入圖元可以被擴(kuò)展為一個(gè)或多個(gè)其他圖元葱淳,或者幾何著色器可以根據(jù)某些條件拒絕輸出某些圖元钝腺。這一點(diǎn)與頂點(diǎn)著色器有明顯的不同:頂點(diǎn)著色器無(wú)法創(chuàng)建頂點(diǎn),只要輸入一個(gè)頂點(diǎn)赞厕,那么就必須輸出一個(gè)頂點(diǎn)艳狐。幾何著色器通常用于將一個(gè)點(diǎn)擴(kuò)展為一個(gè)四邊形,或者將一條線(xiàn)擴(kuò)展為一個(gè)四邊形皿桑。
光柵化階段
光柵化(rasterization)階段的主要任務(wù)是為投影后的3D三角形計(jì)算像素顏色毫目。
視口變換
在裁剪之后,硬件會(huì)自動(dòng)執(zhí)行透視除法唁毒,將頂點(diǎn)從齊次裁剪空間變換到規(guī)范化設(shè)備空間(NDC)蒜茴。一旦頂點(diǎn)進(jìn)入NDC空間,構(gòu)成2D圖像的2D x浆西、y坐標(biāo)就會(huì)被變換到后臺(tái)緩沖區(qū)中的一個(gè)稱(chēng)為視口的矩形區(qū)域內(nèi)粉私。在該變換之后,x近零、y坐標(biāo)將以像素為單位诺核。通常,視口變換不修改z坐標(biāo)久信,因?yàn)閦坐標(biāo)還要由深度緩存使用窖杀,但是我們可以通過(guò)D3D11_VIEWPORT結(jié)構(gòu)體的MinDepth和MaxDepth值修改z坐標(biāo)的取值范圍。MinDepth和MaxDepth的值必須在0和1之間裙士。
頂點(diǎn)屬性插值
除位置外入客,頂點(diǎn)還可以包含其他屬性,比如顏色腿椎、法線(xiàn)向量和紋理坐標(biāo)桌硫。在視口變換之后,這些屬性必須為三角形表面上的每個(gè)像素進(jìn)行插值啃炸。頂點(diǎn)深度值也必須進(jìn)行插值铆隘,以使每個(gè)像素都有一個(gè)可用于深度緩存算法的深度值。對(duì)屏幕空間中的頂點(diǎn)屬性進(jìn)行插值南用,其實(shí)就是對(duì)3D空間中的三角形表面進(jìn)行線(xiàn)性插值(如圖5.33所示)膀钠;這一工作需要借助所謂的透視矯正插值(perspective correct interpolation)來(lái)實(shí)現(xiàn)。本質(zhì)上裹虫,三角形表面內(nèi)部的像素顏色都是通過(guò)頂點(diǎn)插值得到的肿嘲。
圖5.34 一條3D線(xiàn)被投影到投影窗口上(在屏幕空間中投影是一條2D線(xiàn))。我們看到恒界,在3D線(xiàn)上取等距離的點(diǎn)睦刃,在2D屏幕空間上的投影點(diǎn)卻不是等距離的。所以十酣,我們?cè)?D空間中執(zhí)行線(xiàn)性插值涩拙,在屏幕空間需要執(zhí)行非線(xiàn)性插值。
像素著色器階段
像素著色器會(huì)處理每個(gè)像素片段(pixel fragment)耸采,它的輸入是插值后的頂點(diǎn)屬性兴泥,由此計(jì)算出一個(gè)顏色。
輸出合并階段
當(dāng)像素片段由像素著色器生成之后虾宇,它們會(huì)被傳送到渲染管線(xiàn)的輸出合并(output merger搓彻,簡(jiǎn)稱(chēng)OM)階段。在該階段中嘱朽,某些像素片段會(huì)被丟棄(例如旭贬,未能通過(guò)深度測(cè)試或模板測(cè)試)。未丟棄的像素片段會(huì)被寫(xiě)入后臺(tái)緩沖區(qū)搪泳。混合(blending)工作是在該階段中完成的稀轨,一個(gè)像素可以與后臺(tái)緩沖區(qū)中的當(dāng)前像素進(jìn)行混合,并以混合后的值作為該像素的最終顏色岸军。某些特殊效果奋刽,比如透明度,就是通過(guò)混合來(lái)實(shí)現(xiàn)的
chili教程記錄
chili的原版英文教程-中文字幕
chili的原版英文教程
模板繼承
在第20講大約13:40中講到艰赞,如果一個(gè)子類(lèi)模板佣谐,繼承的父類(lèi)也是一個(gè)模板,并且子類(lèi)需要使用父類(lèi)模板的父類(lèi)中的方法方妖,則需要顯示指明狭魂,如下:
class Bindable
{
public:
virtual void Bind( Graphics& gfx ) noexcept = 0;
virtual ~Bindable() = default;
protected:
static ID3D11DeviceContext* GetContext( Graphics& gfx ) noexcept;
static ID3D11Device* GetDevice( Graphics& gfx ) noexcept;
static DxgiInfoManager& GetInfoManager( Graphics& gfx ) noexcept(IS_DEBUG);
};
template<typename C>
class ConstantBuffer : public Bindable
{
....
}
template<typename C>
class VertexConstantBuffer : public ConstantBuffer<C>
{
using ConstantBuffer<C>::pConstantBuffer;
using Bindable::GetContext;
public:
void Bind( Graphics& gfx ) noexcept override
{
// 這里這個(gè)GetContext需要顯示指明
// 1. 使用using Bindable::GetContext;
// 2. 使用this->GetContext
// 3. 使用域作用符Bindable::GetContext
GetContext( gfx )->VSSetConstantBuffers( 0u,1u,pConstantBuffer.GetAddressOf() );
}
};