GLSL 着色器在集成 GPU 上编译,但不在专用 GPU 上编译

问题描述 投票:0回答:1

我正在开发一个使用 OpenGL 3.3 和 GLSL 330 的程序。着色器在使用集成 GPU 时进行编译,但在使用专用 GPU (Nvidia RTX 2060) 时则无法编译。

我收到以下错误消息:

ERROR::SHADER::VERTEX::COMPILATION_FAILED 0(21) : error C7549: OpenGL does not allow C style initializers

ERROR::SHADER::FRAGMENT::COMPILATION_FAILED 0(13) : error C7549: OpenGL does not allow C style initializers

ERROR::SHADER::PROGRAM::LINKING_FAILED

0(21) : error C7549: OpenGL does not allow C style initializers (0) : error C2003: incompatible options for link

0(13) : error C7549: OpenGL does not allow C style initializers (0) : error C2003: incompatible options for link

顶点着色器:

// vertex
#version 330 core
layout (location = 0) in int data;

out vec2 TexCoord;
out vec3 Normal;
out vec3 FragPos;
flat out int FaceId;
out vec3 col;

uniform mat4 transform;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;


float textureScale = 1.0f / 16.0f;
vec2 texCoordArr[] = {vec2(0.0f, 0.0f),vec2(textureScale, 0.0f),vec2(textureScale, textureScale),vec2(0.0f,textureScale)};

void main()
{
    
    int xPos = (data >> 27) & 31;
    int yPos = (data >> 22) & 31;
    int zPos = (data >> 17) & 31;
    int vertId = (data >> 15) & 3;
    int faceId = (data >> 12) & 7;
    int texId = (data >> 4) & 255;

    vec2 texBase = vec2(texId % 16 * textureScale, texId / 16 * textureScale);

    vec3 aPos = vec3(xPos * 1.0f, yPos * 1.0f, zPos * 1.0f);

    gl_Position = projection * view * model * vec4(aPos, 1.0);
    TexCoord = texBase + texCoordArr[vertId];
    FragPos = vec3(model * vec4(aPos,1.0f));

    FaceId = faceId;
}   

片段着色器:

// fragment
#version 330 core
out vec4 FragColor;

in vec2 TexCoord;
in vec3 FragPos;
flat in int FaceId;
in vec3 col;
uniform sampler2D ourTexture;

uniform vec3 ambientColor;


float faceBrightness[] = {1.0f,0.5f,0.9f,0.6f,0.7f,0.7f};

void main()
{
    vec4 result = (texture(ourTexture, TexCoord));
    result = vec4(result.xyz * ambientColor * faceBrightness[FaceId], result.w);
    result *= faceBrightness[FaceId];
    FragColor = result;
}

我已尝试更新 Nvidia 驱动程序,但这并没有解决问题。

glsl shader
1个回答
0
投票

问题

问题源于这些行,分别来自顶点着色器和片段着色器,

vec2 texCoordArr[] = {vec2(0.0f, 0.0f),vec2(textureScale, 0.0f),vec2(textureScale, textureScale),vec2(0.0f,textureScale)};
float faceBrightness[] = {1.0f,0.5f,0.9f,0.6f,0.7f,0.7f};

并且与错误所示完全相同:“OpenGL 不允许 C 样式初始值设定项”。特别是对于这种情况,GLSL 330不允许这样做。链接错误(自然)是顶点着色器或片段着色器未编译的结果。

解决方案

数组应该使用数组构造函数初始化:

vec2 texCoordArr[] = vec2[](vec2(0.0f, 0.0f), vec2(textureScale, 0.0f), vec2(textureScale, textureScale), vec2(0.0f,textureScale));
float faceBrightness[] = float[](1.0f,0.5f,0.9f,0.6f,0.7f,0.7f); 

或者,您可以切换到 GLSL >=420(核心或兼容性),它支持 初始化列表,并允许您使用问题中的大括号语法。

您可以采取以下措施来避免此类问题:

  1. 严格遵守规范。
  2. 使用最新的驱动程序(你就是这么做的!)。
  3. 使用 OpenGL / OpenGL ES 参考编译器 Glslang 验证您的着色器源,与某些 OpenGL 实现不同,它的目标是严格遵循规范。其源代码可以在这里找到。
  4. 尝试在不同的 GPU 上编译着色器,因为某些实现比规范“更严格”。
  5. 有关数组初始化的完整详细信息,请参阅 GLSL 规范(
GLSL 330

GLSL 420)。 为什么着色器编译在集成GPU上

由于某种原因,集成GPU驱动程序提供的OpenGL实现偏离(“不符合”)规范。至于为什么,我们只能猜测。也许它无意中支持了“不正确的”GLSL 版本的初始值设定项列表,或者它支持 C 样式初始值设定项以试图适应程序员? 无论如何,这些偏差在实践中都会发生,除了提交错误报告之外,程序员/用户无能为力。

就个人而言,我认为过于严格的偏差和过于宽松的偏差都是不可取的,因为两者都会使编写可移植代码变得更加困难。

© www.soinside.com 2019 - 2024. All rights reserved.