当前位置: 首页 > news >正文

3D几何流水线之模型变换

参考书:Real-time Rendering 2nd, 《3D游戏与计算机图形学中的数学方法》

最初,物体在模型空间中,通过模型变换改变了物体的位置和朝向,物体被变换到世界空间。

按照变换顺序,应该先旋转后平移,对于opengl的规则,是TR X V。
矩阵T,R都是4X4的,T中只有第4列有效,其他是单位阵的排列,R中是前3X3子阵有效,其他是单位阵排列,将TR相乘:

| 1 0 0 Tx | | Ux Vx Nx 0 | | Ux Vx Nx Tx |
| 0 1 0 Ty | X | Uy Vy Ny 0 | = | Uy Vy Ny Ty |
| 0 0 1 Tz | | Uz Vz Nz 0 | | Uz Vz Nz Tz |
| 0 0 0 1 | | 0 0 0 1 | | 0 0 0 1 |

可 见,在最后得到的4X4 TR矩阵中,等于是把3X3 UVN矩阵填到平移矩阵中,这两个矩阵相乘时互相没有影响对方。其实UVN表示坐标系的映射—用(1,0,0)T, (0,1,0)T, (0,0,1)T分别右乘UVN矩阵,得到的列向量正是UVN的3列,这就是说三个坐标轴被UVN矩阵变换到世界坐标系中了,而UVN的3列表示的正是 x,y,z轴在世界坐标系下的向量。

再加上缩放变换,先看一下R X S :

|Ux Vx Nx 0| | Sx 0 0 0 | | UxSx VxSy NxSz 0 |
|Uy Vy Ny 0| X | 0 Sy 0 0 | = | UySx VySy NySz 0 |
|Uz Vz Nz 0| | 0 0 Sz 0 | | UzSx VzSy NzSz 0 |
|0 0 0 1| | 0 0 0 1 | | 0 0 0 1 |

那么最终的 T X R X S就是:
| UxSx VxSy NxSz Tx |
| UySx VySy NySz Ty |
| UzSx VzSy NzSz Tz |
| 0 0 0 1 |

可见缩放矩阵的作用是分别对三个坐标轴进行缩放。这个4X4矩阵,第4列是平移变换,3X3部分是缩放和坐标轴变换。因为坐标轴是单位向量,所以求3X3每列的模就得到相应的缩放值。

如果是把物体从世界坐标空间变回到模型空间,那么逆矩阵就是:
(TRS)-1 = S-1 X R-1 X T-1
| 1/Sx 0 0 0 | | Ux Uy Uz 0 | | 1 0 0 -Tx | | Ux/Sx Uy/Sx Uz/Sx (U' dot -T) |
= | 0 1/Sy 0 0 | X | Vx Vy Vz 0 | X | 0 1 0 -Ty | = | Vx/Sy Vy/Sy Vz/Sy (V' dot -T) |
| 0 0 1/Sz 0| | Nx Ny Nz 0 | | 0 0 1 -Tz | | Nx/Sz Ny/Sz Nz/Sz (N' dot -T) |
| 0 0 0 1| | 0 0 0 1| | 0 0 0 1 | | 0 0 0 1 |

其中 U', V', N'是U,V,N分别乘以1/Sx, 1/Sy, 1/Sz
这个4X4的逆变换矩阵就不是没影响啦,第4列是U', V', N'和-T的点积,计算这种逆矩阵时要注意,不能直接填-T的!这个逆矩阵是不能直接“填”出来的,3X3部分每一行是逆缩放后的坐标轴,第4列是前面矩阵每一列和-T的点积

至于为什么UVN矩阵的逆就是他的转置,因为UVN是正交矩阵。坐标轴是一组正交基,向量空间中所有向量都可以用这组正交基线性表出。

相关文章:

  • html5 canvas 加载图片错误 SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement'
  • RGBA模式人物换色的实现
  • javascript实现QR code扫描
  • android webview旋转屏幕导致页面重新加载问题
  • FLEX实践—自创相册
  • Nebula3的渲染线程插件(Render Thread Plugin)
  • android webview 遇到android.os.FileUriExposedException错误
  • Ucweb的发展趋势
  • Asp.net MVC scheduler实现
  • 一幅图对比软件开发框架
  • 移动Mobile Market运营模式初探之二:价值链是关键
  • 为什么我认为软件方法论无效
  • ArcGIS Server Java ADF 案例教程 29
  • Nodejs + azure +webrtc 实现android 和web视频聊天步骤
  • ArcGIS Server Java ADF 案例教程 28
  • [数据结构]链表的实现在PHP中
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • HTTP中的ETag在移动客户端的应用
  • IDEA 插件开发入门教程
  • JS实现简单的MVC模式开发小游戏
  • MySQL用户中的%到底包不包括localhost?
  • python学习笔记-类对象的信息
  • Travix是如何部署应用程序到Kubernetes上的
  • Wamp集成环境 添加PHP的新版本
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 电商搜索引擎的架构设计和性能优化
  • 诡异!React stopPropagation失灵
  • 基于web的全景—— Pannellum小试
  • 技术胖1-4季视频复习— (看视频笔记)
  • 简单易用的leetcode开发测试工具(npm)
  • 码农张的Bug人生 - 见面之礼
  • 那些年我们用过的显示性能指标
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 实现菜单下拉伸展折叠效果demo
  • 一起来学SpringBoot | 第三篇:SpringBoot日志配置
  • (8)STL算法之替换
  • (9)目标检测_SSD的原理
  • (vue)页面文件上传获取:action地址
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (四)JPA - JQPL 实现增删改查
  • (转载)虚函数剖析
  • .java 9 找不到符号_java找不到符号
  • .jks文件(JAVA KeyStore)
  • .Net CoreRabbitMQ消息存储可靠机制
  • .NET Framework与.NET Framework SDK有什么不同?
  • .Net mvc总结
  • .NET6使用MiniExcel根据数据源横向导出头部标题及数据
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • @Data注解的作用
  • @Resource和@Autowired的区别
  • [ 渗透测试面试篇 ] 渗透测试面试题大集合(详解)(十)RCE (远程代码/命令执行漏洞)相关面试题
  • [120_移动开发Android]008_android开发之Pull操作xml文件
  • [2]十道算法题【Java实现】