2

在诸如shadertoy 之类的 Web 工具中,我的片段着色器源包含在我无法控制或查看的 main() 中。如果我分发一些 GLSL 库,情况也是如此。

我的问题是确保 webGL2 和 1 之间的兼容性:如果浏览器或操作系统仅支持 WebGL1,我想编写 GLSL 后备来模拟缺少的内置 webGL2。-> 有没有办法从着色器测试当前的 webGL/GLSL 版本,就像我们为扩展的可用性所做的那样?

(顺便说一句,由于语言中包含了一些扩展,测试扩展变得越来越复杂:例如,尽管功能存在,但 GL_EXT_shader_texture_lod 在 webGL2 中未定义。因此能够测试 GLSL 版本至关重要。)

4

1 回答 1

2

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 替换变得复杂。例如这个库

于 2017-04-28T02:49:51.363 回答