Unity Shader Lab 模型切线和法线

DCC和unreal中的法线与切线

Unity Shader Lab 模型切线和法线_第1张图片(maya)

 Unity Shader Lab 模型切线和法线_第2张图片绿:法线, 红:切线, 蓝:副切线(ue4)

Unity Shader Lab 模型切线和法线_第3张图片uv channel 0

法线由DCC软件确定,一般使用两种:(该点为三根线的端点)

Unity Shader Lab 模型切线和法线_第4张图片三根法线合一,为相邻三个面法线的平均,在shader中视作一个点,

Unity Shader Lab 模型切线和法线_第5张图片与相邻面法线 同向,unreal视作三个点,可能因为一个点对应的inputlayout(顶点缓冲布局) 只对应一组 NORMAL语义,

切线(作为切线空间的x轴)方向必定与法线方向垂直,并且与uv坐标的 u轴在垂直法线的平面的投影向量 同向,

Unity Shader Lab 模型切线和法线_第6张图片裁UV 导致一个点有多个方向切线和副法线,导入unreal 一个点直接算作多个点,保证一个点 对应一组 normal,tangent,binormal(上图 由于裁UV 25个点变30个点)

法线变换,非均匀缩放:

制作模型确定顶点法线,同时由法线确定切线,导入unreal 此时 法线和切线必定垂直,但缩放Unity Shader Lab 模型切线和法线_第7张图片(模型空间)
在unity中 对模型进行非均匀缩放(上图1/4缩小),
a. 左点:法线与临近的面法线同向,要求变换时依旧保持与 面法线同向
                切线 则 与该面平行
        缩放后,两法线失效,两切线依旧保持 与面平行,
b. 右点:法线是个平均值(与重心距离加权),在此处,渲染时 是光滑过渡,
        缩放后,切线方向,仍然由面确定,
        Unity Shader Lab 模型切线和法线_第8张图片

法线的计算

渲染时,需要计算光照,需要 世界空间的 顶点或像素的法线方向,由于模型可能存在非均匀缩放,所以不能使用 (float3x3) _Object2World矩阵,

Unity Shader Lab 模型切线和法线_第9张图片《unityshader入门精要》

 若M1 *M2 *M3 =M1* M3, 则M2为单位矩阵,设M1 为[ aij ] M2 为[ bij ] M3为 [ cij ] 直接相乘,就能找到规律。

所以 要使用:模型到世界矩阵 的逆 的转置

UnityObjectToWorldNormal()

// Transforms normal from object to world space
inline float3 UnityObjectToWorldNormal( in float3 norm )
{
#ifdef UNITY_ASSUME_UNIFORM_SCALING
    return UnityObjectToWorldDir(norm);
#else
    // mul(IT_M, norm) => mul(norm, I_M) => {dot(norm, I_M.col0), dot(norm, I_M.col1), dot(norm, I_M.col2)}
    return normalize(mul(norm, (float3x3)unity_WorldToObject));
#endif
}

// Transforms direction from object to world space
inline float3 UnityObjectToWorldDir( in float3 dir )
{
    return normalize(mul((float3x3)unity_ObjectToWorld, dir));
}

若均匀缩放,则直接使用UnityObjectToWorldDir()

若非均匀缩放,则乘以逆矩阵的转置(此处mul函数参数顺序,会转置该逆矩阵)。

   

 

        

        

你可能感兴趣的:(unity,shaderlab,unity)