深入解析:Metal - 5.深入剖析 3D 变换

news/2025/9/27 18:20:37/文章来源:https://www.cnblogs.com/yxysuanfa/p/19115435

在第四章中,我们通过在顶点函数中简单地计算位置数据,实现了模型的位移。但如果要在 3D 空间中执行更复杂的任务,例如旋转和缩放,并最终引入场景中的摄影机,矩阵(Matrices)是不可或缺的工具。

本章将详细讲解如何使用矩阵来实现这些 3D 变换。一旦掌握了对单个三角形的矩阵操作,将其扩展到包含数千个顶点的模型将非常简单。


一、 变换概述(Transformations)

变换(Transformations) 是对 3D 几何图形进行操作的过程。本章讨论的变换属于 仿射变换(Affine Transformations),这意味着在应用变换后,所有平行线依然保持平行。

核心的 3D 变换包括:位移(Translation)、缩放(Scale)和旋转(Rotation)。

二、 位移(Translation)

在第四章中,我们通过简单地将位移向量添加到顶点位置来实现位移。然而,在现代计算机图形学中,更常见的方法是:将包含模型当前位置、旋转和缩放信息的矩阵发送给顶点着色器。

1. 创建矩阵(Creating a Matrix)

在 Metal 中,变换操作通过 4×44 \times 44×4 矩阵来实现。

  • 单位矩阵(Identity Matrix):这是所有变换的起点。它是一个 4x4 矩阵,主对角线上的元素是 111,其余元素为 000
    • 在 Swift 端,我们定义一个 matrix_float4x4 并初始化为单位矩阵。
  • 位移向量:在 4x4 矩阵中,位移向量(x,y,zx, y, zx,y,z)存储在矩阵的第四列x,y,zx, y, zx,y,z 分量中。

将矩阵发送到着色器:

  1. Swift 端:使用 renderEncoder.setVertexBytesmatrix_float4x4 类型的 matrix 发送到缓冲区索引 11。
  2. 着色器端:顶点函数通过 [[buffer(11)]] 限定符接收 constant float4x4 &matrix

2. 矩阵乘法应用

为了将位移应用于顶点,着色器将从简单相加改为执行矩阵乘法:

translation=matrix×in.position\text{translation} = \text{matrix} \times \text{in.position}translation=matrix×in.position

此时,in.position(顶点原始位置)被视为一个 4×14 \times 14×1 的向量,并与 4×44 \times 44×4 的变换矩阵相乘。

var vertices: [Float] = [
-0.7,  0.8,  0,
-0.7, -0.5,  0,
0.4,  0.1,  0
]
let translateX: Float = 0.3
let translateY: Float = -0.4
let translationMatrix = float4x4(
[1, 0, 	0,	0],
[0,	1,	0,	0],
[0,	0, 	1, 	0],
[translateX, translateY, 	0, 1])

注意,OpenGL、Metal 以及 Swift 的 SIMD 库都使用列主序存储,因为计算机的内存是一维的、线性的,所以 [translateX, translateY, 0, 1] 其实对应的是第四列。

在这里插入图片描述

三、 缩放(Scaling)

缩放操作的实现与位移类似,但其值位于矩阵的不同位置。

  • 缩放矩阵的结构:缩放因子位于矩阵的对角线上。例如,要在 X,Y,ZX, Y, ZX,Y,Z 轴上分别缩放 Sx,Sy,Sz\text{Sx}, \text{Sy}, \text{Sz}Sx,Sy,Sz,只需将它们放置在矩阵第一、第二和第三列的对角线位置。
  • 组合变换:要实现缩放后的位移,需要将位移矩阵乘以缩放矩阵。在 Metal 的矩阵乘法中,顺序很重要。例如,matrix = translation * scaleMatrix 会将缩放后的三角形进行位移。
let scaleX: Float = 0.5
let scaleY: Float = 0.5
let scaleMatrix = float4x4(
[scaleX, 0, 	0,  0],
[0, scaleY,	0,	0],
[0, 			0, 	1, 	0],
[0, 			0, 	0,  1])

在这里插入图片描述

四、 旋转(Rotation)

旋转操作的实现方式与缩放类似。

  • 旋转矩阵:通常围绕 Z 轴定义旋转角度。
  • 单位:计算机图形学中,标准单位是 弧度(radians)。Metal 使用 Float.pi / 2.0 来表示 90∘90^{\circ}90
  • 绕原点旋转:默认的旋转矩阵操作总是围绕 原点 $$ 进行。
let angle = Float.pi / 2.0
let rotationMatrix = float4x4(
[cos(angle), -sin(angle), 0, 	0],
[sin(angle), cos(angle),  0, 	0],
[0, 					0, 				  1, 	0],
[0, 					0, 					0, 	1])

注意,Metal 是左手坐标系,从观察者视角来看,是顺时针旋转,但是从z轴方向看(人站在z轴正方向无穷远处顺着负方向看)是逆时针旋转。

在这里插入图片描述

绕任意点旋转(Rotation About a Point)

