【Unity Shader入门精要 第4章】数学基础(二)

1. Unity中的坐标空间

1.1 五个坐标空间

模型空间

  • 模型自身的3D坐标系空间,左手坐标系
  • 是一个相对空间,坐标轴指向随模型旋转变化
  • 当物体有父节点时,Transform组件中各属性的值表示的即为该物体在其父物体的模型空间中的值
  • 当模型顶点传入顶点着色器时,其中的空间信息均为自身模型空间的信息

世界空间

  • 世界3D坐标系空间,左手坐标系
  • 是一个绝对空间,坐标轴指向不会发生变化
  • 当物体没有父节点时,Transform组件中各属性的值表示的即为该物体在世界空间中的值

观察空间

  • 摄像机的模型空间,也是一个3D坐标系空间
  • 是Unity中唯一的一个右手坐标系空间
  • 以摄像机位置为坐标原点
  • 摄像机面向的方向为Z轴负方向

齐次裁剪空间

  • 左手坐标系
  • 其本质是视锥体包围的空间,或摄像机渲染范围的空间
  • 齐次裁剪空间也被称作投影空间,但实际上这时候并没有进行真正的投影,因为还没有对矢量进行降维,该空间仍然是一个3D空间
  • 齐次空间范围内的部分可见,范围外的部分为不可见,需要从渲染中剔除
  • 在透视投影下:
    • 由近裁截面距离、远裁截面距离、FOV以及横纵比决定空间范围
    • 形状为平头四棱锥
    • FOV决定锥体竖直方向的张开角度
    • 根据近裁截面、远裁截面和FOV可以求出近裁截面和远裁截面的高度,根据横纵比可以求出近裁截面和远裁截面的宽度
  • 在正交投影下:
    • 由近裁截面距离、远裁截面距离、SIZE以及横纵比决定空间范围
    • 形状为立方体
    • SIZE决定立方体竖直方向上高度的一半
    • 根据近裁截面、远裁截面和SIZE可以求出近裁截面和远裁截面的高度,根据横纵比可以求出近裁截面和远裁截面的宽度
  • 齐次空间仍然为一个非归一化的三维空间

屏幕空间

  • 左手坐标系
  • 对应当前显示屏幕的2D像素空间
  • 空间范围为(0, 0 )到(ScreenMaxPixelX, ScreenMaxPixelY)

1.2 四个转换过程

模型变换

  • Model Transform —— M
  • 将顶点从模型空间转换到世界空间

观察变换

  • View Transform —— V
  • 将顶点从世界空间转换到观察空间

投影变换

  • Projection Tranform —— P
  • 将顶点从观察空间转换到投影空间(齐次裁剪空间)
  • 根据摄像机的设置不同,分为透视投影(Perspective Projection)和正交投影(Orthographic Projection)两种投影变换方式
  • 同样,这里所谓的投影变换并不是真正进行降维投影,仍然是3D空间到3D空间的变换
  • 所谓投影变换只是对矢量乘以一个变换矩阵(称为投影矩阵或裁剪矩阵),得到矢量在当前齐次空间中真正的齐次坐标
  • 变换矩阵的推导过程并不重要,变换矩阵长什么样也不重要,重要的是我们知道矢量经过与变换矩阵的计算后,其w分量发生了变化,不再是初始的1和0,而是变成了-Z(点)和1(向量)

屏幕映射

  • 以上MVP三种变换都是在顶点着色器中完成的,回忆第二章中渲染流水线的几何阶段,在顶点着色器和屏幕映射阶段之间还有一个必不可少的裁剪阶段,因此在做真正的屏幕映射之前,还需要先进行一步裁剪
  • 上面我们提到过,齐次裁剪空间是一个非归一化的空间,在不同的摄像机设置下,视锥体的范围是不同的,为了能够对不同的视锥体范围进行统一的裁剪处理,需要先将齐次坐标映射到一个统一的范围之内,这一步通过将齐次坐标的所有分量都除以w分量来完成,称为齐次除法(感觉齐次除法就是一个从四维投影到三维的过程)
  • 经过齐次除法后,我们得到了一个(x/w, y/w, z/w, 1)的坐标,称为归一化设备坐标(NDC),而原来的裁剪空间也被投影到了一个(-1,1)的正立方体空间范围(DX为0到1)
  • 此时就可以对所有的NDC坐标进行统一的裁剪处理,只需要考虑坐标是否超出(-1,1)的范围即可
  • 裁剪结束后,所有剩余的顶点都是在屏幕范围内的点,需要根据其X和Y的值映射到(0, 0)至(MaxScreenPixelX, MaxScreenPixelY)的范围内,可以看到,这时候才真正从3D空间投影到了2D空间
  • 剩余的Z值则表示该顶点到屏幕的距离,即深度值

