沙,
我所做的是在我的 OpenGL 坐标中布置一个矩形网格点。(我使用了 50x50 的网格)。然后我在同一坐标空间中定义一个或多个控制点。我有一个我写的通用捏拉伸算法。它需要一个控制点、一个半径和一个有符号整数来表示吸引/排斥网格点的数量,并将其应用于我的网格坐标。对于捏合,它将网格点拉近控制点,而对于拉伸,它将控制点推开。变化在控制点处最大,随着与控制点的距离增加到半径值而下降。
一旦我改变了我的网格的坐标,我就定义了一组三角形条带来绘制我的图像的整个(扭曲的)矩形区域。我可以通过一个 OpenGL 绘图调用将我的整个纹理渲染到扭曲的网格上。OpenGL 负责拉伸图像像素以适应我的控制点网格中的扭曲三角形。这是一个使用多个控制点创建胖脸外观的前后图像示例。它显示了网格,因此您可以看到它在做什么。这是我的丑杯子,所以提前道歉:

和拉伸的图像:

在我的例子中,我希望图像周边的控制点保持在原位,并且只有图像的内部会被扭曲,所以我添加了额外的代码逻辑来将周边控制点锁定到位。这就是为什么图像的框架没有像您的图像那样被推入。然而,这需要额外的代码。
代码最终使用距离公式计算出每个网格点与控制点的距离,然后触发计算角度,乘以改变距离,然后再触发计算每个网格的新位置-观点。不过,由于我只转换了一个 50x50 的控制点网格,它的速度足以跟上。
我们的应用程序 Face Dancer 在应用商店免费提供。(在此链接下载它:应用商店中的 Face Dancer您可能想下载并尝试一下。(它包括许多免费的变形,然后提供额外的变形作为应用内购买)还有一个付费的“ Plus”版本,包含所有变形。
当您运行 Face Dancer 时,如果您用两根手指在图像上双击,它会显示用于创建变形的控制点网格,以便您可以看到它在做什么。
有一个名为 GLCameraRipple 的 OpenGL 示例应用程序,它包含在 Xcode 中并从文档链接。我建议将其作为起点。它从摄像头获取视频并将其绘制到屏幕上。如果您触摸屏幕,它会扭曲图像,就好像屏幕是一池水,而您的手指会在其中产生涟漪。它使用了我所描述的网格扭曲技术。
不幸的是,我不认为该应用程序使用 GLKit,这是使用 OpenGL ES 2.0 的一种更简单的方法。GLKit 提供了许多使其更易于使用的功能,包括 GLKViews 和 GLKViewControllers。