ios - iOS上的Accelerate框架可以用来画圆吗?

标签 ios opengl-es gpuimage accelerate-framework

我正在尝试编写一个 GPUImageFilter 子类,它可以渲染数千个羽毛圆圈(是的,这是一个画笔描边)。我当前的方法包括调用glDrawArrays来绘制一吨正方形,以及每个正方形的顶点属性,该顶点属性通知片段着色器每个正方形的质心在哪里,以便着色器可以绘制一个其alpha值的圆形向边缘(距离质心最远)逐渐变细。

这在我的测试设备(iPad Mini)上已经足够快了,除非 (a) 圆圈超过 1,000 个,或者 (b) 圆圈非常大。多边形速度很快,但着色器速度很快。

我想知道将圆圈直接渲染到字节缓冲区是否会更快,并让 GPUImage(使用 GPUImageRawDataInput)尽可能抓取字节以进行渲染(通过其他过滤器)屏幕。

Accelerate 框架是我所知道的在 iOS 上操作字节的最快方法。我发现我可以使用此方法非常快速地用 vDSP 填充 RGBA 缓冲区:

const int iValue = [RGBA colour as int];

vDSP_vfilli(&iValue, (int*)bytes, 1, width * height);

有人可以建议我如何使用 vDSPvImage 函数集将羽化圆圈渲染到我的字节缓冲区中吗?我想到的唯一方法是使用太多 for 循环来提高性能。

最佳答案

要绘制许多羽状圆圈,您可能找不到比使用许多四边形和片段着色器更好的方法了。您在这里似乎遇到的性能问题是需要将任意数量的重叠圆形元素混合在一个框架中。您不仅需要处理大量并行像素,而且还有大量可能影响每个像素的圆圈。

我在 Molecules 应用程序中遇到了类似的问题,并在 this question 中询问如何调整我的着色器。 。就分子而言,我正在绘制边缘锋利的球体冒名顶替者,但我仍然需要将数千个或非常大尺寸的球体混合在一起。

您可以立即采取一些措施来提高片段着色器的性能(不幸的是,如果没有您正在使用的代码,我只能猜测您是否正在这样做)。首先,如果着色器中有分支,请删除分支。使用 step() (在您的情况下最有可能是 smoothstep())来替换 if 语句。其次,将所有可以进行的计算转移到顶点着色器中。顶点着色器仅针对四边形的每个顶点运行一次,而不是每个像素运行一次的片段着色器。我为四个顶点中的每一个传递了标准化的 -1,-1 到 1,1 坐标,这使得在片段着色器中计算距中心点的距离变得更简单。

禁用混合可以大大加快这些设备上的渲染速度,但我认为您无法在这里做到这一点。您也许可以使用 iOS 6 中新增的帧缓冲区获取操作进行一些巧妙的操作来提高混合性能,但我不确定这是否会有帮助。

到目前为止,最大的性能提升将来自于尝试减少需要执行的绘图量。就我而言,我能够在球体冒名顶替者所在的位置后面绘制一系列不透明的正方形(最终迭代中的八边形),并使用深度缓冲区丢弃在任何条件下都永远不可见的像素。这导致性能提高了大约 6 倍。如果您的圈子的某些部分不透明,您也许可以像这样进行预通过。

考虑到这是一个画笔描边,在我看来,您应该能够进行更简单的优化,因为您只绘制帧与帧之间发生变化的任何内容。绘制的画笔图像的旧版本可以存储到平面纹理中,该纹理仅使用新的画笔描边进行绘制(并再次保存为存储的纹理)。您不需要为每个帧重新绘制所有画笔描边,这应该会显着减少渲染负载。

关于ios - iOS上的Accelerate框架可以用来画圆吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18884918/

相关文章:

iphone - NSUserdefaults 全局默认值

ios - 如何检测用户何时更改键盘?

ios - 实体和关系 : How to configure my tableview?

objective-c - OpenGL ES 1.1 顶点缓冲对象不工作

iphone - 应用程序在dispatch_release信号灯上崩溃了吗?

swift - GPUImage2 录制的视频上没有图像

ios - NSJSON 序列化失败

opengl - 在桌面上为 OpenGL ES 开发

android - 有没有办法检查 Android 设备是否支持 openGL ES 2.0?

ios - iOS Objective-C 中的自动白平衡