Unity的unity_ObjectToWorld里的每一列分别代表什么意思?换个方向反向理解-更简单

官方关键UnityObjectToWorldNormal() 代码

从乐乐姐的书中得知,当我们在shader想获得法线,大概会这么些

o.wordDir = UnityObjectToWorldNormal(i.normal)

(这行代码就包含了官方对“unity_ObjectToWorld”的终极理解+极致应用)

也可以说,掌握了这行代码,就掌握了unity_ObjectToWorld

(这行代码的源码在楼下。。。)

这时候,肯定有一堆高人跳出来分析了, 这个很复杂,分两种情况,巴啦巴啦

我复杂个P,法线转世界坐标就复杂了??下面会一一展开说,甚至关键代码都是幼儿园数学,加减乘除而已

如下面代码,确实是if ... else .. ,也确实分两种“复杂”情况;

但是在大部分情况下,大部分的智商都差不多,所以都不要没搞懂一行代码逻辑,就if .. else ...去企图把两段代码都搞懂,反向一下逻辑很清楚的:如果两段代码是差不多,接近的,就会用一个方法传不同的参数解决。,而不是if .. else .. ;但既然用了if .. else ..解决, 也就是UnityObjectToWorldNormal()里的两段代码南辕北辙, 

那么问题来了?你是希望:

1.先把第一段代码搞懂,(而省下了读第两段代码时间,以至于有经历集中完全掌握关键代码?),

2.还是头铁,两段一起搞,每一段都搞不通,而且两段互调一起又加深混乱?

如楼下这段代码,我们只需要了解, 根本不用管第二种情况(有兴趣同学可课外自行研究)

normalize(mul (unity_objecttoWorld,dir))//这个方法即可

未知代码1

首先,请看下面代码,看不懂没关系的,(未知1)后面会补上幼儿园数学,加减乘除而已,只要上过小学就没问题,初中辍学也能懂,

这段1代码主要是要计算_19的结果,而输入的参数_7,我们从 layout(location ) _7大概就知道这是:法线(normal)

//代码1
layout(location = 1) in vec3 _7;
layout(set = 1, binding = 0, std140) uniform _23_25
{
    vec4 _m0[4];
    vec4 _m1[4];
    vec4 _m2[4];
    vec4 _m3;
} _25;

void main()
{
    _16.x = dot(_7, _25._m1[0u].xyz);
    _16.y = dot(_7, _25._m1[1u].xyz);
    _16.z = dot(_7, _25._m1[2u].xyz);
    _19 = dot(_16.xyz, _16.xyz);
    _19 = inversesqrt(_19);
}

未知代码2

因为未知1,所以我们需要未知2,还是不懂没关系的,请接着往下看,

(会越说越简单的)

//代码2

矢量 - 大概是这么一个东西

        var pos = new Vector3(1, 1.5, 1);

矩阵 - 是大概这么一个东西(3个矩阵相乘)

这个图不是矩阵最终结果

根据某大牛说的:

矩阵:模型顶点从模型空间转换到世界空间用的矩阵,就是unity_ObjectToWorld,那么这个矩阵的内容是什么呢,没错,就是这个模型相对于世界空间原点的缩放,旋转和平移

矩阵最后一列代表的是模型中心点的世界坐标

M - local2World 的三列分别是:

1.最后一列,第4列代表的是模型中心点的世界坐标(明显的最后一列是tx,ty,tx,1)

2.另外第1,2, 3列后面再说

由于我们知道1列1列是有含义的(最后一列是世界坐标(真不需要说模型中心点的,世界坐标就是世界坐标,台湾省难道有任何可能会不是中国台湾省么))

我们知道了列的含义

所以楼上的代码_25[0u] _25[1u], _25[2u]就分别代表了,第1,2,3列,而不是代表行

