青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

麒麟子

~~

導航

<2010年12月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

統計

常用鏈接

留言簿(12)

隨筆分類

隨筆檔案

Friends

WebSites

積分與排名

最新隨筆

最新評論

閱讀排行榜

評論排行榜

HLSL中的MUL指令深層剖析

原作者郵箱 BoYueGame#Gmail#com 歡迎交流。

此貼可以隨意轉載而不用注名出處。但也別說是你寫的就行。

在讀此文之前,讀者應該知道什么是行主,列主矩陣,寫過簡單的HLSL或者ASM SHADER

讀者知道簡單的矩陣運算規則

本文主要內容有:

一、部分背景內容

二、HLSL中的row-major matrix picking and column-major matrix picking

三、MUL規則

四、觀察矩陣的另類解釋和TBN空間的類推

五、HLSL中矩陣的構造(為什么WorldToTargentSpaceMatrix要左乘LightDir)

 

一、部分背景

既然是HLSL中的指令,那我們的所有標準就以D3D而來。換句話說,矩陣以如下方式存儲

11 12?。保场。保?

21?。玻病。玻场。玻?

31?。常病。常场。常?

41?。矗病。矗场。矗?

典型的世界矩陣如下

C1 C2 C3 C4

R1 1  0 0  0

R2 0  1  0  0

R3 0 ?。啊 。薄 。?

R4 20?。玻啊。玻啊。?

這就是傳說中的行主矩陣(row-major matrix) 注:這里只說它的存儲方式,而不管他的運算符操作方法。

對于一個這樣的矩陣,我們給一個行向量(row vector) V(X,Y,Z,W)

那么,V*M為如下結果

X = X*11+Y*21+Z*31+W*41?。ǎ保?

Y = X*12+Y*22+Z*32+W*42?。ǎ玻?

Z = X*13+Y*23+Z*33+W*43?。ǎ常?

W = X*14+Y*24+Z*34+W*44?。ǎ矗?

看到上面的1,2,3,4四個運算,我們很自然想到了向量點乘(Dot Product)我們把三維向量的點乘簡稱dp3,四維的則叫dp4 那么有

dp3(V1,V2)= V1.x*V2.x+V1.y*V2.y+V1.z*V2.z

dp4(V1,V2)= V1.x*V2.x+V1.y*V2.y+V1.z*V2.z+V1.w*V2.w

于是,我們的向量V乘矩陣M就可以表示為

V.X = dp4(V,M[C1]);

V.Y = dp4(V,M[C2]);

V.Z = dp4(V,M[C3]);

V.W = dp4(V,M[C4]);

說了這么多,好像不是在說MUL指令,但其實這個MUL指令息息相關。

首先來看看Mul(x,y)指令的最基本的信息。

當X為向量時,X被視為行向量。

當Y為向量時,Y被視為列向量。

大家都知道,在HLSL中,如果我們采用Effect::SetMatrix進行矩陣的設置時,我們就可以采用如Mul(inPos,matWorldViewProj)來計算?!《绻怯闷胀ǖ腟etVertexConstantF等來設置矩陣數據的話,就需要用Mul(matWorldViewProj,inPos)來計算,或者用

Mul(inPos,matWorldViewProjTranspose)。

我想許多人都明白,那是因為在用SetMatrix時,HLSL會將矩陣進行轉置,進而成為一個列矩陣。自然,采用SetMatrix與不采用SetMatrix就不一樣了。

可是,我們之前不是說了么,行向量乘以行主矩陣才是 向量在左邊呀, 但現在一個是行向量,一個是列矩陣。 怎么就繞不過來了呢。 

其實很容易繞過來,要知道MUL是我們(或者說叫他們)自己定義的,怎么實現難道還非得按照標準的線性代數規則來安排位置不成。用HLSL寫過SHADER的人都應該清楚下面這段代碼的含義。

float4x4 matViewProjection;

float4 vs_main(float4 Position : POSITION0) : POSITION0

{

return mul( Input.Position, matViewProjection );

}

//其對應的匯編代碼如下

// matViewProjection c0 4

//

vs_2_0

dcl_position v0

dp4 oPos.x, v0, c0

dp4 oPos.y, v0, c1