1.3 空间转换图示

在这里插入图片描述

2. 坐标空间变换矩阵

对于坐标空间A和坐标空间B,当我们知道了:

  • B空间的原点 O 在A空间的表示为 OriginalB
  • B空间的 X 轴在A空间的表示为 AxisBx
  • B空间的 Y 轴在A空间的表示为 AxisBy
  • B空间的 Z 轴在A空间的表示为 AxisBz

则从坐标空间B到坐标空间A的转换矩阵MB→A(4*4)为:
( ∣ ∣ ∣ ∣ A x i s B x A x i s B y A x i s B z O r i g i n a l B ∣ ∣ ∣ ∣ 0 0 0 1 ) \left( \begin{matrix} | & | & | & |\\ AxisB~x~ & AxisB~y~ & AxisB~z~ & OriginalB\\ | & | & | & |\\ 0 &0&0&1 \end{matrix} \right) AxisB x 0AxisB y 0AxisB z 0OriginalB1
即将X轴、Y轴、Z轴、原点按列组合形成的4 * 4矩阵(推导过程懒得写了)

由于向量不存在空间位置属性,因此对于向量的变换矩阵可以不关心原点,故可以直接截取3 * 3的轴矩阵 MB→A(3*3):
( ∣ ∣ ∣ A x i s B x A x i s B y A x i s B z ∣ ∣ ∣ ) \left( \begin{matrix} | & | & | \\ AxisB~x~ & AxisB~y~ & AxisB~z~ \\ | & | & | \end{matrix} \right) AxisB x AxisB y AxisB z 

根据以上矩阵可以做如下推导:

  • 对于任意B空间内的向量VB,其在A空间的表示 VA = MB→A(3 * 3) * VB
  • 两边同时乘以 MB→A(3 * 3) 的逆矩阵 MB→A(3 * 3)-1
  • 得到等式 MB→A(3 * 3)-1 * VA = VB

即:MA→B(3 * 3) = MB→A(3 * 3)-1

同时,由于 MB→A(3 * 3)是由坐标空间B的三个坐标轴组合得到的矩阵,而坐标轴组合的矩阵一定是正交矩阵,因此 MB→A(3 * 3)的转置矩阵与逆矩阵相同

因此,此时从坐标空间A反向转换到坐标空间B的转换矩阵 MA→B(3 * 3) = MB→A(3 * 3)-1 = MB→A(3 * 3)T,故 MA→B(3 * 3) 为:
( — A x i s B x — — A x i s B y — — A x i s B z — ) \left( \begin{matrix} — & AxisB~x~ & — \\ — & AxisB~y~ & — \\ — & AxisB~z~ & — \end{matrix} \right) AxisB x AxisB y AxisB z 

3.法线变换

普通的转换矩阵适用于在不同的坐标空间之间对点和普通向量进行空间变换,但是如果直接用该矩阵对法线进行变换,就会出错

这是因为法线并不是空间内真实存在的向量,法线只是对空间内某一平面垂直的一个相对向量,或者说是对空间内真实存在的向量虚构出来的相对向量,具有一定的相对性

当进行空间变换后,这种相对性无法保证依然生效,因此可能导致变换后的法线与变换后的平面并不垂直

而切线是由空间内相邻两点确定的,也就是空间中真实存在的向量,因此可以通过普通的转换矩阵进行空间变换,并且我们可以利用切线来推导出使用于法线的转换矩阵

假设T为切线,N为法线,M为切线的转换矩阵,G为法线的转换矩阵
TB = M * TA
NB = G * NA

由切线与法线垂直可得:
TB · NB = (M * TA) · (G * NA) = 0
注意,上式表示的是两个垂直向量的点乘结果为0

