前言 (更新於 2020/6/15)
從第一次接觸DirectX 11到現在已經有將近三年的時間了。記得當初學習DirectX 11,在用龍書的源碼配置項目運行環境的時候都花了好幾天的時間才搞定,又因為書中的代碼的開發環境(VS 2010)與現在的情況有些沖突,還得忍受上千個無法避免的編譯警告,不得不視警告為無物。而且里面的代碼使用了Microsoft DirectX SDK(June 2010)開發包和里面的Effects 11框架,這些東西都已經是將近10年前的產物了。
后面到18年5月的時候,我先是在Github上翻到了微軟對FX11(原Effects11)庫一直都還在更新,然后發現了DirectX Tool Kit和DirectX SDK Samples,里面提供的教程寫法和龍書的做法不一樣。我才明白,微軟其實已經將DirectX的相關組件隨同Windows SDK一起更新。而我現在使用的是Visual Studio 2019 Community,里面就已經包含了Windows SDK。經過一段時間的文檔和樣例閱讀后,決定嘗試編寫一個全新的教程盡可能地擺脫DirectX SDK的束縛。
但是在轉移的時候也遇到了很多需要解決的問題,比如:
- 沒有了諸如
d3dx11.h
,xnamath.h
,dxerr.h
,xnacollision.h
等這些老舊的頭文件 - 使用新的Effects 11框架的話引發編譯器警告:
X4717: Effects deprecated for D3DCompiler_47
,提示Effects11未來可能不受D3DCompiler的支持 - 着色器需要手工進行管理,並且HLSL的寫法上和FX有些差異(比如Sampler不能在HLSL中直接定義)
- 龍書11的示例代碼有關Effects 11的部分基本上還得靠自己重新編寫
這些問題都可以下面的教程中找到對應的解決/替代方案,在這里就不一一列舉了。
知識儲備
十分重要!由於該文章系列注重的是項目實踐,並不是面向零基礎的初學者。在學習本教程之前需要:
-
熟悉C++及面向對象編程,最好是了解C++11,並且能熟練使用指針、數組等內容。熟悉Visual Studio的使用,有一定的項目開發經驗。推薦閱讀《C++ Primer》一書。
-
了解Win32 API,但窗口初始化不是本教程的重點,這部分內容自行了解即可。
-
對線性代數和3D數學基礎有所掌握,推薦閱讀《3D數學基礎》一書。本教程只會花有限的篇幅進行講解。
-
了解渲染管線基礎,可以閱讀過龍書11的第4章到第5章,用過游戲引擎進行開發,又或者是之前學過DirectX9/11 或 OpenGL
教程與項目特點
本教程與項目的特點如下:
- 完全脫離對DirectX SDK的依賴,下載項目編譯后即可運行,並且兼容Win7-Win10平台
- 使用原生的HLSL編譯器,並且不依賴於FX11(Effects)框架和fx5.0,雖然對實現細節要求更高了,但能夠對底層實現有更加深入的了解
- 對Direct3D 11的一系列API有較為詳細的講解
- 代碼盡可能地不使用高級C++特性(如模板元),以降低閱讀源碼帶來的難度。並且項目內會有一些編寫好的小模塊,一定程度上降低代碼編寫的難度
- 各個項目都是獨立的,沒有依賴項,以降低它們的復雜度
盡管這邊提供了大量的學習Demo,但還是鼓勵大家邊學習邊自己編寫代碼,多動手實踐,只有踩過的坑才是你自己的。此外項目並不是以追求極致效率為目的,這些事情還是在能夠熟練使用Direct3D API的時候再考慮。
降低學習難度
如何讓你的DirectX 11學習之路更為平坦?在此我給出幾點調試相關的建議:
- 時間充裕者優先考慮補足知識儲備再來學習DirectX 11
- 沒學會單步調試、斷點調試的一定要先去學會。
- 在調試程序的時候一定要留意輸出窗口(來源為調試),一些D3D相關的函數運行失敗都會在這里有十分詳細的反饋。了解這個可以省去你很多開發的時間,避免不必要的查找,這一點十分重要!
- 學會使用Visual Studio自帶的圖形調試器,這是必修知識。一定要能夠區分開普通調試(CPU)和圖形調試(GPU)!
- 善於利用一些函數返回的
HRESULT
類型錯誤碼,可以使用我這邊的DXTrace
庫來了解錯誤碼的具體含義,也可以使用DirectX SDK中的Utilities\bin\x86\DXErr.exe
來查詢
下面是一個嘗試使用顯示適配器創建D3D設備引發的錯誤:
注意:
1. 考慮到現在DXTK庫只是用到了它里面的鍵鼠類和紋理加載,現在已經單獨提取出來使用,讀者不需要過於關注這部分內容的實現細節。
2. 現在某些章節會有一些練習題,除了龍書里面有的部分進行挑選外,自己也嘗試出了一些題目。但是題目並不會給出答案(大多數實現方法都並不唯一)
3. 本教程並不能代表Direct3D的方方面面,務必要善於利用下面參考資料中給予的MSDN文檔來查詢信息,培養自己的文檔閱讀能力。
4.如果你只是單純為了做一款游戲,那么學習使用Unity 3D來開發可能會更適合您。
閱讀順序
Direct3D 11學起來並不容易。首先從入門篇開始,再根據其要求先閱讀前置章節(一般是雜項篇)。然后是一些難點部分的問題:
- 第一章要一遍弄懂會比較難,讀者可以先略讀一遍,然后從第二章開始進入正題,以后在自己有初始化需求的時候再回頭看。
- 一些比較細節的東西,如涉及到需要靠匯編來解釋的部分,讀者弄不懂可以先直接記住結論后跳過。
- 盡管博客總體講述比較詳細,但閱讀代碼的時候從GameApp類開始,然后最好是按自頂向下的方式逐漸深入。
項目下載
在開始教程之前務必下載一份源碼,教程中的源碼不會給全,只是根據實際需要進行展開說明。同時也希望能進去點個Star支持一下。
GitHub項目瀏覽與下載
歡迎加入QQ群: 727623616 可以一起探討DX11,以及有什么問題也可以在這里匯報。
項目概述
語言:
-C++11和少量C++14
-HLSL Shader Model 5.0
目前所有項目無需依賴第三方庫的編譯,而是從微軟官方項目中提取了下述模塊到項目中:
DirectXTex/DDSTextureLoader
DirectXTex/WICTextureLoader
DirectXTex/ScreenGrab
DXTK/Mouse(源碼上有所修改)
DXTK/Keyboard(源碼上有所修改)
教程需求與配置表
IDE | VS2019 | VS2017 | VS2015 |
---|---|---|---|
D3DComplier版本 | 47 | 47 | 47 |
Windows SDK版本 | 10.0 (最新安裝的版本) | 10.0.17763.0 | 10.0.14393.0 |
Windows開發/運行環境 | Windows 10 | Windows 10 | Windows 7 SP1及更高版本 |
平台 | x86/x64支持 | x86/x64支持 | x86/x64支持 |
配置 | Debug/Release支持 | Debug/Release支持 | Debug/Release支持 |
注意:
- 教程不支持VS2013及更低版本!
- VS2015在安裝時需要勾選VS2015 更新 3, 以及Tools(1.4.1)和Windows 10 SDK(10.0.14393)
- Win7系統需要安裝Service Pack 1以及KB2670838補丁以支持Direct3D 11.1
博客和項目維護不易,目前教程和項目僅由作者一人維持,精力有限。如果本系列教程對你有所幫助,希望能夠掃碼支持一下博主。
目錄
雜項篇(優先度從高到低)
實戰篇
目錄 |
---|
實現一個3D魔方(1) |
實現一個3D魔方(2) |
實現一個3D魔方(3) |
入門篇
目錄 |
---|
01 DirectX11初始化 |
02 頂點/像素着色器的創建、頂點緩沖區 |
03 索引緩沖區、常量緩沖區 |
04 變換 |
05 DirectXMath數學庫 |
06 鍵盤和鼠標輸入 |
07 添加光照與常用幾何模型、光柵化狀態 |
08 Direct2D與Direct3D互操作性以及利用DWrite顯示文字 |
09 紋理映射與采樣器狀態 |
10 基於Transform的攝像機類與GameObject類 |
進階篇
高級篇
目錄 |
---|
26 計算着色器:入門 |
27 計算着色器:雙調排序 |
28 計算着色器:波浪(水波) |
29 計算着色器:內存模型、線程同步;實現順序無關透明度(OIT) |
30 計算着色器:高斯模糊、索貝爾算子 |
31 陰影映射 |
32 SSAO(屏幕空間環境光遮蔽) |
33 曲面細分階段(Tessellation) |
34 位移貼圖 |
35 粒子系統 |
參考資料
MSDN文檔,同時推薦大家收藏以隨時查閱:
Direct3D 11 Graphics API(Windows SDK)
Direct3D 11 Graphics(Windows SDK)
參考到的一些網站:
參考書籍:
Introduction to 3D Game Programming with DirectX 11
Practical Rendering and Computation with Direct3D 11
Mathematics for 3D Game Programming and Computer Graphics, Third Edition
DirectX12 3D游戲開發實戰
后記(更新於2020/7/29)
這個博客系列斷斷續續寫了28個月的時間,中間經歷了太多太多的事情,而且還要准備考研,當然現在也已經上岸了,更到現在,我個人認為已經達到了第一階段的封筆了,后續工作主要是代碼和博客的維護。轉眼間現在博客出了50篇(不包括目錄),這個項目也收獲了顆,感謝大家對本項目和教程的支持。一開始只是想着告訴人怎么過渡到Windows SDK版的DX,然后初期的代碼基本上就是DirectX-SDK-Samples跟龍書的縫合框架。寫到后面有什么好的想法還可能要經常回頭改代碼,當然這些代碼只有在自己實現一遍的時候才會感觸良深,受益匪淺。再后來就是認識到了更多的dl,也感受到自己還有很多很多不懂的東西。當然,理論上如果你能看完整個博客系列,你就對Direct3D 11的主線知識基本上都了解的差不多了,對於那些比較邊緣的知識此時讀者應當有能力自己去根據需要來探尋。這里自問自答幾個問題:
- 為什么不講多線程渲染?我認為如果要學多線程渲染的話,還不如留到學DX12的時候學會更好一些。
- 骨骼動畫、Assimp、ImGui怎么鴿了?最主要的問題是我一直都在克制自己,不給這個系列項目引入第三方的代碼,如果引入了勢必會對后續的更新帶來麻煩。當然能跟我教程這么久的讀者我覺得應該也有能力去自己嘗試加入一些外面的東西了吧。
現在要考慮的問題是接下來學什么?下面是一些可以嘗試的內容:
- GAMES101:現代計算機圖形學入門(推薦)
- 現代圖形庫API:DirectX12、Vulkan
- Real Time Rendering 4th
- Physically Based Rendering 3rd
- 全局光照技術
- 光線追蹤技術
- Unity、Unreal引擎
8月開始事情逐漸多起來了,有什么想補充的話后面我會在這里更新的,希望大家能夠繼續努力。