0

在 webGL1 中,可以使用(例如)从片段着色器测试 GLSL 扩展的可用性#ifdef GL_EXT_shader_texture_lod。它似乎不再在 webGL2 (=GLSL-ES3.0) 中工作:扩展不一样,但例如#ifdef GL_EXT_color_buffer_float似乎是错误的,尽管https://webglreport.com/?v=2告诉扩展存在。或者我做错了什么?

4

1 回答 1

0

是否向 GLSL 添加标志取决于扩展

EXT_shader_texture_lod是专门影响 GLSL 的扩展。它的规范说它添加了那个宏

GLSL 宏 GL_EXT_shader_texture_lod 定义为 1。

EXT_color_buffer_float不是影响 GLSL 的扩展。它的规范没有提到任何 GLSL 宏。与 WebGL1 没有变化

无论如何,这些标志在 WebGL 中大多是无稽之谈。您可以轻松地进行自己的字符串操作

const shaderTextureLodExt = gl.getExtension('EXT_shader_texture_lod');


const shader = `
#if ${shaderTextureLodExt ? 1 : 0}
   ... code if shader texture lod exists
#else
   ... code if shader texture lod does not exist
#endif

  ...
`;

或者一千种其他方法来操纵着色器字符串。

这是另一个

const colorBufferFloatExt = gl.getExtension('EXT_color_buffer_float');

function replaceIfDefs(s) {
  return `
  ${colorBufferExtension ? '#define EXTENSION_color_buffer_float' : ''}
  ${s.replace(/GL_EXT_color_buffer_float/g 'EXTENSION_color_buffer_float')}
  `;
}
const shader = replaceIfDefs(`
#ifdef GL_EXT_color_buffer_float
   ...
#endif
   ...
`);

ETC...

此外,由于在 OpenGL 中从来没有一个GL_EXT_color_buffer_floateven ,所以调用宏没有多大意义GL_EXT_color_buffer_float。事实上,这可以说是一个坏主意,因为它最终看起来像一个官方指定的宏,即使它不是。最好选择不以 . 开头的自己的名字GL_

还要考虑使用#ifdef可能甚至不是一个好主意,因为您可以只使用字符串操作。例如

const colorBufferFloatExt = gl.getExtension('EXT_color_buffer_float');

const snippet = colorBufferFloatExt
  ? `
      float decode_float(vec4 v) {
        return v;
      }
    `
  : `
      float decode_float(vec4 v) {
         vec4 bits = v * 255.0;
         float sign = mix(-1.0, 1.0, step(bits[3], 128.0));
         float expo = floor(mod(bits[3] + 0.1, 128.0)) * 2.0 +
                      floor((bits[2] + 0.1) / 128.0) - 127.0;
         float sig = bits[0] +
                     bits[1] * 256.0 +
                     floor(mod(bits[2] + 0.1, 128.0)) * 256.0 * 256.0;
         return sign * (1.0 + sig / 8388607.0) * pow(2.0, expo);
       }
   `;

const shader = `
precision highp float;

${snippet}

uniform sampler2D data;
uniform vec2 dataSize;

void main(
   vec4 d = texture2D(data, gl_FragCoord.xy / dataSize);
   vec4 v = decode_float(d) * 2.0;
   gl_FragColor = v;
}
`;


...etc...
于 2020-09-24T15:47:21.203 回答