此着色器程序在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;
}
片段着色器:
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);
}
答案 0 :(得分:3)
您可以做的第一件事就是将#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 (...)
的输出,则很难诊断着色器问题 - 每个实现都有不同程度的详细程度,但它们通常都会产生 某些 在编译/链接失败时很有用;)
答案 1 :(得分:2)
感谢大家的建议。我需要一段时间才能从我的测试人员那里获得反馈,但最终我的程序在Intel HD4000上运行而没有在其他平台上破坏程序。
我几乎没有对顶点着色器进行任何更改:
#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'修饰符,添加了语言版本,并删除了一个未使用的变量声明。
我对片段着色器进行了更多更改:
#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);
}
除了重复顶点着色器的所有更改外,我还将varying_Color
值复制到局部变量。这解决了HD4000上的错误,即英特尔芯片不允许片段着色器修改变化。
我还发现,如果我在varying_Color_bak
之外声明了我的局部变量(varying_Color_2
和main()
),我在我的NVidia GT430上崩溃了。但是一切似乎都在main()
内声明的局部变量稳定运行。