cesium 渲染分析(以太阳为例),实现卫星任务规划中地球赤道平面绘制

分析太阳的绘制,对绘制赤道和其它天体有很大的启发。

太阳的定义在文件sun.js 中

function Sun() {
  /**
   * Determines if the sun will be shown.
   *
   * @type {Boolean}
   * @default true
   */
  this.show = true;

  this._drawCommand = new DrawCommand({
    primitiveType: PrimitiveType.TRIANGLES,
    boundingVolume: new BoundingSphere(),
    owner: this,
  });
  this._commands = {
    drawCommand: this._drawCommand,
    computeCommand: undefined,
  };
  this._boundingVolume = new BoundingSphere();
  this._boundingVolume2D = new BoundingSphere();

  this._texture = undefined;
  this._drawingBufferWidth = undefined;
  this._drawingBufferHeight = undefined;
  this._radiusTS = undefined;
  this._size = undefined;

  this.glowFactor = 1.0;
  this._glowFactorDirty = false;

  this._useHdr = undefined;

  var that = this;
  this._uniformMap = {
    u_texture: function () {
      return that._texture;
    },
    u_size: function () {
      return that._size;
    },
  };
}

在这个文件中,定义了它的_drawCommand, DrawCommand类在cesium中有举足轻重的地位,在场景中绘制的任何对象,最后都会转换为具体的DrawCommand。

sun对象的创建时机,我们跟踪代码发现在cesiumWidget的构造函数里面,创建了sun对象,并把它作为场景的一个成员。

  if (skyBox !== false) {
      scene.skyBox = skyBox;
      scene.sun = new Sun();
      scene.moon = new Moon();
  }

Shader在文件sunVS.js  ,需要进一步分析。

下面仿照太阳的渲染方式,我们实现了赤道平面的绘制。

 

太阳位置的计算,对卫星的任务分析很重要,在对地观测任务中,我们应当充分考虑太阳的照射情况。在涉及太阳位置计算时,应该弄清楚几种天球坐标系和地球坐标的概念。

天球坐标系

然后需要了解,天极、天轴等概念

我们知道,坐标轴确定了,坐标系也就确定了。 如果三个轴中的两个轴确定了,那么另外一个轴根据右手规则也相应确定了。地球质心到春分点的方向为X轴,地球自转轴指向北极的方向为Z轴正向,由于地球自转过程中,由于月球和其它因素的干扰,会产生章动现象,所有它的自转轴并不固定,看起来就像个摇摇晃晃的陀螺:

这样运动中不断变化的坐标系当然不利于描述其它天体的位置,解决方案有两个,取某一瞬时的天球三轴为坐标系,就像给运动过程在的汽车,很难讲它的精确为位置,但我可以给它拍照,以相片上汽车当时的位置为准。另一种方案,大家约定一个具体的时间,以该具体时间为准,将天球的三个轴固定下来。

上面这个划分就更细了,又增加了“改动”与“不改动”的区别。所以在碰到描述太阳位置的地方,需要仔细区别当时采用的坐标系。下面来说说地球坐标系。

地心惯性坐标系(ECI×J2000历元坐标系)

   地心惯性坐标系是太阳系内的一个惯性坐标系,不随地球而转动,也不受地球、太阳运行的章动和岁差的影响。其坐标原点位于地心0e;OeX轴位于赤道平面内,指向特定某一年(历元时刻)的太阳春分点位置;Oez轴指向某一年(历元时刻)地球北极的平均位置处;Ocy轴位于赤道平面内,与0eX轴垂直,且与0cX、9ez构成满足右手定则的笛卡儿直角坐标系。由于采用的历元时间不同,可以有各种不同的地心惯性坐标系,目前国际上通用的地心惯性坐标系J2000历元坐标系,它是以公元2000年的春分点为基准的历元坐标系。

地心固定坐标系(ECF)

  地心固定坐标系的坐标原点位于地心0c,Oez轴指向地球北极,Oe凭轴位于赤道平面内指向地理经度的零点,Oey轴根据右手定则确定。地心固定坐标系为笛卡尔直角坐标系,该坐标系在宇宙空间中相对地球静止,伴随地球自转和公转。

