我正在尝试使用 Unity 中的天空球体将鱼眼图像映射到 360 度 View 。场景位于球体内部。我非常接近,但我看到一些轻微的失真。我正在计算 UV 坐标如下:
Vector3 v = currentVertice; // unit vector from edge of sphere, -1, -1, -1 to 1, 1, 1
float r = Mathf.Atan2(Mathf.Sqrt(v.x * v.x + v.y * v.y), v.z) / (Mathf.PI * 2.0f);
float phi = Mathf.Atan2(v.y, v.x);
textureCoordinates.x = (r * Mathf.Cos(phi)) + 0.5f;
textureCoordinates.y = (r * Mathf.Sin(phi)) + 0.5f;
这是失真和三角形:
整个球体的其余部分看起来很棒,只是在这一点我得到了失真。
这是源鱼眼图像:
顶部带有 UV 测试纹理的相同球体显示相同的变形区域。完整的 UV 测试纹理在右侧,虽然为了我的屏幕截图,它在右侧被拉伸(stretch)成矩形,但它是一个正方形。
上面的失真是使用球体贴图而不是鱼眼贴图。这是使用鱼眼贴图的 UV 纹理:
数学不是我的强项,我在这里做错了什么还是这种映射根本不是 100% 可能的?
最佳答案
您看到的点是 r 非常接近 1 的情况。正如您在源图像中看到的那样,这是非常扭曲的图像数据和黑色之间的边界区域。
这个区域非常扭曲,但这不是主要问题。查看结果,您可以看到 UV 方向存在问题。
我在您的源图像中添加了几行来说明我的意思。当 r 很小(黄线)时,您可以看到 UV 坐标可以在四边形的角之间进行插值(假设四边形而不是三边形)。但是,如果 r 很大(红角),则插入 UV 坐标将使它们穿过源图像中 r 远小于 1 的区域(红线),从而导致 UV 空间失真。实际上,这些红线不应该是直线,而是应该沿着源图像数据的边界行进。
您可以通过在 r 接近 1 的天球区域使用更高的多边形数来改善这一点,但只要您的 UV 以线性方式插值,它就永远不会完美。
我还发现了另一个问题。如果您仔细观察该位置,您会发现完整的源图像很小。这是因为您的 UV 坐标在该点环绕。当渲染通过观察者时,uv 坐标从 0 向 1 行进。在它们位于 1 的地方,相邻顶点在 0.001 或其他位置,导致整个源图像在中间渲染。为了解决这个问题,你需要在天空球的接缝处有两个单独的顶点,一个是球体表面的起点,一个是它的终点。在对象空间中,它们是相同的,但在 uv 空间中,一个位于 0,另一个位于 1。
关于image-processing - 将鱼眼映射到球体 - 360 度 View ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36603888/