将地球的卫星照片转换为球体上的纹理贴图(OpenGL ES)

时间:2012-06-24 18:16:56

标签: ipad 3d opengl-es-2.0

我们有5颗地球静止卫星,在赤道周围间隔(不是等距,但差不多)每天拍摄地球照片。每张照片的输出是 - 惊喜! - 从远处拍摄的球体照片。

我需要将这些照片重新组合成一个纹理映射的球体,我不知道如何最好地做到这一点。关键问题:

  1. 这些照片 - 显然 - 从中​​心越远越大,因为他们正在看球体
  2. 在一天中的不同时间拍摄了5张照片中有数百张“套”。任何解决方案都需要是程序化的 - 我不能手工做到这一点:(
  3. 输出平台是iPad3:Open GL ES 2,纹理高达4096x4096 - 但不如桌面GPU强大。我对着色器不太好(虽然我做了很多OpenGL预着色器)
  4. 照片本身是高分辨率的,我不确定我可以同时加载所有5个纹理。我还为行星表面(卫星照片下方)加载了一个非常高分辨率的纹理。
  5. 我已经有了:一个矩形纹理映射到一个球体上(我的球体是一个包裹在一个球体中的标准网格,顶点在表面上均匀分布),所以......我尝试将5张球体照片转换成一个矩形的地图(但到目前为止没有成功;虽然有人指着我做了一个“极地蜿蜒曲线”,看起来它可能效果更好)。

    我还想过用5张照片制作立方体贴图做一些时髦的事情,并且聪明地决定要为给定的像素读取哪些照片,但我并不完全相信。

    有更好的方法吗?我忽略了什么?或者有没有人有一个实现上述目标的具体方法?

1 个答案:

答案 0 :(得分:0)

我会从中做一个矩形纹理。

您需要2 x 2D 纹理/数组,其中一个用于r,g,b颜色求和平均值,另一个用于计数 cnt 。另外我不相信我会使用 OpenGL / GLSL ,因为在我看来C / C ++会更好。

我会这样做:

  1. 清空目标纹理(avg[][]=0, cnt[][]=0
  2. 获取卫星位置/方向,时间

    从位置和方向创建变换矩阵,以与照片相同的方式投射地球。然后从时间确定轮换班次。

  3. 循环遍历整个地球表面

    只有两个嵌套循环a - 旋转和`b - 距赤道的距离。

  4. x,y,z获取a,b并转换矩阵+轮换转换(a - 轴)

    也可以倒退a,b,z = f(x,y),但它更棘手,但更快,更准确。您还可以在相邻的x,y,z

  5. 之间插入(pixels/areas)[a][b]
  6. 添加像素

    如果x,y,z位于正面(z>0z<0取决于相机Z方向),那么

    avg[a][b]+=image[x][y]; cnt[a][b]++;
    
  7. 来自第3点的嵌套循环结束。

  8. 转到下一张照片的#2
  9. 循环遍历整个avg纹理以恢复平均颜色

    if (cnt[a][b]) avg[a][b]/=cnt[a][b];
    
  10. <强> [注释]

    1. 可以测试复制的像素是否为:

      在白天或晚上获得(仅使用你想要的东西而不是混合在一起!!!)也可以确定云(我认为灰色/白色的颜色不是雪)并忽略它们。

    2. 不要溢出颜色

      可以使用3个单独的纹理r[][],g[][],b[][]代替avg来避免

    3. 可以忽略靠近地球边缘的区域以避免扭曲

    4. 可以应用照明修正

      timea,b坐标标准化照明

    5. 希望它有所帮助...

      [Edit1]正交投影

      所以这里明确我的意思是正交投影:

      Satellite photo texture (EUMETSAT)

      这是使用纹理(无法找到更适合和免费的网络),并希望使用真正的卫星图像而不是一些渲染......

      orthogonal projection

      这是我的正交投影App

      • 红色,绿色,蓝色线是地球坐标系(x,y,z轴)
      • (红色,绿色,蓝色)白色线是卫星投影坐标系(x,y,z轴)

      关键是要将地球顶点坐标(vx,vy,vz)转换为卫星坐标(x,y,z),如果z >= 0则为其处理纹理的有效顶点,以便直接从x,y计算纹理坐标没有任何观点(正交)。

      例如tx=0.5*(+x+1); ...如果x缩放为<-1,+1>且可用纹理为tx <0,1> y轴也是如此:{{1如果ty=0.5*(-y+1);缩放为y且可用纹理为<-1,+1>(我的相机具有与ty <0,1>坐标系相对应的纹理矩阵,那么y上的倒置符号{ {1}}轴)

      如果y那么你正在处理纹理范围之外的顶点所以忽略它...  正如你在图像上看到的那样,纹理的外边界是扭曲的,所以你应该只使用内部(例如70%的地球图像区域),你也可以根据纹理中点的距离做一些纹理坐标校正。完成后,只需将所有卫星图像投影合并到一个图像即可。

      [编辑2] 我玩了一点,发现了这个:

      • 反投影校正根本不适用于我的纹理我觉得它可能是后处理图像......
      • 基于中点距离的校正看起来不错,但是使用的比例系数是奇数没有线索为什么要乘以6时应该是4我认为......

        z < 0

      corrected nonlinear projection

      • 校正非线性投影(by asin)

      corrected nonlinear projection edge zoom

      • 校正非线性投影边缘缩放
      • 扭曲比使用tx=0.5*(+(asin(x)*6.0/M_PI)+1); ty=0.5*(-(asin(y)*6.0/M_PI)+1); 纹理坐标修正
      • 小得多