跨平台图形程序使用以 GLSL 1.40 版编写的着色器。
GLSL 1.40 的特性完全满足了应用的需求。事实上,基本的着色器是用来绘制纹理的:
顶点着色器:
attribute vec2 position;
attribute vec2 textureCoordinates;
uniform mat3 transformationProjectionMatrix;
varying vec2 interpolatedTextureCoordinates;
void main() {
interpolatedTextureCoordinates = textureCoordinates;
gl_Position.xywz = vec4(transformationProjectionMatrix * vec3(position, 1.0), 0.0);
}
片段着色器:
precision mediump float;
uniform vec4 color;
uniform sampler2D textureData;
varying vec2 interpolatedTextureCoordinates;
void main() {
gl_FragColor.rgba = color * texture(textureData, interpolatedTextureCoordinates).bgra;
}
在程序中为不同版本的 GLSL 设置多个着色器是否有意义,这些着色器将根据特定硬件的支持进行选择?
使用更现代版本的着色器语言时是否可以获得加速?
不,如果您不使用更新版本中提供的任何优化功能,实际性能将几乎相同。
通常,为不同版本的 GLSL 复制着色器不会带来额外的好处(此外,您不应在一个着色器程序中混合不同版本的 GLSL)。因此,使用图形引擎支持的最小版本的 GLSL是有意义的,并且仅在必要时应用更新的版本。
同样,为不同的 GLSL 版本复制着色器也没有多大意义,因为可以通过一些额外的调整/宏为不同的 GLSL 版本编译相同的着色器源代码,因为 GLSL 保留了向后兼容性(在 GLSL 150 / OpenGL 3.2 中发生的唯一重大语法变化,这也丢弃了很多已弃用的功能)。
但是,OpenGL 驱动程序中存在可能改变这种情况的错误。例如,在实践中,当在
#version 300 es
支持 OpenGL ES 3.0 的设备上编译时,相同的 GLSL 程序无法运行,并且成功地与#version 100 es
.此外,使用特定版本中未正式支持的新 GLSL 功能也可能会出错。GLSL 规范是一个相当复杂的东西,你可以花很多时间作为一个书虫来确定哪个版本添加了这个或那个特性。请注意,许多驱动程序允许使用某些新功能而无需指定适当的 GLSL 版本(硬件允许),并且您可能会认为您的程序符合 GLSL,例如
#version 140
实际上不符合 GLSL,这可能在测试不同的驱动程序时发现opengl.根据我的经验,NVIDIA 驱动程序允许与 GLSL 规范有很大的偏差(可能是因为 NVIDIA GLSL 编译器将代码翻译成另一种语言 - Cg)。AMD 驱动程序更严格,但也允许一些偏差。到目前为止,我见过的最严格的 GLSL 验证器是在 macOS OpenGL 驱动程序中。在这种情况下,指定更高版本的 GLSL 可能会更安全、更可靠,以便与更广泛的硬件兼容,尽管它只会隐藏在确定支持的最低 GLSL 版本时出现的错误。
翻译自 SO