(后面证明是错了,0,1,2就是行的列,_25行[0,1,2]列,

是:

m1[1] m1[2] 25[3]

m2

m2

而不是
m[1] m2 m3

m[2]

m[3]

那么。。。localToWorld矩阵的第1,2,3列(行)到底是什么意思呢?

最简单的解释localToWorld

    _16.x = dot(_7, _25._m1[0u].xyz);
    _16.y = dot(_7, _25._m1[1u].xyz);
    _16.z = dot(_7, _25._m1[2u].xyz);

从楼上的代码(代码1)我们可知道

用法线 "_7" dot点乘 x 矩阵unity_objectToWorld "_25" 的第一列是什么意思呢

这里还做了3个dot

这里还做了3个dot

这里还做了3个dot

矩阵x 矢量(法线==矢量)数学含义

刚刚好,结果形成了新的矢量

//代码-2

点乘的数学含义

两个矢量的点乘,就是各自的分量.xyz相乘后,再相加

dot(vec a,  vec b)= x_1x_2 + y_1y_2 + z_1z_2;

凑巧,就是,矩阵的第一行,3个数分别乘以矢量的x,y,z,结果就是dot点乘的结果

对应楼上的代码:就是那么刚好,刚刚同学遇到凑巧同学,所以,

//形成新的矢量 ——16
    _16.x = dot(_7, _25._m1[0u].xyz);//如楼上伪代码,x==16
    _16.y = dot(_7, _25._m1[1u].xyz);//如楼上伪代码,y==4
    _16.z = dot(_7, _25._m1[2u].xyz);//如楼上伪代码,z==7

所以计算——16就是得出了法线——7的世界坐标(因为_7是从Localtion(2)声明,是从Vectex Shader传入,vertex为模型自身顶点坐标|法线也是自身坐标,还不是世界坐标)

未知代码3 - 法线归一

然后,这3行代码后面,还有2行代码:

下面——19这两行代码就太简单了,就是矢量的"归一化":

    //形成新的矢量 ——16
    _16.x = dot(_7, _25._m1[0u].xyz);//如楼上伪代码,x==16
    _16.y = dot(_7, _25._m1[1u].xyz);//如楼上伪代码,y==4
    _16.z = dot(_7, _25._m1[2u].xyz);//如楼上伪代码,z==7

    //这两行代码就太简单了
    _19 = dot(_16.xyz, _16.xyz);
    _19 = inversesqrt(_19);

    //法线的世界坐标的dir(_19)=nomalize(mul(法线,objectToWorld矩阵)

归一化是什么意思?我不打算解释了,总之上面代码

好了,说到这里,我们只需要掌握

  • 矢量基本加减乘除,法线也是矢量
  • 矩阵 = 
  • 矩阵相乘 = 3个,平移x旋转x缩放矩阵
  • Shader基础语法
  • 矩阵相乘后再乘以法线矢量
  • 矢量归一化

等同于文章最开始的截图(调转)

“”_19“”法线的世界坐标的dir = nomalize(mul(法线, objectToWorld矩阵));
//objectToWorld矩阵也可以是float4x4的,但是最后一列前面解释了,没什么数学含义
//所以,也就是Unity官方的写法
worldDir = normalize(mul((float3x3)unity_ObjectToWorld, dir));

所以, 你掌握了官方的这个函数方法,就能准确应用 unity_ObjectToWorld ,当你会用了自然就明白了,只是unity 本身写的太绕(太基础了,谁都不想解释)

那么现在,你知道unity_ObjectToWorld矩阵,每行每列是什么意思了吧?

参考:

(2 条消息) unity_ObjectToWorld里的每一列分别代表什么意思? - 知乎 (zhihu.com)

UnityCG.cginc源码之UnityObjectToWorldNormal之模型非等比缩放导致的法线不垂直问题解决分析_shader法向量非等比缩放-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/106856.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot | SpringBoot中实现“微信支付“

SpringBoot中实现"微信支付": 1.“微信支付”产品2."微信支付"接入流程3.“微信小程序支付”时序图:3.1 “商家端JSAPI下单” 接口3.2 “微信小程序端调起支付” 接口 4.微信支付准备工作:4.1 获得微信支付平台证书、商户私钥文件4…

永恒之蓝漏洞 ms17_010 详解

文章目录 永恒之蓝 ms 17_0101.漏洞介绍1.1 影响版本1.2 漏洞原理 2.信息收集2.1 主机扫描2.2 端口扫描 3. 漏洞探测4. 漏洞利用5.后渗透阶段5.1创建新的管理员账户5.2开启远程桌面5.3蓝屏攻击 永恒之蓝 ms 17_010 1.漏洞介绍 永恒之蓝(ms17-010)爆发于…

搜索引擎搜索技巧总结

晚上在B站上刷到一个关于搜索技巧的干货视频,这个视频真的不错,结尾还提到了AI时代的搜索思路之前自己也零碎的探索出了一些搜索技巧,但是没有总结,就没法稳定的加入自己的工作流,持续提高效率受到这个视频的启发&…

MySQL 5.7限制general_log日志大小

背景 需求: 在MySQL 5.7.41中开启general_log 并限制其大小,避免快速增长占用硬盘空间。 解决: 通过定时任务,执行简单的脚本,判断general_log 日志的大小,实现对通用查询日志的“每日备份”或“每日清…

毅速丨哪些金属材料在3D打印中应用最多

金属3D打印作为一种新兴的制造技术已经在很多领域得到广泛应用,目前金属3D打印应用较多的材料有不锈钢、钛合金、铝合金、钴铬合金、镍基合金、模具钢等,其中不锈钢材料的应用最为常见。 这些金属3D打印材料各有其特点和适用场景,可以根据具体…

Qt重定向QDebug,Qt/C++开源作品39-日志输出增强版V2022

Qt重定向QDebug,自定义一个简易的日志管理类 Chapter1 Qt重定向QDebug,自定义一个简易的日志管理类0.前言1.最简单的操作运行结果2.实现一个简易的日志管理类 Chapter2 Qt::Qt Log日志模块Qt Log日志模块官方解释官方Demo思路 Chapter3 QT日志模块的个性…

蓝桥杯 第 2 场算法双周赛 第3题 摆玩具【算法赛】 c++ 贪心

题目 摆玩具【算法赛】https://www.lanqiao.cn/problems/5888/learning/?contest_id145 问题描述 小蓝是一个热爱收集玩具的小伙子,他拥有 n 个不同的玩具。 这天,他把 n 个玩具按照高度顺序从矮到高摆放在了窗台上,然后,他希…

阿里云对象存储OSS文件无法预览,Bucket设置了Referer

您发起的请求头中没有Referer字段或Referer字段为空,与请求Bucket设置的防盗链策略不相符。 解决方案 您可以选择以下任意方案解决该问题。 在请求中增加Referer请求头。 GET /test.txt HTTP/1.1 Date: Tue, 20 Dec 2022 08:48:18 GMT Host: BucketName.oss-examp…

Docker GitLab-Runner安装

Docker GitLab-Runner安装 GitLab-Runner安装 问题合集GitLab 域名的配置修改Runner容器内注册失败,提示 dial tcp: lookup home.zsl0.com on 192.168.254.2:53: no such host GitLab-Runner 安装 拉去gitlab/gitlab-runner镜像 docker pull gitlab/gitlab-runne…

汽车行驶性能的主观评价方法(1)-底盘校准方法

底盘校准的目的是,从行驶性能和行驶舒适性两个方面进行协调,从而优化行驶动力学特性。为了达到这一目标,工程人员早在设计阶段,就对大多数对行驶动力性有重要意义的部件提出了要求。这些要求不仅与底盘的组件有关,还必…

轻量封装WebGPU渲染系统示例<2>-彩色立方体(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/version-1.01/src/voxgpu/sample/VertColorCube.ts 此示例渲染系统实现的特性: 1. 用户态与系统态隔离。 2. 高频调用与低频调用隔离。 3. 面向用户的易用性封装。 4. 渲染数据和渲染机制分离。 5. …

超宽带技术在汽车领域的应用

随着科技的不断发展,超宽带(Ultra-Wideband, UWB)技术在各个领域展现出了强大的潜力,其中汽车领域更是受益匪浅。UWB技术以其高精度的定位能力、高速的数据传输和低功耗的特点,为汽车行业带来了许多创新。本文将探讨UW…

20.1 OpenSSL 字符BASE64压缩算法

OpenSSL 是一种开源的加密库,提供了一组用于加密和解密数据、验证数字证书以及实现各种安全协议的函数和工具。它可以用于创建和管理公钥和私钥、数字证书和其他安全凭据,还支持SSL/TLS、SSH、S/MIME、PKCS等常见的加密协议和标准。 OpenSSL 的功能非常…

安卓开发实例:方向传感器

调用手机的方向传感器&#xff0c;X轴&#xff0c;Y轴&#xff0c;Z轴的数值 activity_sensor.xml <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayoutxmlns:android"http://schemas.android.c…

Git Gui使用技巧

资料 https://www.runoob.com/w3cnote/git-gui-window.html 操作过程 创建仓库→添加远程仓库→扫描目录→文件移动→提交→上传 注意填注释 文件忽略 创建文件.gitignore→编写内容 *.log #文件 config.ini #文件 temp/ #目录

Linux--安装与配置虚拟机及虚拟机服务器坏境配置与连接---超详细教学

一&#xff0c;操作系统介绍 1.1.什么是操作系统 操作系统&#xff08;Operating System&#xff0c;简称OS&#xff09;是一种系统软件&#xff0c;它是计算机硬件和应用软件之间的桥梁。它管理计算机的硬件和软件资源&#xff0c;为应用程序提供接口和服务&#xff0c;并协调…

spark

spark Spark可以将Hadoop集群中的应用在内存中的运行速度提升100倍&#xff0c;甚至能够将应用在磁盘上的运行速度提升10倍。除了Map和Reduce操作之外&#xff0c;Spark还支持SQL查询&#xff0c;流数据&#xff0c;机器学习和图表数据处理。开发者可以在一个数据管道用例中单独…

面试总结之消息中间件

RabbitMQ的消息如何实现路由 RabbitMQ是一个基于AMQP协议实现的分布式消息中间件&#xff0c;AMQP具体的工作机制是生产者将消息发送到RabbitMQ Broker上的Exchange交换机上&#xff0c;Exchange交换机将收到的消息根据路由规则发给绑定的队列&#xff08;Queue&#xff09;&am…

汇总区间(Java)

大家好我是苏麟 , 这篇文章也是凑数的 ... 描述 : 给定一个 无重复元素 的 有序 整数数组 nums 。 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说&#xff0c;nums 的每个元素都恰好被某个区间范围所覆盖&#xff0c;并且不存在属于某个范围但不属于 n…

C++之特殊类的设计

目录 一、单例模式 1、设计模式 2、单例模式 1、饿汉模式 2、懒汉模式 3、单例对象的释放问题 二、设计一个不能被拷贝的类 三、设计一个只能在堆上创建对象的类 四、设计一个只能在栈上创建对象的类 五、设计一个不能被继承的类 一、单例模式 1、设计模式 概念&am…