GLSL着色器程序不在英特尔HD4000上运行

GLSL着色器程序不在英特尔HD4000上运行,glsl,Glsl,此着色器程序在Radeon 3450M、GT 550Ti、GT430和其他设备上正常工作,但在Intel HD4000上失败。有什么想法可能是错误的,或建议使着色器更英特尔友好 顶点着色器: uniform mat4 uniform_Projection; attribute vec4 attribute_Position; attribute vec4 attribute_Color; varying vec4 varying_Color; vec4 varying_Co

此着色器程序在Radeon 3450M、GT 550Ti、GT430和其他设备上正常工作,但在Intel HD4000上失败。有什么想法可能是错误的,或建议使着色器更英特尔友好

顶点着色器:

uniform mat4    uniform_Projection;
attribute vec4  attribute_Position;
attribute vec4  attribute_Color;
varying vec4    varying_Color;
vec4    varying_Color_Bak;

void main(void)
{
  varying_Color.x = clamp(abs((attribute_Position.x + 3.0f) / 5.0f), 0.1f, 1.0f);
  varying_Color.y = clamp(abs((attribute_Position.y + 3.0f) / 5.0f), 0.1f, 1.0f);
  varying_Color.z = 0.0f;//clamp(abs((attribute_Position.x + attribute_Position.y + 4.0f) / 7.0f), 0.1f, 1.0f);
  varying_Color.w = 0.9f;
  gl_Position = uniform_Projection * attribute_Position;
}
#version 120

uniform mat4    uniform_Projection;
attribute vec4  attribute_Position;
attribute vec4  attribute_Color;
varying vec4    varying_Color;

void main(void)
{
  varying_Color.x = clamp(abs((attribute_Position.x + 3.0) / 5.0), 0.1, 1.0);
  varying_Color.y = clamp(abs((attribute_Position.y + 3.0) / 5.0), 0.1, 1.0);
  varying_Color.z = 0.0;//clamp(abs((attribute_Position.x + attribute_Position.y + 4.0) / 7.0), 0.1, 1.0);
  varying_Color.w = 0.9;
  gl_Position = uniform_Projection * attribute_Position;
}
片段着色器:

uniform mat4    uniform_Projection;
varying   vec4    varying_Color;
vec4    varying_Color_Bak;
void main (void)
{
   varying_Color_Bak = varying_Color;
   varying_Color = uniform_Projection * varying_Color;
   for (int i = 0; i < 3; i++) {
      varying_Color = sin(varying_Color);
      varying_Color = inversesqrt(abs(varying_Color));
      varying_Color = abs(log(varying_Color));
   }
   varying_Color = clamp(varying_Color, 0.1f, 1.0f);
   varying_Color = mix(varying_Color, varying_Color_Bak, 0.9f);
   gl_FragColor = sin(varying_Color);
}
#version 120

uniform mat4    uniform_Projection;
varying   vec4    varying_Color;
void main (void)
{
   vec4 varying_Color_Bak;
   vec4 varying_Color_2;
   varying_Color_Bak = varying_Color;
   varying_Color_2 = uniform_Projection * varying_Color;
   for (int i = 0; i < 3; i++) {
      varying_Color_2 = sin(varying_Color_2);
      varying_Color_2 = inversesqrt(abs(varying_Color_2));
      varying_Color_2 = abs(log(varying_Color_2));
   }
   varying_Color_2 = clamp(varying_Color_2, 0.1, 1.0);
   varying_Color_2 = mix(varying_Color_2, varying_Color_Bak, 0.9);
   gl_FragColor = sin(varying_Color_2);
}
均匀mat4均匀_投影;
不同的颜色;
vec4可变颜色;
真空总管(真空)
{
改变颜色=改变颜色;
可变颜色=均匀投影*可变颜色;
对于(int i=0;i<3;i++){
变色=sin(变色);
变化颜色=反向QRT(abs(变化颜色));
可变颜色=abs(对数(可变颜色));
}
变色=钳形(变色,0.1f,1.0f);
变化颜色=混合(变化颜色,变化颜色,0.9f);
gl_FragColor=sin(不同颜色);
}

要使此功能可移植,您可以做的第一件事是将
#version 120
添加到着色器的顶部。如注释中所述,可选的
f
浮点精度后缀是GLSL 1.2的添加。在GLSL 1.1中,规范不包括此项,如果严格符合规范的编译器在GLSL 1.1着色器中遇到此问题,则会发出解析错误

这里的基本问题是,如果在着色器顶部不包含
#version
指令,则兼容的GLSL编译器假定假定着色器是根据GLSL 1.1规范编写的。许多编译器将放宽这些规则,您可以使用GLSL 1.1中不存在的语法,而无需发出警告,但其他编译器非常严格。如果没有办法提示GLSL编译器实现在其警告中更加详细,那么您必须在自己的时间内熟悉每个GLSL版本之间的差异。ANGLE项目提供了一个可移植的着色器验证器(大多数WebGL实现都使用它),但它针对的是OpenGL ES 2.0版本的GLSL,在这里对您没有帮助


着色器中的所有其他内容似乎对GLSL 1.1有效。这里的要点是,GLSL着色器顶部的
#version
指令比您想象的更重要。如果不读取
glGetShaderInfoLog(…)
glGetProgramInfoLog(…)
的输出,就很难诊断着色器问题-每个实现都有不同程度的详细性,但它们通常都会在编译/链接失败时产生一些有用的东西

