Three.js和Cesium.js中坐标

在了解Three.js和Cesium.js前先了解并弄清楚图形学关于空间的基本概念流程:

计算机图形学

 图形学中涉及到多个坐标空间,这些空间之间的变换是图形渲染中的核心部分。下面是一些常见的图形学空间及其变换顺序:

  1. 对象空间(Object Space)

    • 这是模型的原始坐标空间,模型的顶点数据是在这个空间中定义的。
    • 变换:通常通过模型变换(Model Transformation)来改变模型在对象空间中的位置、旋转和缩放。
  2. 世界空间(World Space)

    • 模型在场景中的位置,旋转和缩放都是在世界空间中定义的。
    • 变换:世界变换(World Transformation)。
  3. 观察空间(View Space 或 Camera Space)

    • 这是从相机视角看到的场景。
    • 变换:视图变换(View Transformation)或摄像机变换。
  4. 裁剪空间(Clip Space)

    • 在这里进行透视除法,得到规范化设备坐标。
    • 变换:透视变换(Perspective Transformation)。
  5. 规范化设备坐标空间(Normalized Device Coordinates,NDC)

    • 所有的顶点坐标都被映射到[-1, 1]的范围内。
    • 变换:规范化。
  6. 屏幕空间(Screen Space)

    • 最后一步变换,将NDC坐标映射到屏幕像素坐标。
    • 变换:视口变换(Viewport Transformation)。

变换的顺序通常是从对象空间开始,经过模型变换,然后是世界变换,接着是视图变换,透视变换,规范化,最后是视口变换。

在图形管线中,几何数据首先被转换到世界空间(World Space),然后到相机空间(Camera Space),接着进行投影变换,得到裁剪空间的坐标。这个裁剪空间的坐标在[-w, w]范围内,其中w是顶点的齐次坐标的w分量。

裁剪空间中的坐标之后会经过视口变换(Viewport Transformation),将其映射到屏幕空间,最终渲染到屏幕上。

在裁剪空间中,可以进行裁剪操作,例如剔除不在视锥体内部的顶点,这样可以提高渲染效率。

在计算裁剪空间坐标时,通常使用齐次坐标来表示顶点位置,这样可以简化透视除法的计算。透视除法将裁剪空间中的坐标转换为规范化设备坐标(Normalized Device Coordinates,NDC),其x、y和z坐标范围在[-1, 1]之间。

案例参考GAMES101 04 games101-变换(模型、视图、投影)-CSDN博客

Three.js

Canvas画布空间(规范化设备空间)(-1,1)

Canvas画布布局和全屏

threejs渲染输出的结果就是一个Cavnas画布,canvas画布也是HTML的元素之一,这意味着three.js渲染结果的布局和普通web前端习惯是一样的。

通过renderer.domElement属性可以访问threejs的渲染结果,也就是HTML的元素canvas画布。

12. Canvas画布布局和全屏 | Three.js中文网

屏幕空间

 坐标转化(屏幕坐标转标准设备坐标)[transformI]

// .offsetY、.offsetX以canvas画布左上角为坐标原点,单位px
const px = event.offsetX;
const py = event.offsetY;
//屏幕坐标px、py转WebGL标准设备坐标x、y
//width、height表示canvas画布宽高度
const x = (px / width) * 2 - 1;
const y = -(py / height) * 2 + 1;

纹理贴图UV坐标空间

顶点UV坐标可以在0~1.0之间任意取值,纹理贴图左下角对应的UV坐标是(0,0)右上角对应的坐标(1,1)

UV纹理空间转到Canvas画布空间(裁剪空间) [transformII]

物体坐标空间

 局部坐标(x,y,z)

坐标转换流程
   模型转换:(不同坐标系)

  局部坐标 -> 世界坐标 -> 观察空间坐标 -> 裁剪空间坐标 -> 屏幕空间坐标

我们将 观察空间坐标系 和 裁剪空间坐标系 之间的转换统一处理,最终得到 标准设备坐标系

  局部坐标 Inverse MVP ->世界坐标 -> MVP标准设备坐标 transformI->屏幕空间坐标

纹理转换:(不同坐标系)

    纹理坐标 (transformII)-->裁剪空间坐标(Inverse MVP)->世界坐标

  ->  (MVP)标准设备坐标  ->(Inverse transformII)纹理坐标

