网站首页 > 技术文章 正文
“ 观察矩阵的目的就是计算模型从世界坐标系转换到观察坐标系后的坐标”
3D渲染是通过世界坐标系建模,观察坐标系变换到观察者场景,再进行投影变换将3D场景投影到观察平面生成2D图形这三个步骤来实现的,本文讲述观察矩阵的推导过程。
01
—
世界坐标系
在使用3D建模软件时,都要布置模型空间、进行灯光等的布局,以blender为例,下图所示的模型界面就是在世界坐标系下,其中照相机的位置也是参考世界坐标系确定的,所谓世界坐标系就是建模物体、照相机、灯光等实体的参照系。
02
—
观察坐标系
观察坐标系就是照相机代表的观察者参照系,点击blender右上角照相机图标就会展现以照相机视角看到的模型展现场景,就像拍照需要一个好的构图和角度,3D渲染同样也需要一个合理的照相机布局。
通常一个照相机用一个观察坐标系来表示,观察坐标系由三个因素来确定:
视点:也就是观察点,表示观察者的位置或照相机的位置,它就是观察坐标系的原点。
视线:从视点到观察物体的方向,一般以视线的反方向作为其中一个坐标轴的正向。这里用坐标轴w来表示,类似于世界坐标系的z轴。
上方向:向上的朝向决定了观察者或相机的上方向,如果不指定上方向相机还
可以以视线为轴旋转,这样观察到的场景也就会有不同的偏移,就不能唯一确定观察场景了。这里用坐标轴v来表示,对应世界坐标系的y轴。
确定了视线和上方向,按照右手定则就可以确定观察坐标系的u轴了,对应世界坐标系的x轴。
03
—
从世界坐标系到观察坐标系
切换观察者场景,实际就是已知世界坐标系的坐标和观察者坐标系,求解以观察者坐标系为参照的坐标。我们先以2D平面为例进行分析,得出的结论可以类比得出3D正交坐标系的变换方法。
假设o、x、y代表的是世界坐标系,e、u、v代表的是观察坐标系,o、e分别表示各坐标系的原点。
根据向量的表示方式,我们可以分别列出两种坐标系下P点的表示公式:
P = (xp, yp) = o + xp*X + yp*Y (1)
P = (up, vp) = e + up*U + vp*V (2)
(说明:X、Y代表x轴、y轴的单位向量,U、V代表u轴、v轴的单位向量)
公式2中的e、U、V我们可以使用世界坐标系来表示:
P = (xp, yp) = (xe,ye) + up*(xu,yu) + vp*(xv,yv)
可以写成如下等价矩阵的形式:
这个公式表示的是如何从u、v坐标系中的P点坐标计算出x、y坐标系下的P点坐标,从矩阵形式可以看出,是依次通过旋转加平移的方式变换得到的。
然而,这个变换与我们希望的变换是相反的,对我们的需求来说,世界坐标系下的坐标是已知的,当然还有观察坐标系也是已知的或者可以根据给出的条件推导出来,希望通过某种变换得出观察坐标系下的坐标。
我们来对上面的矩阵形式进行等效变换,等式两边同时乘以相同的矩阵(原旋转矩阵的转置*反向平移矩阵),等式依然成立
把矩阵进一步合并可得,右边的矩阵最终计算得到了单位矩阵
最后,就得到了如何从x、y表示的世界坐标系下的坐标值变换到u、v表示的观察者坐标系下的坐标,从矩阵形式可以看出,通过依次进行平移变换和旋转变换得到。
同样地,推导方法可以应用到3D坐标系,得出3D坐标下从世界坐标系变换到观察者坐标系下的变换公式:
其中,旋转矩阵乘以平移矩阵得到的就是观察矩阵,图形学编程中图形库一般都会提供创建观察矩阵的方法,一般以LookAt的形式提供,该方法以视点、观察点(可以确定视线)、上方向为参数,最终返回观察矩阵(也称为视图矩阵)。
猜你喜欢
- 2025-09-13 线性代数最核心的根基就是线性方程组
- 2025-09-13 小红书大模型探索实践:从0到1构建自研RLHF框架
- 2025-09-13 CPU推理性能提高数十倍,旷视天元计算图、MatMul优化深度解读
- 2025-09-13 计算机图形学:变换矩阵_变换矩阵怎么求
- 2025-09-13 人工智能数学基础----矩阵_人工智能基础 数学知识
- 2025-09-13 最小二乘法的线性代数解释_最小二乘法 线性代数
- 2025-09-13 DL4J实战之五:矩阵操作基本功_矩阵中d4
- 2025-09-13 浅析机器人学位姿之单位四元数,一文彻底了解四元数,干货
- 2025-07-08 最让人惊艳的并行算法之一——矩阵算法
- 2025-07-08 小红书基于 PPO 的多模态大模型 RLHF 系统的设计与优化
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (84)
- el-date-picker开始日期早于结束日期 (76)
- js判断是否是json字符串 (75)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)