警告:顶点着色器“v_gradient”的输出未被片段着色器读取。

47

当我在使用Xcode 8运行我的应用程序在iOS 10上时,我会在调试控制台中看到以下信息,并且UI会冻结,有人知道为什么会发生这种情况吗?

当我在 iOS 10 使用 Xcode 8 运行我的 App 时,在调试控制台中会出现以下信息,同时 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

我也遇到了这个问题。 - Kevin
2
@noellee 你的应用程序中使用了地图视图吗? - Vaisakh
1
@AndreyM。是的,我也在使用MKMapView。 - Vaisakh
我也在使用MKMapView,并且遇到了这个错误。 - Emre
1
我的应用程序只在调试模式下冻结,否则一切正常,但仍然收到此警告。 - Vaisakh
显示剩余3条评论
2个回答

52

答案

Xcode中可能出现此警告的情况之一是在使用使用着色器的应用程序(例如带有MKMapViewMaps应用程序)时。您会发现,在具有真实硬件/本机操作系统的真实设备上,地图视图可以正常工作而不会出现该警告。

在模拟器中,SolidRibbonShader 片段着色器 无法读取 v_gradient 顶点着色器 的输出,可能是因为它处于测试版,或者Xcode版本和SIM版本之间存在不兼容性。但是这些着色器在真实设备上被识别。

说明

这些着色器属于OpenGL渲染管道。渲染管道是OpenGL渲染对象时采取的步骤序列。

渲染管道负责诸如应用纹理、将顶点转换为正确的坐标系并在屏幕上显示字符等事项。

这个管道有六个阶段。

  1. 每个顶点操作
  2. 基元装配
  3. 基元处理
  4. 光栅化
  5. 片段处理
  6. 每个片段操作

最后,在设备的屏幕上出现了一张图像。这六个阶段被称为OpenGL渲染管道,所有用于渲染的数据都必须经过它。

什么是着色器?

着色器是您开发的在GPU中运行的小程序。 着色器是使用特殊的图形语言OpenGL着色语言(GLSL)编写的。

一个着色器取代了OpenGL渲染管道中两个重要的阶段: 每个顶点处理每个片段处理 阶段。 这两个阶段各有一个着色器。

顶点着色器(Vertex Shader)的最终目的是将网格顶点进行最后的转换,以便进入渲染管线。而片段着色器(Fragment Shader)则提供颜色和纹理数据给即将传输到帧缓冲区的每个像素。

顶点着色器将三角形的顶点从本地模型坐标系转换为屏幕位置。片段着色器计算在屏幕上光栅化的三角形中每个像素的颜色。

单独的着色器对象可增加编译和链接速度

许多OpenGL ES应用程序使用多个顶点和片段着色器,有时重复使用同一片段着色器,配合不同的顶点着色器或者反之亦然,但由于核心OpenGL ES规范要求一个顶点和片段着色器必须连接在一个着色器程序中,混合和匹配会导致大量的程序生成,增加了初始化应用程序时的总着色器编译和链接时间。


3
是的,但我们能做些什么呢?等待苹果来调试吗? - Xero
1
答案是警告信息的正确原因。堆栈答案有时是代码解决方案,或仅仅是 Xcode 或 iOS 问题的答案。这个答案是正确的解释,并且还说着色器在实际设备上会加载正常,所以这也是一个解决方案。 - TokyoToo
与我的经验相符:模拟器上的问题,而不是设备上的问题。 - Ron Diel
7
回答不错,但我在我的真机上遇到了这个问题(iPhone 5C,iOS 10.2,但在早期版本和XCode 8.2上也出现过)。我构建了我的应用并在iPhone上运行它 - 在控制台中出现了与问题相同的错误(使用不同的VectorKit版本)。 - franiis
2
我在我的设备上(iPhone 5,iOS 10.3.2和Xcode 8.3.3)遇到了同样的问题,但在我的其他设备上(iPhone 6,iOS 10.3.2和iPhone 4s,9.3.5)没有这个问题。我猜这是iPhone 5的问题。 - MMSousa

3

更新: 问题现在似乎已经在Xcode9/iOS11上解决了。


首先,这个冻结问题只会在从Xcode 8运行并且只在iOS 10(目前是10.0.2)上发生,无论是在调试模式还是发布模式下。虽然MKMapView在通过App Store或第三方Ad hoc分发系统分发应用程序时似乎没有问题,但这个问题仍然存在。你看到的警告可能与问题有关,也可能与问题无关,我不确定。

我所发现的问题是MKMapView的析构函数中存在问题,无论你如何处理地图视图对象或配置它,比如仅仅调用

[MKMapView new];

在代码中的任何地方都会导致应用程序冻结。 主线程在信号量上挂起,原因不明。

我尝试过的其中一件事情是在单独的线程中销毁地图视图对象,但这并没有帮助。 最终,我决定在DEBUG构建中至少保留我的地图对象。

注意:这是一个非常差的解决方法,但至少它可以帮助您在不冻结的情况下调试应用程序。 保留这些对象意味着每次创建具有地图的视图控制器时,您的内存使用量将增加大约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
}

我也刚注意到这个问题。你有没有开一个雷达? - allocate
这个和我的问题可能有关啊... http://stackoverflow.com/questions/41869703/app-freezes-on-main-thread-on-iphone-5c-but-not-on-iphone-6s/41874600?noredirect=1#comment70959393_41874600 - Mikael
1
有人报告了吗?我也遇到了同样的问题。 - Mikael
2
这个问题在iOS 10.3.3上仍然存在,有人已经报告了吗? - jjv360
对我来说,只有在调试器(Xcode)附加时运行应用程序时才会挂起,因此我使用 if(AmIBeingDebugged()) 代替 #if DEBUG - Pang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接