dp4 oPos.z, v0, c2

dp4 oPos.w, v0, c3

是不是覺得dp4很親切呢。對了,就是它?!∵@意思就是說,我們的c0,c1,c2,c3存放著我們先前講到的C1 C2 C3 C4?!∵@就是我們的背景內容,到此結束?!∠旅鎸⒄归_一系列的為什么。

而如下的HLSL代碼

float4x4 matViewProjection;

float4 vs_main(float4 Position : POSITION0) : POSITION0

{

return mul(matViewProjection,Input.Position );

}

對應的ASM SHADER如下

mul r0, v0.y, c1

mad r0, c0, v0.x, r0

mad r0, c2, v0.z, r0

mad oPos, c3, v0.w, r0

由此可以看出 此時的C0-C3存放的是一個行矩陣。在此僅為證明 mul(向量,矩陣) 與 mul(矩陣,向量)不是一個東西。

二、HLSL中的row-major matrix picking and column-major matrix picking

HLSL在將矩陣賦值給常量寄存器的時候。有兩種方式,一種是每個常量寄存器存放一行的數據,另一種是每個常量寄存器存放著一列的數據。默認是按列選取(column-major matrix picking)?!?

假設有一個矩陣M,其存放位置是從C0寄存器開始。 那么如果我們按行選?。╮ow-major picking)則有

C0 = 11 12 13 14

C1 = 21 22 23 24

C2 = 31 32 33 34

C3 = 41 42 43 44

如果我們按列選取(col-major picking)則有

C0 = 11 21 31 41

C1 = 21 22 32 42

C2 = 31 32 33 43

C3 = 41 42 43 44

三、MUL規則

有了上面的的了解,我們就可以很容易地知道,MUL到底用什么。當然是取決于這兩種選取規則。下面我們就逐一討論?!≡诖艘廊灰暶饕幌?, 我們程序中的矩陣是按D3D標準存放。

1、采用SetMatrix, 采用按列選?。╟ol-major picking)

在這樣的方式下,若我們將C0-C3按如下排開

C0

C1

C2

C3

則它是一個轉入矩陣的轉置矩陣。即Cx為先前矩陣的x列

而由我們先前提到的MUL(向量,矩陣)的ASM代碼可以得出?!∵@正是我們想要的。

dp4 oPos.x, v0, c0

dp4 oPos.y, v0, c1

dp4 oPos.z, v0, c2

dp4 oPos.w, v0, c3

于是,在這種方式下,我們采用的是MUL(向量,矩陣)

2、采用SetMatrix,采用按列選取(row-major picking)

在這樣的方式下,我們得到的和設置前的矩陣一樣?!∮纱丝磥?,我們得到的矩陣與按行存儲的矩陣剛剛是一個轉置。 既然是這樣,那大家回憶一下矩陣運算法則

A*B ó BT*AT

這里若A*B對應的是Mul(向量,矩陣).  其中A為行向量即1Xn的矩陣,矩陣為nXm

那么Mul(矩陣,向量)則真好對應了上面的公式。

注:當向量作為第二個參數是,是一個列向量,即n X 1矩陣

所以,在這種方式下我們采用的是Mul(矩陣,向量)

3、不采用SetMatrix,采用按列選擇。

在這樣的方式下,相對于一方按,得到的矩陣和2方案相同。

4、不采用SetMatrix,采用按行選擇.得到的矩陣和1方案相同。

四、觀察矩陣的另類解釋和TBN空間的類推

在D3D SDK文檔中有一份這樣的公式。講述的是

D3DXMatrixLookAtLH

函數生成的東西。(這是一個左手觀察系,采用D3D的行矩陣方式存儲)

zaxis = normal(At - Eye)
xaxis = normal(cross(Up, zaxis))
yaxis = cross(zaxis, xaxis)
 
       C1              C2                 C3             C4  
 R1 xaxis.x           yaxis.x           zaxis.x          0
 R2 xaxis.y           yaxis.y           zaxis.y          0
 R3 xaxis.z           yaxis.z           zaxis.z          0
R4 -dot(xaxis, eye)  -dot(yaxis, eye)  -dot(zaxis, eye)  l
 
 
 