如果需要围绕模型的某个特定点(而不是原点)进行旋转,需要一个三步序列的组合变换:

  1. 平移到原点:使用位移矩阵 T−1T^{-1}T1 将旋转中心点移动到原点。
  2. 旋转:应用旋转矩阵 RRR
  3. 平移回去:应用逆位移矩阵 TTT 将所有点移回原位。

最终的变换矩阵是这三个操作的乘积:

Final Matrix=T×R×T−1\text{Final Matrix} = T \times R \times T^{-1}Final Matrix=T×R×T1

在 Swift/Metal 中实现此操作时,需要首先计算出将目标旋转点移动到原点所需的位移矩阵 TTT,然后通过调用 translation.inverse 来获取 T−1T^{-1}T1


五、 组合

  1. scaleMatrix * rotationMatrix * translationMatrix
    在这里插入图片描述
  2. translationMatrix * rotationMatrix * scaleMatrix

在这里插入图片描述

六、 Metal 变换总结(Key Points)

  • 向量与矩阵:向量是只有一行或一列的矩阵。
  • 组合变换:通过组合位移、旋转和缩放这三个矩阵,可以将模型定位在场景中的任何位置。
  • 顶点函数:顶点函数负责接收这个组合变换矩阵,并通过矩阵乘法计算出每个顶点在裁剪空间中的最终位置。
  • 数学基础:虽然 Metal API 抽象了大部分数学细节,但理解线性代数(特别是向量和矩阵的视觉意义)对于创造性地使用变换至关重要。

七、 Metal 与 OpenGL 变换概念对比

Metal 和 OpenGL 在实现 3D 变换时,核心数学原理(矩阵乘法)是相同的,但 API 级别上存在显著的工具和哲学差异。

概念Metal (SIMD, MSL)OpenGL (GLM, GLSL)核心差异
数学库依赖于 Apple 的 SIMD 框架(如 matrix_float4x4)和 Metal Shading Language (MSL) 的内置类型。依赖于第三方数学库,最常见的是 GLM (OpenGL Mathematics)。GLM 是专为 OpenGL 定制的头文件库,提供了矩阵和向量操作。Metal 自带数学类型;OpenGL 需要外部库。
矩阵定义矩阵和向量类型在 Swift 和 MSL 中原生支持(例如 float4x4)。GLSL 提供了 mat4vec4 等类型。C++ 主程序通常使用 GLM 定义 glm::mat4
矩阵传输矩阵通常通过 renderEncoder.setVertexBytes 或作为 MTLBuffer 中的 Uniforms 结构体发送到着色器。矩阵通过 Uniform 变量发送到 GLSL 着色器。需要使用如 glUniformMatrix4fv 这样的函数来发送数据。
矩阵乘法在 MSL 顶点函数中执行乘法:float4 position = matrix * in.position在 GLSL 顶点着色器中执行乘法:gl_Position = transform * vec4(aPos, 1.0f)
变换顺序组合变换需要遵循正确的矩阵乘法顺序,通常是 T×R×ST \times R \times ST×R×S (如果顶点是从右向左乘)。OpenGL 中同样需要遵循矩阵乘法顺序,例如:projection * view * model。GLM 自动将连续的操作相乘,但开发者仍需注意函数调用的顺序。
渲染位置输出顶点函数将最终结果输出到 VertexOut 结构体中的 [[position]] 属性。顶点着色器将结果赋值给内置变量 gl_Position
NDC 空间Metal NDC 的 ZZZ 轴范围是 000111OpenGL NDC 的 X,Y,ZX, Y, ZX,Y,Z 轴范围都是 −1.0-1.01.01.01.01.0

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

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

相关文章

垃圾收集器G1ZGC详解

垃圾收集器G1&ZGC详解 一、G1 收集器(-XX:+UseG1GC) G1(Garbage-First)是面向多处理器、大内存的服务器级收集器,核心目标是可预测的 GC 停顿时间与高吞吐量平衡。1. 核心特性Region 划分:将 Java 堆划分为最…

菠菜网站怎么做外贸网站该怎么做

控制actor在level中沿着一个spline path运动。 由finterp to 函数的输出数值来控制每一帧actor运动的距离。 从开始位置到spline path的终点的时间,是1/interp speed。假如我们控制actor从开头到终点运动的总时间是1秒,那么 interp speed就传入0.5&#…

Godot Outline

Godot OutlineGodot 4.5 这几天更新了,补全了模板缓冲, 在渲染Depth Buffer时,一般使用D32S8的类似格式。在Godot中,原本Depth Buffer就只渲染了Depth,因此S8的通道没有被使用。Stencil即特定材质可以向这个通道里…

油猴脚本(tampermonkey)离线安装文件下载,带油猴(tampermonkey)插件清单

油猴插件(Tampermonkey)是一款浏览器扩展程序(也称为“用户脚本管理器”),主要是在浏览器中安装和运行自定义脚本,用于修改或增强网页功能。目前支持Chrome、Firefox、Edge、Safari等主流浏览器,基本就是丰富浏…

