2021年10月26日 星期二
2021年10月25日 星期一
右手座標和左手座標的資料交換
如果有1個建模軟體是右手座標系
首先
在建模軟體裡成生1個假的左手座標系 W
(就是生成1組3軸和原點,視你引擎的需要來定義)
mesh的部分
把資料變換到該座標系 W
(透過world To Local transform 幾何意義)
資料可能是
- 頂點vertexs
- 法向量normal
- 切向量tangent (轉換tangent.xyz之外, tangent.w 也要乘上1個負號 )
這樣一來 在座標系W 裡的 local 資料
就能直接拿出去給左手的引擎使用
也能在建模軟體正確的顯示
(透過local To World transform 幾何意義)
bone的部分
bone其實就是階層式的座標系
(也就是階層式的matrix)
Bn代表第n個bone
- 每個Bn其實可以寫成1個 bone matrix Mn
- 已經和parent bone matrix相乘的叫=> Mn_world
- 還沒和parent bone的matrix相乘的叫 => Mn_local
- matrix同時有S(縮放)、R(旋轉)、T(位移) 3個資訊
- R(旋轉)矩陣 等價於「1個繞軸旋轉」可以用「1個四元數」來表示
- S(縮放)矩陣 等價於 vS = (Sx,Sy,Sz)
- T位移 等價於 vP = (Px,Py,Pz)
我想到的方法是
- (步驟1)把Mn_world轉換成對映的 Qn_world 、vSn_world、vPn_world
- (步驟2)把Qn_world 、vSn_world、vPn_world變換到座標系 W 得到 (為什麼?)
- Qn_world_w
- vSn_world_w
- vPn_world_w
- 在座標系 W裡 把上面3個東西轉換為Mn_world_w
- 在座標系 W裡 重建 Mn_world_w的階層關系得到Mn_local_w
- export的時候再把Mn_local_w轉成
- Qn_local_w
- vSn_local_w
- vPn_local_w
上面的(步驟2) 把matrix拆成3種分量做轉換是因為考慮到
- 如果直接轉換matrix 會像這樣 圖示 (W座標系其實和建模世界的world重疊,但為了好比較,所以畫的時候偏移了一下)
- bone代表的3軸並沒有變成左手的
- 如果是先透過 四元數(繞軸旋旋)來轉換
- 就會像這樣 圖示
- ⚠️只是如果Sx,Sy,Sz都不一樣,轉換後scale 還要把Sy,Sz做交換
這麼說來
(步驟1)(步驟2)
改成直接轉換Mn_world到Mn_world_w 圖示
再交換bone的y軸、z軸也是可以的(但縮放不交換)
W座標系
根據 圖示 以row-major寫出 W座標系就是(用column-major其實會得到1樣的結果)
W=
1 0 0
0 0 1
0 1 0
因為W只是旋轉矩陣
W的逆=W的transpose=W
1 0 0
0 0 1
0 1 0
(x,y,z)W =(x,z,y)
所以轉換mesh的
- 頂點
- 法向量
- 切向量
到W座標系
實際上做的也只是交換y,z值而已
如何根據uv計算出頂點的Tangent
https://photos.app.goo.gl/1Nj8ojgitocw5iSu7
下面是詳細過程
三角形的頂點是A、C、B、對映到的uv座標是a、b、c
uv座標的2個軸是u-axis、v-axis向量
a= (a.u,a.v) 代表
從uv座標的原點 o=(0,0)出發
沿著u-axis軸移動 a.u 長度、再沿著v-axis軸移動a.v長度,會到達點a
o + u-axis✖️a.u + v-axis✖️a.v = a
b和c也是類似的
o + u-axis✖️b.u + v-axis✖️b.v = b
o + u-axis✖️c.u + v-axis✖️c.v = c
這有什麼用呢?
現在換看頂點ACB
想像ACB會在同1個平面上P,然後再想像P上會有1個原點D
一開始我們不知道D的實際位置
但我們可以模仿uv空間
o + u-axis✖️a.u + v-axis✖️a.v = a
寫出
D + T✖️a.u + BN✖️a.v = A
D + T✖️b.u + BN✖️b.v = B
D + T✖️c.u + BN✖️c.v = C
再來只要解上面3個聯立方程式,就能找出tangent了
https://photos.app.goo.gl/1UVE8M3LQBSwupPm8
T.w就是Peek tangent in Unity裡的w
建模軟體要怎麼判定tangent.w的正負?連結
2017年5月18日 星期四
Why Object having NormalMap material can do mirror in Unity 5
4 case (make 3 real-axis look like match right hand rule)
它們都做了奇數次的鏡射(odd times mirror)
3 case (make 3 real-axis still match left hand rule)
它們都做了偶數次的鏡射(even times mirror)
在奇數次的鏡射的情況(in odd times mirror)
要再多改變一次tangent的方向(swap y again)
Unity乘上unity_WorldTransformParams.w應該就是這個原因
但Unity怎麼計算出unity_WorldTransformParams.w?
我猜可能像這樣...
方法(1)
transform has LossyScale(the global scale of object)
unity_WorldTransformParams.w=sign(LossyScaleX*LossyScaleY*LossyScaleZ)
方法(2)
transform has right ,
up , forward
但是right,up ,forward並不會反應出scale設為負值後的方向改變
所以必須乘上lossyScale
(也就是光看right,up,forward看不出3軸有沒有match right hand rule )
檢查cross(real_right ,real_up)和real_forward
是不是同向,決定[鏡射因子]
Vector3 real_right=LossyScaleX*right;Vector3 real_up=LossyScaleY*up;Vector3 real_forward=LossyScaleZ*forward;unity_WorldTransformParams.w=sign(dot(cross(real_right,real_up),real_forward));
2017年5月16日 星期二
Peek tangent in Unity
Unity use cross(v.Normal,v.tangent)*v.tanget.w
to find biNormal
I guess v.tanget.w=-1 in general situation
and v.tangetw=1 in mirror situation
then I try some test
in 3dsmax (general situation)
in Unity w of tangent is -1
Normal Direction : red ball to green ball
Tangent Direction : red ball to blue ball
in 3dsmax (mirror situation)
in Unity w of tangent is 1
PS:
set Absolute Mode to see the UV
coordinate
訂閱:
文章 (Atom)