計算機圖形學書上也講了如何推導這個矩陣。但貌似依然沒有給出為什么這樣寫就構成了觀察矩陣了。
 
        首先明白觀察矩陣的目的是:將一個世界空間的坐標轉換到觀察坐系中。 即將一個由X,Y,Z軸構成的世界空間的坐標點調整到由攝相機的 上向量、觀察方向、右向量的空間中。 在這里,攝相機的右向量(上向量與觀察方向的叉乘)等同于世界坐標系中的X軸?!∩舷蛄康韧赮軸,觀察方向等同于Z軸。
 
然后,我們試著拿一個點與這個矩陣相乘。
V0*matView
按背景知識中講到的,我們得到的一個點V1是。
V1.x = V0.x·matView[C1]
V2.y = V0.y·matView[C2]
V3.z = V0.z·matView[C3]
V4.w = V0.w·matView[C4]
 
上面式子中 ·表示dp4
 
在中學的時候我們就學過,點乘表示一個向量在另一個向量上的投影。好吧,我們要的就是這東西。
clip_image002
上面的圖中(圖太丑了,見笑) AD即為AC在AB上的投影。
而-dot(xaxis, eye)  -dot(yaxis, eye)  -dot(zaxis, eye) 則是因為攝相機并不在原點,而我們在做投影變換的時候,以原點為觀察參考點會簡化很多工作。所以我們的頂點要先把自己移回原點才行。而移的多少,正好是原點到攝相機的位置構成的一個向量在自己各個軸上的投影。
 
于是,我們可以知道,乘以觀察矩陣, 就相當于是把一個點以原點為起點,自己為終點,構造一個向量,然后求出自己在由攝相機的各個軸構上的投影。最后再根據攝相機位置移回原點的過程?!∮捎谖一旧喜粫媹D,所以大家看起來有些吃力了。請各位見諒?!〉@并不是什么復雜的事情,只要用上點乘是投影的這個理念,自然就想明白了。
 
而我們模型中的T B N信息。按以下方式構造出來的矩陣,則剛好是由模型空間到切線空間的轉換。
 
Tx Bx Nx
Ty By Ny
Tz Bz Nz
 

五、HLSL中矩陣的構造(為什么WorldToTargentSpaceMatrix要左乘LightDir)

在我們的NormalMapping等需要轉換到切線空間的映射中,常常看到這樣的代碼

Float3x3 matWorldToTargent = {WorldT,WorldB,WorldN};

又或者

Float3x3 matWorldToTargent;

matWorldToTargent[0] = WorldT;

matWorldToTargent[1] = WorldB;

matWorldToTargent[2] = WorldN;

//float3 LightDir;

LightDirInTS = mul(matWorldToTargent,LightDir);

我也看到網上許多人問這個問題,并且我先前也不是懂。 因為看到的HLSL代碼中,并沒有出現row-major matrix picking和column-major matrix picking轉換的代碼,也就是說,默認為column-major matrix picking。 當然會想到,我們構造出來的矩陣,其對應的寄存器值正好是

Cx = WorldT;

Cx+1 = WorldB;

Cx+2 = WroldN;

所以,它剛好是
Tx Bx Nx
Ty By Ny
Tz Bz Nz

的轉置,

Tx Ty Tz

Bx By Bz

Nx Ny Nz

應該用LightDirInTS = mul(LightDir,matWorldToTargent);才對。

顯然,我們被眼睛深深的欺騙了。

請看如下代碼

float4x4 mat;

mat[0] = float4(1,2,3,4);

mat[1] = float4(5,6,7,8);

mat[2] = float4(9,10,11,12);

mat[3] = float4(13,14,15,16);

mul(mat,inPos);

對應的是

def c4, 1, 2, 3, 4

def c5, 5, 6, 7, 8

def c6, 9, 10, 11, 12

def c7, 13, 14, 15, 16

而若將指令改為mul(inPos,mat); 那么常量存放的值為

def c4, 1, 5, 9, 13

def c5, 2, 6, 10, 14

def c6, 3, 7, 11, 15

def c7, 4, 8, 12, 16

