所以我的 opengl es 游戏中有一个纹理(在帧缓冲区中),我一直想模糊它。我一直在尝试多种方法来查看哪一种方法可以获得最好的 FPS,因为这需要实时发生,因为纹理会不断变化。
我究竟如何获取一个 opengles 纹理并将其发送到 coreImage,然后返回到 opengles 进行显示?
这是一些基本上你放在 UIImage 中的代码,它返回一个模糊的。我卡住的地方是将纹理获取到 UIImage,我想知道它们是否是一种更好的方法,然后每次加载新的 UIImage。
- (UIImage *)blurredImageWithImageUIImage *)sourceImage{
// Create our blurred image
CIContext *context = [CIContext contextWithOptions:nil];
CIImage *inputImage = [CIImage imageWithCGImage:sourceImage.CGImage];
// Setting up Gaussian Blur
CIFilter *filter = [CIFilter filterWithName"CIGaussianBlur"];
[filter setValue:inputImage forKey:kCIInputImageKey];
[filter setValue:[NSNumber numberWithFloat:15.0f] forKey"inputRadius"];
CIImage *result = [filter valueForKey:kCIOutputImageKey];
/* CIGaussianBlur has a tendency to shrink the image a little, this ensures it matches
* up exactly to the bounds of our original image */
CGImageRef cgImage = [context createCGImage:result fromRect:[inputImage extent]];
UIImage *retVal = [UIImage imageWithCGImage:cgImage];
return retVal;
}
如图所示,核心图像可能比最有效的方法更好。
Best Answer-推荐答案 strong>
如果您还没有尝试并注意到,您引用的方法会杀死性能——要从 GL 纹理创建 UIImage ,您需要阅读一堆像素离开 GPU 并进入 CPU 内存。然后 CoreImage 可能会将其发送到 GPU 以执行其效果,但是由于您从中获得了 UIImage ,因此您在将图像发送回 GPU 之前再次从 GPU 读取用作纹理。那是每帧四次数据传输,而且每一次都很昂贵。
相反,将 Core Image 保留在 GPU 上,并且不要使用中间的 UIImage 。
您需要保留一个 CIContext 以进行渲染,因此请尽早使用 contextWithEAGLContext: 从您的 GL 上下文中创建一个并坚持下去。
使用 imageWithTexture:size:flipped:colorSpace: 从您的 GL 纹理创建 CIImage 。
当您想将过滤器链的结果渲染到 GL 纹理时,将其与 glBindFramebuffer 绑定(bind)(就像您制作自己的渲染到纹理传递一样),并使用 drawImage:inRect:fromRect: 在您的 CIContext 中绘制过滤器的输出 CIImage . (并且不要忘记在使用它执行其他 GL 渲染之前重新绑定(bind)该纹理。)
这在 2012 年的 WWDC 演讲中得到了很好的介绍:Core Image Techniques .讨论从 40:00 左右开始,代码和演示持续到 46:05 左右。但是在接下来的演讲中,您将获得更多的演示、灵感、代码和架构技巧,这些都是您可以在 GL 中使用 CoreImage 做的有趣事情,让游戏看起来很棒。
此外,如果您使用 Metal ( |