我正在尝试使用Unity中的天空球将鱼眼图像映射到360度视图。场景在球体内部。我非常接近,但我看到一些轻微的扭曲。我正在计算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纹理:
数学不是我的强项,我在这里做错了什么,或者这种映射是不是100%可能?
答案 0 :(得分:1)
你看到的地方是r非常接近1的情况。正如你在源图像中看到的那样,这是非常扭曲的图像数据和黑色之间的边界区域。
这个区域非常扭曲,但这不是主要问题。查看结果,您可以看到UV方向存在问题。
我在源图片中添加了几行来演示我的意思。在r很小(黄线)的地方,您可以看到UV坐标可以在四边形的角之间进行插值(假设四边形而不是三角形)。然而,在r很大(红色角落)的情况下,插值UV坐标将使它们穿过源图像的区域,其中r远小于1(红线),从而导致UV空间的扭曲。实际上,那些红线不应该是直的,但它们应该沿着源图像数据的边界传播。
你可以通过在你的天体区域中获得更高的多边形来改善这一点,其中r接近1,但只要你的UV以线性方式插值,它就永远不会完美。
我还发现了另一个问题。如果你仔细观察现场,你会发现完整的源图像存在于那里。这是因为您的UV坐标在此处环绕。当渲染在观察者周围传播时,uv坐标从0向1行进。在它们处于1的点处,相邻顶点为0.001或者某种东西,导致整个源图像在其间呈现。要解决这个问题,你需要在天体的接缝处有两个单独的顶点,一个是球体表面开始的,另一个是结束的顶点。在对象空间中它们是相同的,但在uv空间中,一个是0,另一个是1。