树在线网页制作网站wordpress目录在哪里

一款博客网站源码 源码软件库 为大家内置了主题 清爽又强大真正的永久可用的一条源码,该版本为整合版本,内置了Joe主题,搭建后直接启用即可~ 安装环境要求: PHP 7.2 以上 MySQL, PostgreSQL, SQLite 任意一种数据库支持&#xff…

海口建网站 模板c 网站开发培训

文章目录 文章介绍下载连接安装教程 文章介绍 安装Qt5.12.2 下载连接 点击官网下载 安装包下载完毕 安装教程 点开设置,添加临时储存库,复制连接“https://download.qt.io/online/qtsdkrepository/windows_x86/root/qt/” 点击测试&#xff0…

SentinelOne与MITRE ATTCK企业版2025评估的深度解析

本文深入探讨SentinelOne对MITRE ATT&CK评估体系的立场转变,分析企业级网络安全评估标准的发展趋势,并揭示安全厂商在资源调配与产品路线图之间的战略平衡。文章聚焦于现代网络安全技术演进与实战化评估体系的内…

详细介绍:Docker的介绍

详细介绍:Docker的介绍pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", &qu…

详细介绍:【汽车篇】基于深度学习的2D+3D整车漆面外观缺陷检测

详细介绍:【汽车篇】基于深度学习的2D+3D整车漆面外观缺陷检测pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Co…

深入解析:网线传输距离限制 | 理论基础 / 实际应用 | 双绞线分类与特性 / 水晶头制作

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

react useEffect Hook讲解

什么是 useEffect Hook? useEffect 是 React 中的一个 Hook,用于在函数组件中处理副作用(side effects)。副作用是指那些不在组件渲染过程中直接发生的事情,比如:发起网络请求(比如从服务器获取数据) 操作 DOM…

2025海丰杯WP

2025海丰杯WP ​#CTF#,#海丰杯#​ 签到 R1kzRE1ZWldHRTNET04zQ0dNWURHTUpXR1laVFNNWlVHTVpER01SVEdNWkdJTVpYR00zRE1OQlRHWVpHSU1aVUdNWlRHTkpXR0laR0lOUlJHWVpER05KVEdJWkdJTVpXR00yVEdOQldHSTNER01aVEdZM0RHTlpXR1Va…

备案 网站名企点网印通

1、打开终端,输入命令$sudo apt-get install stardict,开始下载安装。 2、安装完成后,打开后选择左下角取词选项,即可完成屏幕取词功能。 3、以上是实现的是在线翻译功能,要实现离线翻译,需要下载离线辞…

2025年试验机品牌权威推荐榜:聚焦 TOP5 专精特新企业,疲劳试验机,压力试验机,液压万能试验机等设备技术实力与口碑解析!

在工业制造高质量发展进程中,材料性能检测是保障产品安全与品质的关键环节,试验机作为核心检测设备,其性能稳定性、技术精准度直接影响企业生产效率与行业质量标准。当前市场上试验机品牌众多,但产品质量参差不齐,…

[2025.9.27鲜花] 私たちもう一生 分かり合えないと 分かっていたでしょう

已经在以周为单位计量我的生活了,一周过的跟以前的一天一样[2025.9.27鲜花] 私たちもう一生 分かり合えないと 分かっていたでしょう 咕了一个月的鲜花,被小登催了,所以来写了() 听了一个月的尸蜡,太耐听了 …

2025年岗亭厂家最新权威推荐榜:内蒙古门卫室岗亭,售货岗亭,值班岗亭,保安岗亭,低噪声岗亭选购指南

当前城市化进程不断提速,岗亭作为公共服务、安防管理及商业运营的关键设施,市场需求呈持续上升态势,但行业发展中的问题也逐渐凸显。据市场调研数据,超 60% 的企业用户在采购岗亭时,曾遭遇质量参差不齐、交付延迟…

万网空间上传网站吗百度关键词优化快速排名软件

今天好累&#xff0c;但收获多多&#xff0c;满足。 2012.2.23图层和蒙版层的类型&#xff1a;图层&#xff0c;智能图层【一个文档里嵌入一个文档&#xff0c;双击图层后形成一个新的文档】&#xff0c;调节层&#xff1b;背景层<-->图层&#xff1a;按ALT双击背景层--&…

gen-ui-python

gen-ui-python https://github.com/fanqingsong/gen-ui-python?tab=readme-ov-file https://github.com/bracesproul/gen-ui-python Generative UI with LangChain Python 🦜🔗Overview This application aims to…

SPI和普通设计模式区别

目录背景和价值1. 扩展主体:框架外部 vs 内部2. 接口与实现的绑定方式:“隐式约定” vs “显式编码”3. 设计目标:“开放给外部扩展” vs “内部逻辑解耦”一句话总结 背景和价值 SPI(Service Provider Interface)…

混元开源之力:spring-ai-hunyuan 项目功能升级与实战体验 - 指南

混元开源之力:spring-ai-hunyuan 项目功能升级与实战体验 - 指南2025-09-27 17:51 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !im…