要使此可移植,您可以做的第一件事是将
#version 120
添加到着色器的顶部。如注释中所述,可选的
f
浮点精度后缀是GLSL 1.2的添加。在GLSL 1.1中,规范不包括此项,如果严格符合规范的编译器在GLSL 1.1着色器中遇到此问题,则会发出解析错误

这里的基本问题是,如果在着色器顶部不包含
#version
指令,则兼容的GLSL编译器假定假定着色器是根据GLSL 1.1规范编写的。许多编译器将放宽这些规则,您可以使用GLSL 1.1中不存在的语法,而无需发出警告,但其他编译器非常严格。如果没有办法提示GLSL编译器实现在其警告中更加详细,那么您必须在自己的时间内熟悉每个GLSL版本之间的差异。ANGLE项目提供了一个可移植的着色器验证器(大多数WebGL实现都使用它),但它针对的是OpenGL ES 2.0版本的GLSL,在这里对您没有帮助


着色器中的所有其他内容似乎对GLSL 1.1有效。这里的要点是,GLSL着色器顶部的
#version
指令比您想象的更重要。如果不读取
glGetShaderInfoLog(…)
glGetProgramInfoLog(…)
的输出,就很难诊断着色器问题-每个实现都有不同程度的详细性,但它们通常都会在编译/链接失败时产生一些有用的东西

谢谢大家的建议。我花了一段时间才从测试人员那里得到反馈,但我最终在英特尔HD4000上运行了我的程序,而没有破坏其他平台上的程序

我几乎没有对顶点着色器进行任何更改:

uniform mat4    uniform_Projection;
attribute vec4  attribute_Position;
attribute vec4  attribute_Color;
varying vec4    varying_Color;
vec4    varying_Color_Bak;

void main(void)
{
  varying_Color.x = clamp(abs((attribute_Position.x + 3.0f) / 5.0f), 0.1f, 1.0f);
  varying_Color.y = clamp(abs((attribute_Position.y + 3.0f) / 5.0f), 0.1f, 1.0f);
  varying_Color.z = 0.0f;//clamp(abs((attribute_Position.x + attribute_Position.y + 4.0f) / 7.0f), 0.1f, 1.0f);
  varying_Color.w = 0.9f;
  gl_Position = uniform_Projection * attribute_Position;
}
#version 120

uniform mat4    uniform_Projection;
attribute vec4  attribute_Position;
attribute vec4  attribute_Color;
varying vec4    varying_Color;

void main(void)
{
  varying_Color.x = clamp(abs((attribute_Position.x + 3.0) / 5.0), 0.1, 1.0);
  varying_Color.y = clamp(abs((attribute_Position.y + 3.0) / 5.0), 0.1, 1.0);
  varying_Color.z = 0.0;//clamp(abs((attribute_Position.x + attribute_Position.y + 4.0) / 7.0), 0.1, 1.0);
  varying_Color.w = 0.9;
  gl_Position = uniform_Projection * attribute_Position;
}
我删除了“f”修饰符,添加了语言版本,并删除了一个未使用的变量声明

我对片段着色器进行了更多更改:

uniform mat4    uniform_Projection;
varying   vec4    varying_Color;
vec4    varying_Color_Bak;
void main (void)
{
   varying_Color_Bak = varying_Color;
   varying_Color = uniform_Projection * varying_Color;
   for (int i = 0; i < 3; i++) {
      varying_Color = sin(varying_Color);
      varying_Color = inversesqrt(abs(varying_Color));
      varying_Color = abs(log(varying_Color));
   }
   varying_Color = clamp(varying_Color, 0.1f, 1.0f);
   varying_Color = mix(varying_Color, varying_Color_Bak, 0.9f);
   gl_FragColor = sin(varying_Color);
}
#version 120

uniform mat4    uniform_Projection;
varying   vec4    varying_Color;
void main (void)
{
   vec4 varying_Color_Bak;
   vec4 varying_Color_2;
   varying_Color_Bak = varying_Color;
   varying_Color_2 = uniform_Projection * varying_Color;
   for (int i = 0; i < 3; i++) {
      varying_Color_2 = sin(varying_Color_2);
      varying_Color_2 = inversesqrt(abs(varying_Color_2));
      varying_Color_2 = abs(log(varying_Color_2));
   }
   varying_Color_2 = clamp(varying_Color_2, 0.1, 1.0);
   varying_Color_2 = mix(varying_Color_2, varying_Color_Bak, 0.9);
   gl_FragColor = sin(varying_Color_2);
}
#版本120
均匀mat4均匀_投影;
不同的颜色;
真空总管(真空)
{
vec4可变颜色;
vec4可变颜色;
改变颜色=改变颜色;
可变颜色=均匀投影*可变颜色;
对于(int i=0;i<3;i++){
改变颜色=sin(改变颜色);
变色法=反色法(abs(变色法);
可变颜色=abs(对数(可变颜色);
}
改变颜色=钳位(改变颜色2,0.1,1.0);
改变颜色=混合(改变颜色,改变颜色,0.9);
gl\u FragColor=sin(变化的颜色为2);
}
除了重复顶点着色器中的所有更改外,我还将
variable_Color
值复制到一个局部变量。这解决了HD4000上的错误,即Intel芯片不允许片段着色器修改不同的片段


我还发现,如果我在
main()
之外声明了我的局部变量(
variable\u Color\u bak
variable\u Color\u 2
),我的NVidia GT430在Linux上崩溃了。但是,在
main()。我花了一段时间才从测试人员那里得到反馈,但我最终在不破坏程序的情况下让程序在英特尔HD4000上运行