Last active
October 15, 2020 03:05
-
-
Save reinsteam/9e291ed75925eb74d827 to your computer and use it in GitHub Desktop.
Snippet to calculate TBN basis from quaternion in 8 instructions (seems like this one is used at Crytek: http://www.crytek.com/download/izfrey_siggraph2011.pdf)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*---------------------------------------------------------------------------------------------------------------------- | |
Custom cross-product: mad + mul | |
----------------------------------------------------------------------------------------------------------------------*/ | |
half3 crs(half3 v0, half3 v1) | |
{ | |
//return cross(v0, v1); | |
half3 v0_0 = v0.yzx; | |
half3 v0_1 = v1.zxy; | |
half3 v1_0 = v0.zxy; | |
half3 v1_1 = v1.yzx; | |
return v0_0 * v0_1 - (v1_0 * v1_1); | |
} | |
/*---------------------------------------------------------------------------------------------------------------------- | |
Tangent and BiTangent computation takes 6 instructions : add, mul, mad, mad, mad, mad | |
Normal computation takes 2 instructions (crs prod) : mul, mad | |
----------------------------------------------------------------------------------------------------------------------*/ | |
half3x3 tbn_from_quat_1(half4 quat) | |
{ | |
half3x3 tbn; | |
half4 dquat = (quat + quat); | |
half4 wquat = (quat + quat) * quat.w; | |
half3 tbn_t_0 = (quat.xyz * dquat.xxx) + half3(-1.0, 0.0, 0.0); | |
half3 tbn_b_0 = (quat.xyz * dquat.yyy) + half3(0.0, -1.0, 0.0); | |
half3 tbn_t_1 = (wquat.wzy * half3(1.0, -1.0, 1.0)) + tbn_t_0; | |
half3 tbn_b_1 = (wquat.zwx * half3(1.0, 1.0, -1.0)) + tbn_b_0; | |
tbn[0] = tbn_t_1; | |
tbn[1] = tbn_b_1; | |
tbn[2] = crs(tbn_t_0, tbn_b_0); | |
return tbn; | |
} | |
/*---------------------------------------------------------------------------------------------------------------------- | |
Tangent and BiTangent computation takes 6 instructions : add, mul, mad, mad, mad, mad | |
Normal computation takes 2 instructions : mad, mad | |
----------------------------------------------------------------------------------------------------------------------*/ | |
half3x3 tbn_from_quat_2(half4 quat) | |
{ | |
half3x3 tbn; | |
half4 dquat = (quat + quat); | |
half4 wquat = (quat + quat) * quat.w; | |
half3 tbn_t_0 = (quat.xyz * dquat.xxx) + half3(-1.0, 0.0, 0.0); | |
half3 tbn_b_0 = (quat.xyz * dquat.yyy) + half3(0.0, -1.0, 0.0); | |
half3 tbn_n_0 = (quat.xyz * dquat.yyy) + half3(0.0, 0.0, -1.0); | |
half3 tbn_t_1 = (wquat.wzy * half3(1.0, -1.0, 1.0)) + tbn_t_0; | |
half3 tbn_b_1 = (wquat.zwx * half3(1.0, 1.0, -1.0)) + tbn_b_0; | |
half3 tbn_n_1 = (wquat.yxw * half3(-1.0, 1.0, 1.0)) + tbn_n_0; | |
tbn[0] = tbn_t_1; | |
tbn[1] = tbn_b_1; | |
tbn[2] = tbn_n_1; | |
return tbn; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment