冯乐乐 unity_Unity常用矩阵运算的推导补遗——切线空间

本文补充了Unity中切线空间的构建和转换矩阵的细节,探讨了法线贴图、切线、副切线在坐标变换中的作用。通过TBN矩阵,解释了如何将向量从切线空间转换到其他坐标空间,并指出在处理非标准缩放时的注意事项。同时,文章纠正了之前关于副切线计算的错误,并展示了如何从高度图反推出法线图。
摘要由CSDN通过智能技术生成

在上一篇文章中,我写了一些关于Unity中各个坐标空间及其转换矩阵是如何得到的,说实在的,我是那种“记忆需要依靠外部装置存储”类、如同《攻壳机动队》的电子脑一样的人,每次遇到问题了再去对着笔记慢慢翻找才是我的风格:

破晓:Unity中常用矩阵的推导​zhuanlan.zhihu.com
629fd5c905b1ffe8a3d4fb40e6077a0c.png

在文章中我漏了一个本该提到的内容,那就是切线空间。

一般在法线贴图中,颜色都是偏蓝的,按照颜色空间和坐标空间的对应来看,z值一般都很大,大部分情况下,都是接近垂直于物体表面的。

如果是不需要法线贴图的情况下还好说,用NORMAL语义可以直接从顶点获得模型空间下的法线,如果要使用法线贴图?那就需要切线空间了。

常识告诉我们,构建一个空间笛卡尔直角坐标系需要三个互相垂直的基向量,而常识又告诉我们,两个向量的叉乘结果垂直于这两个向量构成的平面,故我们可以用两个向量完成切线空间的构建。

一个就是法线(Normal),一个是切线(Tangent),其叉乘结果为副切线(Bitangent)或者副法线(Binormal),这两种叫法我都看到过。以Unity官方的Shader例子举例:

v2f vert (float4 vertex : POSITION, float3 normal : NORMAL, float4 tangent : TANGENT, float2 uv : TEXCOORD0)
{
    
    v2f o;
    //...
    half3 wNormal = UnityObjectToWorldNormal(normal);
    half3 wTangent = UnityObjectToWorldDir(tangent.xyz);
    // 计算其方向
    half tangentSign = tangent.w * unity_WorldTransformParams.w;
    // 用世界空间下的法线、切线做叉乘,得到副法线
    half3 wBitangent = cross(wNormal, wTangent) * tangentSign;
    // 得到转换矩阵
    o.tspace0 = half3(wTangent.x, wBitangent.x, wNormal.x);
    o.tspace1 = half3(wTangent.y, wBitangent.y, wNormal.y);
    o.tspace2 = half3(wTangent.z, wBitangent.z, wNormal.z);
    //...
    return o;
}

fixed4 frag (v2f i) : SV_Target
{
    
    // 从法线贴图里采样并解码法线
    half3 tnormal = UnpackNormal(tex2D(_BumpMap, i.uv));
    // 从切线空间转换到世界空间
    half3 worldNormal;
    worldNormal.x = dot(i.tspace0, tnormal);
    worldNormal.y = dot(i.tspace1, tnormal);
    worldNormal.z = dot(i.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值