2018年2月26日 星期一

關於Transform的矩陣乘法

關於Transform的矩陣乘法
前言
  這個部分印象寫了不少次,但每次寫的時候就是無法把細節全記起來,這次就在這裡記錄下來。

內容
  由於矩陣有分左乘與右乘,以下的說明皆為"左乘"。首先是TRS矩陣,使用位移(transition)、旋轉(rotation)與比例(scale)矩陣所組成,組成的順序如下

  TRS_Matrix = ScaleMatrix * RotationMatrix * TransitionMatrix

再來,如果考量到有Parent的Transform,組成的順序如下

  WorldMatrix = TRS_Matrix(child) * TRS_Matrix(parent) * (More parent's TRS_Matrix)...

有以上兩種規則組成的矩陣就是WorldMatrix,如果要將Transfrom的內容應用到Shader就要考慮ViewMatrix與ProjectionMatrix,組成的順序如下

  WVPMatrix = WorldMatrix * ViewMatrix * ProjectionMatrix

這樣的就可以組成WVPMatrix。
 


2018年2月19日 星期一

關於wglCreateContextAttribsARB()的問題

關於wglCreateContextAttribsARB()的問題
前言
  wglCreateContextAttribsARB()是可以選擇context的版本的CreateContext(),在create方面沒問題,但在wglMakeCurrent()後,會發現畫面再也畫不出任何東西,可是畫面卻是有清除的!這個問題以前一直不知道是什麼問題,最近有空就來Debug一下。

內容
  首先畫面是有清除的,表示glClear()有效的,但"Hello Trangle的範例"執行後會發現三角形畫不出來!
glGetError()也沒有得到錯誤訊息。以前都一直以為是wglCreateContextAttribsARB()的參數沒下好,又或是wglMakeCurrent()的時機的問題,讓我一直找不出這個問題的答案。在Debug中發現當版本被調到3.1後遽然就畫得出來了!但到了3.2以後的版本都繪畫不出來,這時才開始懷疑可能不是wglCreateContextAttribsARB()的問題,看了一下"Hello Trangle的範例"的程式碼,在OpenGL的設置有glUseProgram()、glEnableVertexAttribArray()、glBindBuffer()與glVertexAttribPointer(),看來沒什麼問題,但在google關於OpenGL3.2的範例後發現裡面多了一個glBindVertexArray()!這是OpenGL3.2多的Vertex Array Object(VAO),在我之前對VAO的認知是這個東西可用可不用,但我錯了,在我把VAO加入後,"Hello Trangle的範例"就可以順利畫出三角形了,原來在OpenGL3.2以後,VAO是"必要"流程,而不是可選擇的流程,真是學習了。

參考資料
Tutorial2: VAOs, VBOs, Vertex and Fragment Shaders (C / SDL)

2018年2月13日 星期二

從D3D10到D3D11

從D3D10到D3D11
前言
  最近要將原本的D3D10的引擎整合D3D11,這邊把一些差異的部分記錄下來。

內容
  首先D3D10的Device在D3D11被分裂成Device與DeviceContext,D3D11的Device主要負責製造資源,而DeviceContext負責執行繪圖的命令。這裡要注意D3D11是可以向下整合的!剩至可以相容D3D10,而原本的D3D10在10.0與10.1差異只有用不同的Create()去區分。
  在DXGISwapChain的部分,要注意11.0的作法與D3D10差不多,但11.1的作法就不一樣了,可以參考D3D11的教學範例,參考教學2的做法即可。
  在shader的方面,D3D11多了Hull shader與Domain shader,ConstatBuffer、Texture與SamplerState的設置介面和舊有的Shader是一樣的,但D3D11的SetShader()的介面多了2個參數,目前還不知具體的作用,設成空的是可行的。
  編譯shader的部分只要把版本調成"5"就可以了,至少目前沒發生問題。
  RasterizerState、BlendState與DepthStencilState基本上和D3D10的做法一樣,但若是11.1的話,要注意BlendState在Create的時候,D3D11_BLEND_DESC1的Rendertarget裡會多一個"RenderTargetWriteMask",這個參數的預設值請設成"D3D11_COLOR_WRITE_ENABLE_ALL",就算是把Blend設為關閉也要設置這個變數,不可以設成"0",如果設成"0"會看不到任何繪製結果!一定要注意。

後記
如果只是單純用D3D11模擬D3D10的繪製方法的話,整體來說還算是簡單,但看了一下Device的介面裡多可一些新的資源可以Create,那些新東西以後有機會再來研究研究。
參考資料
ID3D11Device interface
D3D11的教學範例

2018年2月5日 星期一

關於矩陣的乘法

關於矩陣的乘法

前言

  以前總是這樣乘矩陣,ModelMatrix*ViewMatrix*ProjectionMartix,但不知什麼時候開始出現另一種乘法,ProjectionMartix*ViewMatrix*ModelMatrix,雖然早就知道矩陣乘法不具有交換律,但卻都沒有去好好確認過為什麼會有這樣的差異。最近發生在C++的引擎使用第一種方法,但webgl的引擎卻是使用第二種方法!剛好有這機會我就來探究原因。


內容

  首先先把webgl的引擎用第一種方法乘,然後列印出來跟C++來比對,發現內容遽然不一樣!
後來發現是兩邊的矩陣乘法的做法不一樣,C++的乘法來自一般數學課程對矩陣乘法的定義,webgl的引擎的乘法來自three.js的矩陣乘法,再來是我觀察unity3d也是使用第二種乘法,這時的我才發現原來矩陣的乘法有2種,一種是row*col另一種則是col*row。


後記

  這兩種乘法的差異不只會引響引擎的乘法而已,想想看shader裡面的矩陣乘法也會有影響!所以決定好其中一種,並記住乘法是屬於哪一種的,這樣轉code的時候就不會被到底師第一種乘還是第二種乘所迷惑了!