CubeMap转全景图

Number of views 78

CubeMap如何转全景图的算法分析。

v253d177ebe14d8523f93d5731cde492421440w.png

CubeMap的顶点坐标可以通过上图简化表示。在3D引擎构建:WebGL Skybox实现已有说明。

v2c500f8e361a0514c350e730436446d05r.png

文章中已经介绍如何通过顶点坐标映射为CubeMap的纹理坐标。本文的理论基础基于上述链接。

要把CubeMap转为全景图,实际上就是把CubeMap的像素点平铺到一张平面图的过程。

v240843c8a83e5f43462f2c03b067a4f0f1440w.png

其中,图宽2PI表示横向可以360°采样CubeMap的像素信息。图高PI用于表示对CubeMap的纵向角度采样。

而底边坐标(0, 0),... (PI, 0), .... (2PI, 0)表示采样点为CubeMap底面中心点,坐标为(0,-1,0)。顶边坐标(0, PI), ... (PI, PI), ... (2PI, PI)表示采样点为CubeMap的顶面中心点,坐标为(0, 1, 0)。

并且已知底边采样时的纵向采样角度为0,顶边采样时的纵向采样角度为PI,又由于不管是顶变还是底边的横坐标角度如何变化都不影响所属边采样角度的坐标值。再根据这两边的采样坐标可得出在采样CubeMap时uvs坐标中v的一般式为:

// y
float vTheta = i.uv.y * PI;
// x
float uTheta = i.uv.x * 2 * PI;
// uvs
float3 unit = float3(0,0,0);
unit.x = ...;
// v
unit.y = cos(vTheta) * -1;
unit.z = ...;

(0, PI/2)表示的采样点为(0, 0, -1);

(PI, PI/2)表示的采样点为(0, 0, 1);

(2PI, PI/2)表示的采样点为(0, 0, -1);

根据这三个坐标与对应采样角度中,由于纵向采样角度PI/2不变,所以纵向角度PI/2对坐标不产生影响并且所得的结果必然为1(因为纵向角度改变后,坐标值也会改变,所以这个角度又不能被忽视),可推出这一项中必然有sin(vTheta),接着可推出uvs坐标中s的一般式为:

// ...
unit.z = cos(uTheta) * sin(vTheta) * -1;

(PI/2, PI/2)表示的采样点为(-1, 0, 0);

(3PI/2, PI/2)表示的采样点为(1, 0, 0);

根据这二个坐标与对应采样角度中,同上可证:

// ...
unit.x = sin(uTheta) * sin(vTheta) * -1;
// ...

项目地址为:Cocos Store

0 Answers