如何对此OpenGL ES纹理应用正确的透视图?

时间:2012-05-05 00:44:47

标签: ios image opengl-es 3d textures

我想描述一下我的目标并获得一些建议解决方案的反馈。我对OpenGL ES(或OpenGL)都很陌生,所以请保持温和。我还想提一下,该平台是iPad(iOS)及其所属的限制。

目标:让用户放置应在正确的视角(或至少可调整的视角)正确绘制纹理的顶点。要解释我的意思,请考虑以下示例。

假设我们有一张房子的照片,房子前面有相应的草坪。现在,我想用一个(用户)指定的路径铺设瓷砖(纹理),使透视看起来正确。如果视图只是正交,则图块将是完全正方形,这在图像中具有某种深度时是不现实的。

现在,一种方法是在OpenGL ES上设置带有平截头体的透视图。然后放一个平面(如下图所示)并将图像纹理放在它上面。

Plane to put image texture on

现在,正如您对上图所示的预期,图像将会失真。但它很好,因为如果我们向后倾斜平面(使其完全适合显示的边界),图像将呈现方形。

如果用户现在定义要铺设的区域,我们可以将这些点放在与倾斜平面相同的角度,然后只放置一个带有方形瓷砖的纹理,它们将以透视图显示。如果我们的倾斜角度不正确,用户可以手动调整,然后发生的情况是上图中平面的角度角度将被调整,平面将以不同方式倾斜以适合显示器。然后,瓷砖纹理将以不同的角度出现。

这是一种可行的方法还是有其他更好的方法来做到这一点?我认为这可能与我在3D编程方面的有限技能有关。

2 个答案:

答案 0 :(得分:3)

如果您只想对图像应用透视图,那么您甚至可能不需要OpenGL ES。你可以简单地创建一个合适的CATransform3D,并按照我在this answer中描述的方式将其设置为UIView或CALayer。关键是变换矩阵的m34分量。

如果您仍想使用OpenGL ES和纹理执行此操作,则可以将变换应用于纹理四边形的顶点以创建透视效果。这方面的一个例子可以在这里看到:

Perspective transform on a quad

我转换纹理显示相机输入,以便它具有应用于它的透视效果。这是使用以下顶点着色器完成的:

 attribute vec4 position;
 attribute vec4 inputTextureCoordinate;

 uniform mat4 transformMatrix;
 uniform mat4 orthographicMatrix;

 varying vec2 textureCoordinate;

 void main()
 {
     gl_Position = transformMatrix * vec4(position.xyz, 1.0) * orthographicMatrix;
     textureCoordinate = inputTextureCoordinate.xy;
 }

我以下列方式生成了基于CATransform3D的矩阵:

 CATransform3D perspectiveTransform = CATransform3DIdentity;
 perspectiveTransform.m34 = 0.4;
 perspectiveTransform.m33 = 0.4;
 perspectiveTransform = CATransform3DScale(perspectiveTransform, 0.75, 0.75, 0.75);
 perspectiveTransform = CATransform3DRotate(perspectiveTransform, rotation, 0.0, 1.0, 0.0);

然后将CATransform3D转换为mat4(它具有4x4矩阵内部结构,因此这很容易)。如果要查看此操作,请在我的GPUImage框架中获取FilterShowcase示例应用程序的代码,然后尝试3-D Transform条目。代码全部在GPUImageTransformFilter中,应该相当容易理解。

答案 1 :(得分:0)

这是最简单的方法。无论如何,您都必须显示一个与正确消失点成角度的平面,因此让用户自己旋转平面是一个可行的解决方案。否则,这是一个图像处理问题。如果你有兴趣,我会研究计算机视觉中的消失点测定。