MVP矩阵API
const viewMatrix = orthoCamera.matrixWorldInverse;//视图矩阵:世界到相机的变换矩阵。
const projectionMatrix = orthoCamera.projectionMatrix;//投影矩阵:三维到二维屏幕。
orthVpMatrix = new THREE.Matrix4();
orthVpMatrix.multiplyMatrices(projectionMatrix, viewMatrix);//为先投影,后视图

orthVpMatrix.getInverse()//获取逆矩阵

Matrix4: 用于创建和操作 4x4 矩阵。

// 创建一个单位矩阵

const matrix = new THREE.Matrix4();

// 平移物体

matrix.makeTranslation(x, y, z);

// 旋转物体

matrix.makeRotationX(angle);

// 缩放物体

matrix.makeScale(scaleX, scaleY, scaleZ);

Object3D.matrix: 用于表示物体的变换矩阵。

// 创建一个立方体

const geometry = new THREE.BoxGeometry();

const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });

const cube = new THREE.Mesh(geometry, material);

// 设置物体的位置、旋转和缩放 cube.position.set(x, y, z);

cube.rotation.set(rx, ry, rz); cube.scale.set(sx, sy, sz);

ShaderMaterial.uniforms: 用于向着色器传递 uniform 变量,包括 MVP 矩阵。

// 创建着色器材质

const material = new THREE.ShaderMaterial

({ uniforms:

{ // 传递 MVP 矩阵给着色器

modelViewProjectionMatrix: { value: new THREE.Matrix4() }

},

vertexShader: vertexShaderCode,

fragmentShader: fragmentShaderCode });

以上是一些常用的 MVP 矩阵相关的 API 和方法,可以通过它们来创建和操作模型的视图和投影变换。

Cesium

Cesium中常用的坐标有两种:WGS84地理坐标系笛卡尔空间坐标系。其中,WGS84地理坐标系包括:WGS84经纬度坐标系(没有实际的对象)和 WGS84弧度坐标系(Carto-graphic);笛卡尔空间坐标系包括:笛卡尔空间直角坐标系(Cartesian3)、平面坐标系(Cartesian2),4D笛卡尔坐标系(Cartesian4)。

三维

WGS-84坐标实例创建icon-default.png?t=N7T8https://blog.csdn.net/qq_27814951/article/details/131645978?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171431375216800186598178%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=171431375216800186598178&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-2-131645978-null-null.142%5Ev100%5Econtrol&utm_term=cesium%E4%B8%AD%E5%9D%90%E6%A0%87%E7%B3%BB%E5%8F%8A%E5%85%B6%E8%BD%AC%E6%8D%A2&spm=1018.2226.3001.4187#1.WGS-84%E5%9D%90%E6%A0%87%E5%AE%9E%E4%BE%8B%E5%88%9B%E5%BB%BA

Cartographic

(1)通过弧度创建实例:new Cesium.Cartographic(lng, lat, height)     //lng, lat为弧度,height为高度(m)

(2)通过弧度创建实例:Cesium.Cartographic.fromRadians(lng, lat, height)   //lng, lat为弧度,height为高度(m)

(3)通过角度创建实例:Cesium.Cartographic.fromDegrees(lng, lat, height)    //lng, lat为角度,height高度(m)

弧度与角度转换:

  1. // 弧度转角度

  •  Cesium.Math.toDegrees()
  1. //角度转弧度

  •  Cesium.Math.toRadians()

世界坐标系(笛卡尔)实例创建icon-default.png?t=N7T8https://blog.csdn.net/qq_27814951/article/details/131645978?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171431375216800186598178%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=171431375216800186598178&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-2-131645978-null-null.142%5Ev100%5Econtrol&utm_term=cesium%E4%B8%AD%E5%9D%90%E6%A0%87%E7%B3%BB%E5%8F%8A%E5%85%B6%E8%BD%AC%E6%8D%A2&spm=1018.2226.3001.4187#2.%E4%B8%96%E7%95%8C%E5%9D%90%E6%A0%87%E7%B3%BB%E5%AE%9E%E4%BE%8B%E5%88%9B%E5%BB%BA

Cartesian3

(1)通过笛卡尔空间直角坐标系创建实例:new Cesium.Cartesian3(x, y, z) 

经纬度转Cartesian3

