GLSL-ES3(webGL2):如何测试来自片段着色器的扩展



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

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

CCD_ 3特别是影响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
...
`);

等等。。。

此外,由于即使在OpenGL中也从来没有GL_EXT_color_buffer_float,因此调用宏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...

最新更新