并且,上面的數據與HLSL中的矩陣數據picking方式無關。而對矩陣的操作,則都為dp4 pos,cx,也就是說對于mul(inPos,mat);的情況,相當于是將其轉置,再進行dp4操作?!《鴮τ趍ul(mat,inPos);則是直接進行dp4操作?!《次覀兿胍模瑒t第一種情況才滿足條件。 第二種是因為優化導致的先轉置再dp4,與前面提到的不轉置進行類似于下面的操作是一樣的。

mul r0, v0.y, c1

mad r0, c0, v0.x, r0

mad r0, c2, v0.z, r0

mad oPos, c3, v0.w, r0

若我們認定HLSL中構造矩陣是一個常量寄存器裝一個mat[i]。即第一種情況?!∧敲创藭r想當于得到的是未經轉置的矩陣,我們則認為,T B N在構造后,形成的是一個

Tx Ty Tz

Bx By Bz

Nx Ny Nz

mul(mat,inPos);剛好滿足要求。

若我們認定HLSL中構造矩陣的時候,一個常量寄存器不是裝一個mat[i] 面是將構造他的float4的各個分量分別存?!〖吹诙N情況。那么得到的便是

Tx Bx Nx
Ty By Ny
Tz Bz Nz
 

我們想要它實現轉換,則必須轉置?!《葾*B ó BT*AT ,可知,mul(mat,inPos)即為所求。

 
第二種認定方案是比較容易讓人接受的方案。
花了三個小時的時間來總結這幾天糾結的問題,總算有一個收場。 其實還有一些關于RenderMonkey的問題,而有了上面的理解了,那些已經不是問題了。待有空再繼續總結。