很多人弄不懂这两种坐标系的区别,其实很简单能区分, 地心地固坐标系ECF的特点是, 地球背着这个坐标系在跑.

ICRF(International Celestial Reference Frame).

ICRF坐标系为惯性坐标系(无旋转)。ICRF坐标系是目前为止最理想的惯性坐标系,对J2000坐标系进行了改进ICRF和J2000坐标系非常接近,但并不相同。与ICRF坐标系相比,J2000坐标系随时间缓慢旋转。最新的星历大部分都在ICRF坐标系中定义。对地球固定坐标系利用算法进行转换从而得到ICRF坐标系。最新的算法使用了P03进动模型、IAU2000A章动模型(进行了调整)和地球自转角(以UT1时间的线性函数来表示),该算法始于2009年1月1日。写作该文档时(2009年1月),IERS(the International Earth rotation and Reference systems Service)没有提供这些模型的可用文档,AGI使用的是SOFA(Standards of Fundamental Astronomy)代码,这些代码可用于计算天文年历。IAU2000A章动模型和地球自转角见IERS技术文档IERS Conventions 2003,文档编号Technical Note No. 32。
(https://blog.csdn.net/stk10/article/details/103263324可以简单理解为, ICRF是J2000的升级版本.

ITRF坐标系

协议地球坐标系(CTS)又称为地球参考系统(ITRS),国际地球参考框架(ITRF)是ITRS的具体实现。ITRS与ITRF由地球自转与参考系统服务(IERS)组织维持与更新,通过IERS分布于全球的跟踪站的坐标和速度场来维持并提供用户使用。现已发布的ITRF系列有ITRF88、ITRF89、ITRF90、ITRF91、ITRF92、ITRF93、ITRF94、ITRF96、ITRF2000、ITRF2005、ITRF2008等全球参考框架。就是我们常说的地固坐标系,其原点在地球质心(包含大气海洋等质量),坐标系xy平面为地球赤道面,z轴指向北极CIO处,x轴指向格林威治子午线与赤道面交点处。可以简单理解为,ITRF是ECF坐标的一种。

下面我看看跟太阳位置相关的几个函数

/**
 * Computes a rotation matrix to transform a point or vector from the International Celestial
 * Reference Frame (GCRF/ICRF) inertial frame axes to the Earth-Fixed frame axes (ITRF)
 * at a given time.  This function may return undefined if the data necessary to
 * do the transformation is not yet loaded.
 *
 * @param {JulianDate} date The time at which to compute the rotation matrix.
 * @param {Matrix3} [result] The object onto which to store the result.  If this parameter is
 *                  not specified, a new instance is created and returned.
 * @returns {Matrix3} The rotation matrix, or undefined if the data necessary to do the
 *                   transformation is not yet loaded.
 *
 *
 * @example
 * scene.postUpdate.addEventListener(function(scene, time) {
 *   // View in ICRF.
 *   var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time);
 *   if (Cesium.defined(icrfToFixed)) {
 *     var offset = Cesium.Cartesian3.clone(camera.position);
 *     var transform = Cesium.Matrix4.fromRotationTranslation(icrfToFixed);
 *     camera.lookAtTransform(transform, offset);
 *   }
 * });
 *
 * @see Transforms.preloadIcrfFixed
 */
Transforms.computeIcrfToFixedMatrix = function (date, result) {
  //>>includeStart('debug', pragmas.debug);
  if (!defined(date)) {
    throw new DeveloperError("date is required.");
  }
  //>>includeEnd('debug');
  if (!defined(result)) {
    result = new Matrix3();
  }

  var fixedToIcrfMtx = Transforms.computeFixedToIcrfMatrix(date, result);
  if (!defined(fixedToIcrfMtx)) {
    return undefined;
  }

  return Matrix3.transpose(fixedToIcrfMtx, result);
};

上面函数的说明中,明确指出,它计算的是一个从ICRF坐标系到ITRF坐标系的变换矩阵。根据上面的概念的理解,可以认为这个函数得到的矩阵是一个从惯性系到地心地固系的转换矩阵。

function setSunAndMoonDirections(uniformState, frameState) {
  if (
    !defined(
      Transforms.computeIcrfToFixedMatrix(frameState.time, transformMatrix)
    )
  ) {
    transformMatrix = Transforms.computeTemeToPseudoFixedMatrix(
      frameState.time,
      transformMatrix
    );
  }

  var position = Simon1994PlanetaryPositions.computeSunPositionInEarthInertialFrame(
    frameState.time,
    uniformState._sunPositionWC
  );
  Matrix3.multiplyByVector(transformMatrix, position, position);

  Cartesian3.normalize(position, uniformState._sunDirectionWC);

  position = Matrix3.multiplyByVector(
    uniformState.viewRotation3D,
    position,
    uniformState._sunDirectionEC
  );
  Cartesian3.normalize(position, position);

  position = Simon1994PlanetaryPositions.computeMoonPositionInEarthInertialFrame(
    frameState.time,
    uniformState._moonDirectionEC
  );
  Matrix3.multiplyByVector(transformMatrix, position, position);
  Matrix3.multiplyByVector(uniformState.viewRotation3D, position, position);
  Cartesian3.normalize(position, position);

  var projection = frameState.mapProjection;
  var ellipsoid = projection.ellipsoid;
  var sunCartographic = ellipsoid.cartesianToCartographic(
    uniformState._sunPositionWC,
    sunCartographicScratch
  );
  projection.project(sunCartographic, uniformState._sunPositionColumbusView);
}

上面函数,先计算太阳在地球惯性系上的坐标,然后乘上一个矩阵,得到地心地固坐标下面的位置,具体代码如下:

 var position = Simon1994PlanetaryPositions.computeSunPositionInEarthInertialFrame(
    frameState.time,
    uniformState._sunPositionWC
  );
  Matrix3.multiplyByVector(transformMatrix, position, position);

好勒,本贴就分析到此处,以后准备讨论如何在cesium上画出日照线。毕竟日照对卫星对地观测任务是一个关键因素。  累了,休息。   2021.5.3    五一快乐。

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Cesium 是一个基于 WebGL 的开源地球渲染引擎,主要用于在浏览器呈现三维地理数据。它使用了一些复杂的渲染技术和算法来实现高性能和高质量的地球渲染效果。下面是对 Cesium 渲染源码的简要分析: 1. Shader:Cesium 使用了大量的着色器程序来实现不同的渲染效果,如光照、纹理映射、阴影等。着色器程序是在 GPU 上执行的,并且可以通过 GLSL(OpenGL Shading Language)语言进行编写。Cesium 的着色器程序通常是在运行时动态生成的,以适应不同的地图数据和渲染需求。 2. 地形渲染Cesium 支持高度精细的地形渲染,它使用了基于切片的地形渲染技术。在渲染过程Cesium 会将地球表面分割成小块切片,并根据每个切片的高度数据和纹理信息生成相应的网格和纹理。这些切片可以根据需要进行加载和卸载,以实现地图数据的动态加载和显示。 3. 纹理映射:Cesium 使用了纹理映射技术来实现地球表面的贴图效果。它可以将不同类型的纹理(如卫星图像、地形纹理、气候数据等)映射到地球表面的不同部分,以实现真实的地貌效果。Cesium 通过加载和解析各种类型的地图数据,将其转换为纹理信息,并将其应用到地球表面的相应区域。 4. 光照和阴影:Cesium 支持实时的光照和阴影效果,以增强地球渲染的真实感。它使用了基于物理的光照模型,考虑了光源的位置、光照强度、表面材质等因素,并通过计算每个顶点和像素的光照实现逼真的光照效果。此外,Cesium 还支持动态阴影的生成,可以根据光源的位置和地形的形状计算出地球表面上的阴影效果。 5. 动态渲染Cesium 支持动态渲染技术,可以在实时交互的情况下实现高性能的地球渲染效果。它使用了一些优化技术,如级联阴影映射、视锥剔除、LOD(Level of Detail)等,以减少渲染负载并提高渲染效率。此外,Cesium 还支持动态加载和卸载地图数据,以实现在不同的视角和缩放级别下的快速渲染和响应。 需要注意的是,Cesium 的源码非常庞大和复杂,涉及到多个模块和子系统。以上只是对其渲染部分的简要分析,实际的源码分析需要深入研究 Cesium 的代码库和文档,并对 WebGL 和图形渲染技术有一定的了解。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值