如果将上式改成矩阵乘法来表示,就需要将TB 转置成列矩阵后再与行矩阵 NB 相乘
于是得到:
(M * TAT · (G * NA) = TAT * MT * G * NA = TAT * (MT * G) * NA = 0

由于TAT * NA = 0,因此要使上式成立,只要 MT * G = I,即G = (MT)-1 = (M-1)T

于是问题转化为求普通转换矩阵 M 的逆矩阵 M-1

  • 如果只存在旋转变换,由于旋转矩阵为正交矩阵,M-1 = MT,因此 G = (M-1)T = (MT)T = M
  • 如果只存在旋转变换和统一缩放变换,假设统一缩放系数为K,则G = 1/k * M(这里一直没明白,为什么不是1/k2 * M,有没有大佬给解释一下??)
  • 如果存在非统一缩放变换或平移变换,就只能求逆矩阵了

4. Unity内置变换矩阵

Unity内置了一些变量,可以轻松的获取对应的转换矩阵,这里提供的都是4*4的矩阵

变量作用
_Object2World模型空间到世界空间
_World2Object世界空间到模型空间
变量作用
UNITY_MATRIX_MVP模型空间到齐次裁剪空间
UNITY_MATRIX_V世界空间到观察空间
UNITY_MATRIX_P观察空间到齐次裁剪空间
UNITY_MATRIX_VP世界空间到齐次裁剪空间
变量作用
UNITY_MATRIX_MV模型空间到观察空间
UNITY_MATRIX_T_MV模型空间到观察空间的转置
UNITY_MATRIX_IT_MV模型空间到观察空间的逆转置

5. Unity内置摄像机参数

Unity内置了部分变量可以用来获取对应摄像机参数

变量类型作用
_WorldSpaceCameraPosfloat3摄像机世界坐标
变量类型作用
_ScreenParamsfloat4(width, height, 1 + 1/w, 1 + 1/h)
_ZBufferParamsfloat4(1 - F/N, F/N, x/F, y/F)
_ProjectinParamsfloat4(1/-1, N, F, 1 + 1/F),首位为-1时表示使用的是翻转的投影矩阵
Unity_OrthoParamsfloat4(w, h, _, 0/1) 最后位为0时为透视相机,为1时为正交相机
变量类型作用
Unity_CameraProjectionfloat4x4摄像机投影矩阵
Unity_CameraInvProjectionfloat4x4摄像机投影矩阵的逆矩阵
Unity_CameraWorldClipPlanes[6]float4左右上下远近

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ARP防火墙能够为网络安全贡献什么样的力量

ARP防火墙(Address Resolution Protocol Firewall)作为网络安全的一环,起到保护网络免受ARP欺骗攻击的关键作用。今天德迅云安全给您介绍ARP防火墙的相关方面,帮助您深入了解和认识这一关键的安全措施。 网络安全对于现代社会的信…

「 网络安全常用术语解读 」SBOM主流格式CycloneDX详解

CycloneDX是软件供应链的现代标准。CycloneDX物料清单(BOM)可以表示软件、硬件、服务和其他类型资产的全栈库存。该规范由OWASP基金会发起并领导,由Ecma International标准化,并得到全球信息安全界的支持,如今CycloneD…

Java——认识异常

目录 一.异常的概念与体系结构 1.异常的概念 1.1算术异常 1.2数组越界异常 1.3空指针异常 2.异常的体系结构 3.异常的分类 3.1编译时异常 3.2运行时异常 二.异常的处理 1.防御式编程 1.1LBYL 1.2EAFP(核心) 2.异常的抛出 3.异常的捕获 3…

使用 ORPO 微调 Llama 3

原文地址:https://towardsdatascience.com/fine-tune-llama-3-with-orpo-56cfab2f9ada 更便宜、更快的统一微调技术 2024 年 4 月 19 日 ORPO 是一种新的令人兴奋的微调技术,它将传统的监督微调和偏好校准阶段合并为一个过程。这减少了训练所需的计算…

【深度学习】第二门课 改善深层神经网络 Week 2 3 优化算法、超参数调试和BN及其框架

🚀Write In Front🚀 📝个人主页:令夏二十三 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝 📣系列专栏:深度学习 💬总结:希望你看完之后,能对…

python实现验证码-图片类型

1 utils.py import randomdef get_random_code():code for i in range(5):# 随机生成大写字母upper_char chr(random.randint(65, 90))lower_char chr(random.randint(97, 122))num_char str(random.randint(0, 9))res random.choice([upper_char, lower_char, num_char]…

软件应用开发安全设计指南

1.1 应用系统架构安全设计要求 设计时要充分考虑到系统架构的稳固性、可维护性和可扩展性,以确保系统在面对各种安全威胁时能够稳定运行。 在设计系统架构时,要充分考虑各种安全威胁,如DDoS攻击、SQL注入、跨站脚本攻击(XSS&…

如何使用 Node.js 开发一个文件上传功能?

在 Node.js 中实现文件上传功能可以通过多种方式完成,但其中最常用的方法之一是使用 Express 框架和 Multer 中间件。Express 是一个流行的 Node.js Web 框架,而 Multer 是一个用于处理文件上传的中间件。 步骤 1: 准备工作 首先,确保你已经…

《Fundamentals of Power Electronics》——升压隔离型变换器、SEPIC隔离型变换器

以下是升压型隔离变换器的相关知识点: 升压型隔离变换器可以通过互换降压型隔离变换器的电源与负载的位置得到。升压型隔离变换器有许多种结构,此处简短的讨论两种情况。这些转换器主要使用在高压电源和低谐波整流器中。 图6.36所示是一种全桥型电路结…

企业定制AI智能名片商城小程序:重塑营销场景,引领数字化营销新纪元

在数字化时代的浪潮中,多企业AI智能名片商城小程序以其独特的魅力和创新的功能,为消费者带来了前所未有的购物体验。它不仅是一个汇聚各类商品的购物平台,更是一个充满活力和创造力的社群生态。通过强化社群互动、鼓励用户生成内容以及引入积…

uniapp 文字转语音(文字播报、语音合成)、震动提示插件 Ba-TTS

简介(下载地址) Ba-TTS 是一款uniapp语音合成(tts)插件,支持文本转语音(无服务费),支持震动提示。 支持语音合成,文本转语音支持震动(可自定义任意震动效果…

一对一WebRTC视频通话系列(二)——websocket和join信令实现

本系列博客主要记录WebRtc实现过程中的一些重点,代码全部进行了注释,便于理解WebRTC整体实现。 一对一WebRTC视频通话系列往期博客: 一对一WebRTC视频通话系列(一)—— 创建页面并显示摄像头画面 websocket和join信令…

Go实战训练之Web Server 与路由树

Server & 路由树 Server Web 核心 对于一个 Web 框架,至少要提供三个抽象: Server:代表服务器的抽象Context:表示上下文的抽象路由树 Server 从特性上来说,至少要提供三部分功能: 生命周期控制&…

堆栈打印跟踪Activity的启动过程(基于Android10.0.0-r41),framework修改,去除第三方app的倒计时页面

文章目录 堆栈打印跟踪Activity的启动过程(基于Android10.0.0-r41),framework修改,去除第三方app的倒计时页面1.打印异常堆栈2.去除第三方app的倒计时页面3.模拟点击事件跳过首页进入主页 堆栈打印跟踪Activity的启动过程(基于Android10.0.0-r41)&#x…

领域驱动设计(DDD)笔记(三)后端工程架构

文章链接 领域驱动设计(DDD)笔记(一)基本概念-CSDN博客领域驱动设计(DDD)笔记(二)代码组织原则-CSDN博客领域驱动设计(DDD)笔记(三)后端工程架构-CSDN博客前导 领域驱动设计(Domain Driven Design,简称DDD)是业内主导的业务工程理论。它在各中权威人士被广泛讨论…

华为云耀云服务器开放端口

博客主页:花果山~程序猿-CSDN博客 关注我一起学习,一起进步,一起探索编程的无限可能吧!让我们一起努力,一起成长! 目录 一.华为云控制台开放端口 寻找到安全组信息 2. 添加开放的端口信息 3. 检查是否成…

信息泄露.

一,遍历目录 目录遍历:没有过滤目录相关的跳转符号(例如:../),我们可以利用这个目录找到服务器中的每一个文件,也就是遍历。 tipe:依次点击文件就可以找到flag 二,phpi…

JavaScript基础(四)

逻辑运算符 && 与 : 多个条件同时满足 ΙΙ 或 : 多个条件满足一个 &#xff01; 非 : 否定某个条件 例: <script> //&多个条件同时满足&#xff0c;才返回true //任意一个为false&#xff0c;就返回false var a 10; var b 20; …

vue快速入门(五十)重定向

注释很详细&#xff0c;直接上代码 上一篇 本篇建立在之前篇目前提下针对重定向进行演示 新增内容 路由重定向写法 源码 src/router/index.js //导入所需模块 import Vue from "vue"; import VueRouter from "vue-router"; import myMusic from "/v…

【51蛋骗鸡595点阵88数码管流水灯综合应用】2021-12-30

缘由51单片机变量进阶与点阵LED-嵌入式-CSDN问答 大佬们 求解单片机点亮点阵程序 被困3天了一直想不明白 - 24小时必答区 #include<reg52.h>//头文件sbit shcpP1^2;//数据输入时钟线 595的11脚 sbit stcpP1^1;//输出存储器锁存时钟线 595的12脚 sbit dsP1^0;//数据线 5…