警告:片段着色器未读取顶点着色器 'v_gradient' 的输出

WARNING: Output of vertex shader 'v_gradient' not read by fragment shader

当我 运行 我的应用程序在 ios 10 中使用 xcode 8 我在调试控制台中收到以下消息,并且 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

更新: 这个问题似乎已经在 Xcode9/iOS11.

上消失了

首先,冻结问题仅在 Xcode 8 运行 且仅在 iOS 10(目前是10.0.2),无论是调试还是发布模式。当应用程序通过 App Store 或第 3 方临时分发系统分发时,MKMapView 看起来不错。您看到的警告可能与问题有关,也可能无关,我不知道。

我发现有问题的代码在 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
}

回答

您可能会在 Xcode 中收到此警告的情况之一是使用使用着色器的应用程序,例如带有 [=10= 的 Maps 应用程序].您会发现地图视图在具有真实 hardware/native OS 的真实设备上按预期工作而没有警告。

在 sim 中,SolidRibbonShader 片段着色器 无法读取 v_gradient 顶点着色器 [=73] 的输出=] 可能是因为它处于测试阶段,或者 Xcode 版本和 SIM 版本之间可能不兼容。然而,着色器在真实设备上被识别。

说明

这些着色器属于 OpenGL 渲染管线。渲染管线是 OpenGL 在渲染对象时采取的一系列步骤。

渲染管道负责应用纹理、将顶点转换为正确的坐标系以及在屏幕上显示角色等。

此管道中有六个阶段。

  1. 逐顶点操作
  2. 原始组装
  3. 图元处理
  4. 光栅化
  5. 片段处理
  6. 每片段操作

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

什么是着色器?

着色器是您在 GPU 中开发的一个小程序。着色器是用一种称为 OpenGL 着色语言 (GLSL) 的特殊图形语言编写的。

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

Vertex Shader 的最终目标是提供网格顶点到渲染管线的最终转换。 Fragment shader 的目标是为指向帧缓冲区的每个像素提供着色和纹理数据。

Vertex shaders 将三角形的顶点从局部模型坐标系变换到屏幕位置。 Fragment shaders 计算屏幕上栅格化的三角形内像素的颜色。

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

许多 OpenGL ES 应用程序使用多个 vertexfragment 着色器,重用相同的 通常很有用具有不同 顶点着色器 的片段着色器,反之亦然。因为核心 OpenGL ES 规范要求 vertexfragment 着色器在单个着色器程序中 linked 在一起,混合和匹配着色器会导致大量程序,增加着色器编译总量和 link 初始化应用程序的时间。