zoukankan      html  css  js  c++  java
  • shader之法线变换

    对于法线变换,进行非统一缩放时,如果使用跟变换顶点相同的变换矩阵来变换法线,则会得到错误的结果,即变换后的法线方向与平面不再垂直。

    如何求得变换法线的矩阵呢:

    转载请注明出处:http://www.cnblogs.com/jietian331/p/7047370.html

    假设空间a中的某点的切线Ta和法线Na,空间a转换到空间b的矩阵Ma->b,则Ta转换到空间b中后为:T= Ma->bTa,求将法线从空间a转换到空间b的矩阵?

    设此矩阵为G,设Na转换到空间b后为Nb,则在空间b中满足:

    Tb* Nb=0

    由于:

    T= Ma->bTa

    Nb = GNa

    所以可得:

    (Ma->bTa)T(GNa) = 0

    推导得:

    TaTMa->bTGNa = 0

    由于在空间a中满足:

    (Ta)TN= 0

    所以

    Ma->bTG = I

    可得出:

    G = (Ma->bT)-1 = (Ma->b-1)T

    如果变换不包含非统一缩放,则Ma->b是正交矩阵,满足 Ma->b-1=Ma->bT,若统一缩放系数为 k,则

    G = Ma->b / k

    否则,则必须求解逆矩阵来得到变换法线的矩阵。

    如UnityCG.cginc中的法线变换函数如下:

    // Transforms direction from object to world space
    inline float3 UnityObjectToWorldDir( in float3 dir )
    {
        return normalize(mul((float3x3)unity_ObjectToWorld, dir));
    }
    
    // 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
    }
  • 相关阅读:
    大作文-学以”成人”
    方案类--博物院整改意见
    归纳概括-我国中小学开展研学旅行活动的特点
    短文-网络新一代
    短评
    讲话稿-文明素养教育主题宣传
    检验用户单点登录方案解决
    Spring @Transactional注解
    RPC-局限于java的RMI
    Redis缓存雪崩、击穿、穿透的问题和解决方式
  • 原文地址:https://www.cnblogs.com/jietian331/p/7047370.html
Copyright © 2011-2022 走看看