警告:顶点着色器'v_gradient'的输出没有被片段着色器读取
当我在ios 10中使用xcode 8运行我的应用程序时,我在debugging控制台中获得以下消息,并且通过UI冻结,任何人都可以知道为什么会发生这种情况
ERROR /BuildRoot/Library/Caches/com.apple.xbs/Sources/VectorKit/VectorKit-1228.30.7.17.9/GeoGL/GeoGL/GLCoreContext.cpp 1763: InfoLog SolidRibbonShader: ERROR /BuildRoot/Library/Caches/com.apple.xbs/Sources/VectorKit/VectorKit-1228.30.7.17.9/GeoGL/GeoGL/GLCoreContext.cpp 1764: WARNING: Output of vertex shader 'v_gradient' not read by fragment shader
回答
在Xcode中可能出现此警告的情况之一是使用着色器(如带有MKMapView
的地图应用程序)的应用程序。 你会发现地图视图按预期的方式工作,没有真正的硬件/本地操作系统的真实设备上的警告。
在SIM卡中, SolidRibbonShader
片段着色器无法读取v_gradient
顶点着色器的输出,因为它是有问题的beta或Xcode的发行版本。 但是着色器是在真实设备上识别的。
说明
这些着色器属于OpenGL渲染pipe线 。 渲染pipe线是OpenGL在渲染对象时需要执行的一系列步骤。
渲染pipe道负责处理纹理,将顶点转换到正确的坐标系,并在屏幕上显示字符等。
这个pipe道有六个阶段。
- 每顶点操作
- 原始大会
- 原始处理
- 光栅化
- 片段处理
- 按碎片操作
最后,您的设备屏幕上会显示一个图像。 这六个阶段被称为OpenGL渲染pipe道 ,所有用于渲染的数据都必须经过它。
什么是着色器?
着色器是您生活在GPU中的一个小程序。 着色器是用称为OpenGL着色语言(GLSL)的特殊graphics语言编写的 。
着色器代替了OpenGL渲染pipe线中的两个重要阶段: 每个顶点处理和每个片段处理阶段。 这两个阶段都有一个着色器。
Vertex Shader
的最终目标是提供网格顶点到渲染pipe道的最终转换。 Fragment shader
的目标是向每个像素提供着色和纹理数据到帧缓冲区。
Vertex shaders
将三angular形的顶点从局部模型坐标系变换到屏幕位置。 Fragment shaders
计算在屏幕上栅格化的三angular形内像素的颜色。
独立的着色器对象加速编译和链接
许多OpenGL ES应用程序使用多个顶点着色器和片段着色器,并且在不同的顶点着色 器中重复使用相同的片段着色器是相当有用的,反之亦然。 由于核心OpenGL ES规范要求在单个着色器程序中将顶点和片段着色器链接在一起,因此混合和匹配着色器会产生大量程序,从而增加了在初始化应用程序时总的着色器编译和链接时间。
更新:这个问题似乎已经消失在Xcode9 / iOS11上。
首先,冻结问题只发生在从Xcode 8运行并且仅在iOS 10 (当前为10.0.2)上运行,无论是在debugging模式还是释放模式。 当应用程序通过App Store或第三方专用分发系统分发时,MKMapView似乎很好。 您所看到的警告可能与问题有关,也可能与问题无关,我不知道。
我发现的是,有问题的代码是在MKMapView的析构函数中,不pipe你用map view对象做什么或者如何configuration它,
[MKMapView new];
代码中的任何地方都会冻结应用程序。 主线程挂在一个信号上,不清楚为什么。
我尝试过的一件事是在一个单独的线程中销毁地图视图对象,但这并没有帮助。 最终我决定保留我的地图对象,至less在DEBUG的构build。
注意 :这是一个真正的解决方法,但至less可以帮助您在不冻结的情况下debugging您的应用程序。 保留这些对象意味着每次使用地图创build视图控制器时,内存使用量将增加约45-50MB。
所以,假设你有一个属性mapView
,那么你可以在你的视图控制器的dealloc中做到这一点:
- (void)dealloc { #if DEBUG // Xcode8/iOS10 MKMapView bug workaround static NSMutableArray* unusedObjects; if (!unusedObjects) unusedObjects = [NSMutableArray new]; [unusedObjects addObject:_mapView]; #endif }