posted on 2010-12-28 00:05 麒麟子 閱讀(3439) 評論(0)  編輯 收藏 引用 所屬分類: GPU and Graphic

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            在线视频精品| 午夜精品视频网站| 国产欧美日韩免费| 国产精品色婷婷| 国产一区二区日韩| 在线欧美日韩精品| 亚洲精品资源美女情侣酒店| 99精品热视频只有精品10| 亚洲欧美日韩国产综合| 午夜精品婷婷| 免费观看一区| 野花国产精品入口| 欧美在线91| 欧美女主播在线| 国产视频久久久久久久| 亚洲国产毛片完整版| 中文日韩电影网站| 久久网站免费| 日韩亚洲欧美成人| 久久久久综合网| 国产精品xvideos88| 在线观看日韩国产| 香蕉av福利精品导航| 亚洲国产成人久久| 9人人澡人人爽人人精品| 久久精品一二三区| 国产精品成人一区| 亚洲午夜羞羞片| 午夜视频精品| 欧美一级网站| 欧美国产精品日韩| 香蕉久久国产| 国产精品海角社区在线观看| 欲香欲色天天天综合和网| 亚洲一区二区在线免费观看| 欧美电影在线观看完整版| 亚洲免费一区二区| 欧美视频一区二区三区…| 亚洲欧洲中文日韩久久av乱码| 久久国产成人| 亚洲自拍16p| 国产精品v日韩精品| 日韩一级片网址| 欧美激情视频免费观看| 久久久午夜精品| 国语精品中文字幕| 久久久女女女女999久久| 亚洲直播在线一区| 国产精品久久久久久久浪潮网站 | 久久三级视频| 亚洲午夜一区二区三区| 欧美日韩免费一区| 99精品欧美一区二区蜜桃免费| 欧美大片在线观看一区二区| 久久久久久高潮国产精品视| 国产日韩欧美日韩大片| 欧美在线视频在线播放完整版免费观看 | 亚洲国产精品一区在线观看不卡| 欧美专区福利在线| 国产午夜一区二区三区| 久久精品99久久香蕉国产色戒 | 欧美日韩国产综合久久| 亚洲精品日产精品乱码不卡| 欧美激情第二页| 欧美mv日韩mv亚洲| 99re热精品| 一区二区三区波多野结衣在线观看| 欧美日韩亚洲激情| 亚洲欧美日韩一区| 欧美一级大片在线观看| 国内一区二区在线视频观看| 免费观看在线综合| 欧美 日韩 国产在线| 99成人在线| 亚洲一级片在线观看| 国产日韩欧美在线播放不卡| 久久免费国产| 欧美极品aⅴ影院| 亚洲免费影院| 久久精品国产2020观看福利| 91久久精品国产91久久性色| 禁久久精品乱码| 亚洲激情专区| 亚洲免费观看高清在线观看| 欧美性视频网站| 久久久国产午夜精品| 暖暖成人免费视频| 先锋影音久久久| 美女主播精品视频一二三四| 亚洲永久免费观看| 久久精品国产第一区二区三区最新章节| 亚洲成人在线| 亚洲午夜在线观看| 最新中文字幕一区二区三区| 宅男66日本亚洲欧美视频| 有坂深雪在线一区| 中国女人久久久| 最新国产精品拍自在线播放| 亚洲综合日韩在线| 最新高清无码专区| 久久精品国产99国产精品澳门| 一区二区冒白浆视频| 久久免费视频这里只有精品| 亚洲欧美日韩中文在线制服| 欧美aaa级| 老牛国产精品一区的观看方式| 欧美性猛交xxxx乱大交退制版 | 国模精品一区二区三区色天香| 91久久精品网| 在线播放中文一区| 午夜精品久久久久久久99热浪潮| 最新日韩精品| 久久这里只有精品视频首页| 欧美中文字幕视频| 国产精品国产精品| 亚洲美女av黄| 亚洲人在线视频| 久久在线视频在线| 蜜臀99久久精品久久久久久软件| 国产麻豆午夜三级精品| 一区二区欧美日韩视频| 99精品热6080yy久久| 久热国产精品| 欧美成人黑人xx视频免费观看| 国内精品嫩模av私拍在线观看| 亚洲欧美日韩国产综合精品二区| 在线亚洲成人| 欧美吻胸吃奶大尺度电影| 亚洲日本国产| 亚洲精品在线二区| 欧美日韩福利| 99在线精品视频| 亚洲一区二区三区影院| 国产精品成人播放| 亚洲尤物影院| 久久久人成影片一区二区三区观看| 国产伦精品一区二区三区高清版 | 亚洲一区二区三区中文字幕在线 | 亚洲欧美国产高清va在线播| av不卡在线看| 六月婷婷一区| 亚洲高清久久网| 亚洲精品综合久久中文字幕| 欧美激情黄色片| 一本色道88久久加勒比精品| 亚洲午夜影视影院在线观看| 国产精品久久久久久久免费软件 | 亚洲欧洲av一区二区| 久久九九国产精品怡红院| 国外成人网址| 欧美高潮视频| 一区二区三区视频观看| 午夜精品久久久久久久99热浪潮| 国产精品自拍小视频| 久久精品视频一| 亚洲精品网站在线播放gif| 亚洲欧美国产毛片在线| 国产偷国产偷亚洲高清97cao| 久久久久久日产精品| 亚洲人线精品午夜| 欧美伊人久久久久久久久影院 | 久热成人在线视频| 91久久嫩草影院一区二区| 欧美日韩在线一区二区| 香蕉久久精品日日躁夜夜躁| 欧美插天视频在线播放| 宅男噜噜噜66一区二区| 国产视频一区在线| 欧美激情精品久久久久久| 亚洲欧美一区二区三区久久| 欧美激情亚洲国产| 羞羞色国产精品| 亚洲美女诱惑| 国产视频一区二区三区在线观看| 免费成人激情视频| 亚洲欧美日韩精品久久久| 亚洲国产欧美不卡在线观看| 欧美一区二区三区四区在线观看| 一区二区三区中文在线观看| 欧美性大战久久久久久久蜜臀| 另类av一区二区| 欧美一级成年大片在线观看| 99视频一区二区三区| 欧美激情中文字幕一区二区| 久久精品综合一区| 亚洲欧美在线高清| av成人免费在线观看| **网站欧美大片在线观看| 国产精品一区二区三区成人| 欧美日韩精品免费观看视频| 蜜臀av性久久久久蜜臀aⅴ四虎| 午夜欧美电影在线观看| 99在线精品视频| 亚洲精品美女久久久久| 欧美 日韩 国产一区二区在线视频| 小处雏高清一区二区三区| 亚洲视频二区| 正在播放亚洲一区| 亚洲精品资源美女情侣酒店| 亚洲黄色性网站|