【问题标题】:How do I apply proper perspective to this OpenGL ES texture?如何对这个 OpenGL ES 纹理应用正确的透视?
【发布时间】:2012-05-05 11:49:44
【问题描述】:

我想描述一下我的目标,并获得一些对提议的解决方案的反馈。我对 OpenGL ES(或根本没有 OpenGL)很陌生,所以请温柔一点。我还想提一下,该平台是 iPad (iOS),它有归属限制。

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

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

现在,一种方法是在 OpenGL ES 上设置一个带有平截头体的透视图。然后放一个平面(如下图)并将图像纹理放在上面以供初学者使用。

现在,正如您从上图的外观所预期的那样,图像将被扭曲。但这很好,因为如果我们将平面向后倾斜(使其完美地适应显示器的边界),图像将显示为正方形。

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

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

【问题讨论】:

    标签: ios image opengl-es 3d textures


    【解决方案1】:

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

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

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

     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 中,应该很容易理解。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 谢谢。考虑不使用 OpenGL,可以想象我们可以处理正交视图,并通过在照片中越远(向上)缩小它的宽度来以某种方式调整纹理。这可能更像是一种黑客行为。但再一次,考虑一下 OpenGL 的方式。你认为它适用于“任何”倾斜角 0
      • 您最好使用 OpenGL,因为它们离您越远,纹理收缩背后的算法已经得到处理。您可以将一个平面(您房子的图片平面)设置为正交以使其更易于处理,并将旋转平面设置为透视。只要你不把你的纹理绘制到无限的平面上,你就不会有问题。 OpenGL 非常健壮,因为它基本上是一组直接在平面上绘制的函数。
      • 再次感谢您,这听起来很聪明。我还对如何将顶点拆分为多边形并进一步拆分为三角形进行了一些研究。由于 ES 只支持绘制三角形。但我找不到一个聪明的方法。我发现,我猜你必须假设用户逆时针(或类似的东西)绘制区域才能真正知道要铺什么。
      猜你喜欢
      • 1970-01-01
      • 2019-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-05
      • 1970-01-01
      • 2012-05-27
      相关资源
      最近更新 更多