webgl坐标转换

文章目录

  • 前言
  • 一、webgl转换流水线
  • 二、坐标系
    • 1.物体(模型)坐标系
    • 2.世界坐标系
    • 3.观察坐标系
    • 4.裁剪坐标系
    • 5.规范化设备坐标系
    • 6.屏幕坐标系
  • 三、总结


前言

webgl虽然属于web端开发,但实际上已经进入图形学的范畴,因此,想要更高效的开发,不仅仅需要掌握扎实的前端基础,对一些webgl的底层原理也要有个基本的掌握,这样才能更高效的排查问题。文本将自己理解的坐标转换过程记录下来。


一、webgl转换流水线

在传统的前端页面开发中,页面要素都是2d的,除非涉及到地图相关的坐标转换,js绘制的要素一般都直接显示在屏幕坐标中,原生dom操作也有获取屏幕坐标的方法。但是在3d中,要将一个外部引入的三维模型数据最终转换到屏幕坐标系中,涉及到多个坐标系的转换,其中一些坐标系对于开发者来说是完全无感的。
webgl中坐标转换过程如下图所示:
webgl坐标转换_第1张图片
其中:
物体坐标系->世界坐标系->观察坐标系->裁剪坐标系 是由CPU计算得来的,对于开发者来讲可以进行操作。
裁剪坐标系->规范化设备坐标系->屏幕坐标系 是在显卡(GPU)中计算的,由显卡自动执行运算,开发者无法操作。

二、坐标系

1.物体(模型)坐标系

我们想象这么一个场景:一个三维模型的小人,我们怎么描述每个点在模型上的位置呢,方法就是在这个小人所在的地方建立一个坐标系用来做参照。这个坐标系位于小人身上,可以是它的脚上,也可以在他的身体中心,并不绝对。十个模型就可以有十个物体坐标系。
物体坐标系采用右手坐标系,如下图。

webgl坐标转换_第2张图片

2.世界坐标系

虽然物体坐标系描述了单个模型上模型点的位置关系,但是显然不能在一个场景中使用多个坐标系,因此,要把这些模型放到一个统一的坐标系中。
假如模型A中有一点 P ,该点在模型A中的坐标(0,1)。 模型A在世界坐标系的(1,0)位置,那么,点 P 在世界坐标系中的坐标就变成了(1,1)。

webgl坐标转换_第3张图片
从物体坐标系到世界坐标系的转换涉及坐标转换,实际上就是坐标的平移,旋转,缩放,假设模型变换矩阵为 M,缩放矩阵为 S,旋转矩阵为 R,平移矩阵为 T,模型上某点物体坐标P-m,在世界坐标中坐标为P-w,所以有如下公式:
P-w = M * P-m = S * R * T * P-m

3.观察坐标系

在世界坐标系中的某点,最终要通过摄像机进入人眼中,观察坐标系一般以相机光心为原点,镜头射向外的射线为z轴构成坐标系,与前面的坐标系不同的是,z轴是指向屏幕内侧的。下图为在观察坐标系中的某个模型。

webgl坐标转换_第4张图片
从世界坐标系到观察坐标系的转换过程与上一个步骤类似,都是坐标经过旋转,偏移,缩放后转换至新的坐标系下。

4.裁剪坐标系

从观察坐标系到裁剪坐标系的转换过程比较抽象,因为这一步骤涉及投影转换矩阵。投影转换分为两种:
(1)透视投影:透视投影符合人眼的视觉效果:近处的物体大于远处的物体,近处的物体可视范围小于远处的物体。
(2)正交投影:在不同的位置物体的大小形状是一定的,与距离远近无关。

透视投影和正交投影的处理流程是类似的,先指定可视范围(位于近平面、远平面、侧平面之间)。然后将近平面上的坐标根据相似三角形计算。透视投影的投影线是由一个光源发射出的相交线,可视范围是一个锥形的盒子;正交投影则是平行线,可视范围是一个长方体。图左
是透视投影,图右为正交投影。

webgl坐标转换_第5张图片webgl坐标转换_第6张图片
投影矩阵是一个4*4大小的转换矩阵,进行转换后,点P-w在裁剪坐标系中的坐标P-c是一个四维坐标:

P-c = (X,Y,Z,W)

在进行投影转换后,X,Y,Z都进行了不同程度的变换。在(X,Y,Z,W)这四个值中,X,Y,Z依旧代表模型的XYZ坐标。W坐标反应的是该点距离观察点的远近,大多情况下,它与Z的大小具备相同的变化趋势。在推导投影矩阵时,可以得出X坐标与Y坐标都是与Z的倒数成正比的,从这里也体现了为什么近处的物体显示在屏幕上更大。同时XYZ值只保留[-W,W]的部分,其余的部分将不处于显示范围内。
特别要注意的一点是,在这一步,Z坐标轴发生了变化,由指向屏幕外变为指向屏幕内

5.规范化设备坐标系

裁剪坐标系中的 (X,Y,Z,W)每一项都除以W,得到新的坐标 (X/W,Y/W,Z/W,1),这个过程被称为齐次变换,由于离观察点远的点W值更高,齐次变换后XY坐标更大,即“近大远小”。在进行齐次变换后的坐标依然是一个四维的,XYZ分别代表模型的坐标。

下图为齐次坐标的前三项的数据范围以及指向。

webgl坐标转换_第7张图片

6.屏幕坐标系

最后一步是把上一步的设备坐标系映射到屏幕上,是通过 WebGL API 中的 gl.viewport来 设置,,这里需要传入视图尺寸的大小,一般是直接设置默认画布的大小:gl.viewport(0, 0, canvas.width, canvas.height)。webgl会调用GPU自动完成这一步。屏幕坐标系一般以左上角为原点,如下图:

webgl坐标转换_第8张图片
从规范化设备坐标只保留了xy坐标信息转换到屏幕坐标系,z坐标的值用来做深度检测,物体的遮挡效果是通过z坐标的值来判断的。
webgl坐标转换_第9张图片

三、总结

以上为webgl中坐标转换的过程,转换流程:

  • 物体(模型)坐标系
  • 世界坐标系
  • 观察坐标系
  • 裁剪坐标系
  • 规范化设备坐标系
  • 屏幕坐标系
    参考:
    https://juejin.cn/post/7035789310024482823
    https://juejin.cn/post/6890795086054260750#heading-15

你可能感兴趣的:(WebGL,前端,javascript,开发语言)