AFAICT没有很好的测试方法。规范说预处理器宏__VERSION__
将设置300
为 GLSL 版本 3.00 的整数版本,所以
#if __VERSION__ == 300
// use 300 es stuff
#else
// use 100 es tuff
#endif
问题在于 WebGL2 在使用 300 es 着色器时,着色器的第一行必须是
#version 300 es
所以你不能这样做
#if IMAGINARY_WEBGL2_FLAG
#version 300 es // BAD!! This has to be the first line
...
#else
...
#
因此,鉴于您已经必须更新第一行,为什么不只使用 2 个着色器,一个用于 WebGL1,另一个用于 WebGL2。否则,所有主要引擎都会生成它们的着色器,因此如果您想沿着这条路走下去,在您的代码中生成 WebGL1 或 WebGL2 应该是非常简单的。
首先,没有理由使用 WebGL2 着色器功能,如果您可以使用 WebGl1,并且如果您正在使用 WebGL2 功能,那么它们就不再是同一个着色器了,是吗?他们需要不同的设置、不同的输入等……
假设我们可以在 GLSL 中完成这一切,您希望它看起来像什么?
// IMAGINARY WHAT IF EXAMPLE ....
#if WEBGL2
#version 300 es
#define texture2D texture
#define textureCube texture
#else
#define in varying
#define out varying
#endif
in vec4 position;
in vec2 texcoord;
out vec2 v_texcoord;
uniform sampler2D u_tex;
uniform mat4 u_matrix;
void main() {
gl_Position = u_matrix * (position + texture2D(u_tex, texcoord));
v_texcoord = texcoord;
}
假设您想这样做。你可以用 JavaScript 做(不建议这样,只是展示一个例子)
const webgl2Header = `#version 300 es
#define texture2D texture
#define textureCube texture
`;
const webglHeader = `
#define in varying
#define out varying
`;
function prepShader(gl, source) {
const isWebGL2 = gl.texImage3D !== undefined
const header = isWebGL2 ? webgl2Header : webglHeader;
return header + source;
}
const vs = `
in vec4 position;
in vec2 texcoord;
out vec2 v_texcoord;
uniform sampler2D u_tex;
uniform mat4 u_matrix;
void main() {
gl_Position = u_matrix * (position + texture2D(u_tex, texcoord));
v_texcoord = texcoord;
}
`;
const vsSrc = prepSource(gl, vs);
您可以根据需要使 JavaScript 替换变得复杂。例如这个库