Unity Shader Lab 模型切线和法线

DCC和unreal中的法线与切线

(maya)

 绿:法线, 红:切线, 蓝:副切线(ue4)

uv channel 0

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

三根法线合一,为相邻三个面法线的平均,在shader中视作一个点,

与相邻面法线 同向,unreal视作三个点,可能因为一个点对应的inputlayout(顶点缓冲布局) 只对应一组 NORMAL语义,

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

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

法线变换,非均匀缩放:

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

法线的计算

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

《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函数参数顺序,会转置该逆矩阵)。

   

 

        

        

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值