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

WebGL 世界坐标系和本地坐标系

目录

前言 

​编辑本地坐标系

世界坐标系

变换与坐标系 


前言 

在WebGL 从0到1绘制一个立方体_山楂树の的博客-CSDN博客中,我们创建并显示了第一个三维物体(一个立方体),示例程序开始变得像一个“真正”的三维程序了。我们亲手设置了立方体的顶点坐标和索引信息,这很耗时间。虽然这样可以实现,但是在构建你自己的,真正的WebGL程序时往往不会这样做。我们通常使用专用的三维建模工具,因为建模工具允许我们通过对各种基本的三维图形(立方体、圆柱体、球体等)进行各种操作(组合、形变、顶点数量调整、顶点间隔优化等)来创建精美复杂的三维模型。三维建模工具Blender(www.blender.org/)的界面如下图所示。

使用三维建模工具制作模型

本地坐标系

当我们创建三维模型时,需要知道原点(0.0,0.0,0.0)在何处。你可以自由选择原点的位置,所以三维模型的建立就比较容易,或者说很容易确定三维模型在场景中的位置。之前我们创建的立方体,原点就在立方体的中心。球状物体如太阳和月亮等,通常也将原点设置在球心。

另一方面,大部分上图所示的游戏角色模型,其原点大部分都是位于脚部,Y轴垂直向上穿过身体的中线。这样,如果我们将角色放置在y坐标为0的位置(也就是地面),角色看上去就像站立在地面上一样——既没有悬浮在空中,也没有沉入地面以下。这时,如果我们沿Z轴或X轴移动角色,看上去就好像角色在地面上跑动或滑动。或者,你也可以对令角色沿Y轴的旋转,看上去就好像在转向一样。

此时,组成场景中的模型或角色的顶点,其坐标是相对于角色本身的原点的,这样的坐标系被称为本地坐标系(local coordinate system)。使用建模工具如Blender创建的模型(包括顶点坐标、颜色、索引等)可以被导出为文件,而我们可以将文件中的顶点数据导入到缓冲区中,并使用gl.drawElements()方法将这个建模工具创建的模型绘制出来。

世界坐标系

下面来考虑在某个三维游戏中,同一个空间内出现多个角色的情况。比如,我们需要将下图(右)中的3个角色放置在下图(左)中的游戏场景中。每个角色都有自己的原点,场景也有原点。

当我们想要在场景中显示角色时,就会遇到一个问题。因为所有角色模型都是基于自身的原点(位于脚部)制作的,它们会重叠出现在场景的同一个位置上,那就是场景自身的原点,如下图所示 

所有的角色堆叠在游戏的原点处

 

为了解决这个问题,你需要调整每个角色的位置使之不再互相重叠。为此,我们可以把企鹅移动到(100,0,0),把猴子移动到(200,10,20),把狗狗移动到(10,0,200)。 

根据上述,我们用来移动和放置角色的坐标系就称为世界坐标系(world coordinate system),或称全局坐标系(global coordinate system)。角色本身仍然是基于本地坐标系的,而上述这种从本地坐标系到世界坐标系的转换,就称为世界变换(world transformation)。

当然,为了避免企鹅、猴子和狗狗角色的相互重叠,在创建它们的时候就应该为其指定世界坐标。比如,在Blender等工具里为企鹅建模的时候,可以将企鹅的模型建立在(100,0,0),这样当你将企鹅的模型加入到场景里面时,企鹅就会自动出现在(100,0,0)的位置,而不用你去进行坐标变换以避免重叠。但是,这种方法也有自身的缺陷。比如,你可能会想让企鹅像在跳芭蕾舞一样自旋,你会使企鹅沿Y轴旋转,但这样就对导致企鹅沿着场景的原点作半径为100的圆周运动。所以,你需要先把企鹅移到场景原点,旋转,再移回来,真够麻烦的。

事实上,这时的情形与WebGL模型视图投影矩阵_山楂树の的博客-CSDN博客中的PerspectiveView_mvp示例程序很像。我们使用一组三角形的顶点(其坐标是相对于场景的原点定义的)绘制了两组三角形,如下图所示。

这里,本地坐标系描述了图中虚线所画三角形的顶点坐标,而世界坐标系描述了沿着X轴平移后的两组三角形。 

变换与坐标系 

目前,我们还是没有讨论过本地坐标系和世界坐标系之间的变换,这样你就可以专注于上面每个例子中的内容。作为参考,下图给出了WebGL中的多种坐标系及其之间的变换关系,希望这张图能够加深你对三维图形学的认识,并帮助你在建模工具中进行实验。

相关文章:

  • “Linux免除系统交互操作方法、expect自动化交互工具” 及 “SSH批量修改主机密码脚本”
  • Python爬虫selenium安装谷歌驱动解决办法
  • 使用Filter AND Interceptor校验等录(全网独一份,机不可失)
  • CCF CSP认证 历年题目自练Day34
  • IDEA中创建Web工程流程
  • Java NIO三大核心组件
  • python和go执行字符串表达式
  • 苏轼在密州的四首千古名作
  • DIY私人图床:使用CFimagehost源码自建无需数据库支持的PHP图片托管服务
  • 【RTOS学习】优先级 | Tick | 任务状态 | 空闲任务 | 任务调度
  • javaweb:mybatis:mapper(sql映射+代理开发+配置文件之设置别名、多环境配置、顺序+注解开发)
  • 一图看懂CodeArts Governance 三大特性,带你玩转开源治理服务
  • OpenCV实现人脸关键点检测
  • pdf格式的简历中的照片太小,如何修改图片的大小
  • iOS 中,isa 指针
  • 小程序 | 小程序后端用什么语言开发比较好
  • 通讯网关软件024——利用CommGate X2Access实现Modbus TCP数据转储Access
  • ORACLE 19C PDB FOR MYSQL 5.7 部署ogg
  • 1.16.C++项目:仿muduo库实现并发服务器之HttpContext以及HttpServer模块的设计
  • 事务管理 vs. 锁控制:你真的分得清吗?何时使用何种并发控制策略?
  • 李云泽:对受关税影响较大、经营暂时困难的市场主体,一企一策提供精准服务
  • 潘功胜:央行将创设科技创新债券风险分担工具
  • “五一”假期银联、网联共处理支付交易234.39亿笔
  • 【社论】跑赢12级狂风,敦煌做对了什么
  • 缅甸国防军继续延长临时停火期限至5月31日
  • 戴紫薇评《不像说母语者》丨后殖民语境下的母语追寻