(2)通过弧度创建实例:Cesium.Cartesian3.fromRadians(lng, lat, height)    //lng, lat为弧度,height为高度(m)

(3)通过角度创建实例:Cesium.Cartesian3.fromDegrees(lng, lat, height)    //lng, lat为角度,height为高度(m)

Cesium中的坐标系统及其转换-CSDN博客

(4)   // 方法:借助ellipsoid对象,先转换成弧度再转换
var cartographic = Cesium.Cartographic.fromDegrees(lng, lat, height); //单位:度,度,米 
var cartesian3 = ellipsoid.cartographicToCartesian(cartographic)

  3.WGS-84坐标实例和世界坐标系实例相互转换icon-default.png?t=N7T8https://blog.csdn.net/qq_27814951/article/details/131645978?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171431375216800186598178%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=171431375216800186598178&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-2-131645978-null-null.142%5Ev100%5Econtrol&utm_term=cesium%E4%B8%AD%E5%9D%90%E6%A0%87%E7%B3%BB%E5%8F%8A%E5%85%B6%E8%BD%AC%E6%8D%A2&spm=1018.2226.3001.4187#3.WGS-84%E5%9D%90%E6%A0%87%E5%AE%9E%E4%BE%8B%E5%92%8C%E4%B8%96%E7%95%8C%E5%9D%90%E6%A0%87%E7%B3%BB%E5%AE%9E%E4%BE%8B%E7%9B%B8%E4%BA%92%E8%BD%AC%E6%8D%A2

(1)世界坐标转WGS-84坐标:

  • Cesium.Cartographic.fromCartesian(cartesian3);

(2)WGS-84坐标转世界坐标:

  • Cesium.Cartographic.toCartesian(cartographic);

二维 

Cartesian2->Cartesian3
  • 应用:屏幕坐标转场景坐标-获取倾斜摄影或模型点击处的坐标

 Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene,cartesian3);

viewer.screenSpaceEventHandler.setInputAction(function (event) {
    // 获取屏幕坐标;Cartesian2平面坐标格式
    const windowPosition = event.position; 
    const ray = viewer.camera.getPickRay(windowPosition); //相交的射线
 
    // 获取世界坐标系地表坐标,考虑地形,不包括模型,倾斜摄影模型表面;
    const cartesian = viewer.scene.globe.pick(ray, viewer.scene); 
    
    // 获取倾斜摄影模型或其他三维模型点击位置的世界坐标系场景坐标
    const cartesian = viewer.scene.pickPosition(windowPosition); 
 
    // 获取世界坐标系椭球面坐标,不考虑地形,模型,倾斜摄影模型表面等;
    const cartesian = viewer.scene.camera.pickEllipsoid(windowPosition);     
}) 

空间变换

Cesium为我们提供了很有用的变换工具类:Cesium.Cartesian3(相当于Point3D)Cesium.Matrix3(3x3矩阵,用于描述旋转变换)Cesium.Matrix4(4x4矩阵,用于描述旋转加平移变换),Cesium.Quaternion(四元数,用于描述围绕某个向量旋转一定角度的变换)。

内置变量 

在Cesium中,czm_modelViewProjection是一个内置的变量,代表了模型视图投影矩阵(Model-View-Projection Matrix),用于将顶点从模型坐标系变换到裁剪空间(Clip Space)。

模型视图投影矩阵通常是由三个变换矩阵相乘得到的:

  1. 模型矩阵(Model Matrix):用于将顶点从模型的局部坐标系变换到世界坐标系。
  2. 视图矩阵(View Matrix):用于将顶点从世界坐标系变换到相机(观察者)的坐标系。
  3. 投影矩阵(Projection Matrix):用于将顶点从相机坐标系变换到裁剪空间,通常是一个透视投影或正交投影矩阵。

czm_modelViewProjection实际上是这三个变换矩阵的乘积,即:

czm_modelViewProjection = czm_projection * czm_view * czm_model;

其中:

  • czm_model是模型矩阵。
  • czm_view是视图矩阵。
  • czm_projection是投影矩阵。

这个变量在顶点着色器中使用,用于将顶点位置从模型坐标系转换到裁剪空间。在Cesium中,通过使用这个变量,可以实现模型的位置变换、相机视角变换和投影效果,从而完成基于顶点的渲染。

  • 13
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值