我正在尝试编译使用多行预处理器宏的WebGL2 300 es着色器,例如此玩具示例:
#define FOO() \
do { } while (false);
同样适用
#define FOO \
do { } while (false);
或
#define FOO() \
do { } while (false); \
这在最新版本的Chrome和Firefox上有效,但是当我致电gl.shaderSource
时,Safari返回以下错误:
WebGL: INVALID_VALUE: shaderSource: string not ASCII
我使用以下循环检查输入源字符串中是否有任何字符代码的值大于127:
for (char c = 0; c < src.length; c += 1) {
if (src.charCodeAt(c) > 127) {
console.error(src.charAt(c), src.charCodeAt(c));
}
}
循环不会打印任何错误。另外,在文本编辑器中启用不可见字符时,看不到任何多余的隐藏字符。
Safari的GLSL编译器是否完全无法处理反斜杠字符?
这里是一个最小的示例片段着色器,由于反斜杠而失败:
#version 300 es
precision highp float;
out vec4 fragColor;
#define FOO() \
true
void main() {
fragColor = vec4(1.0);
}
[Safari自2019年10月起不支持WebGL2。它只是桌面Safari上的一项实验性功能,甚至没有通过20%的WebGL2一致性测试。 See the source。搜索“ NOT IMPLEMENTED”,您将看到超过80个WebGL2 API函数未实现,仅仅是一个未完成多少工作的示例。
void WebGL2RenderingContext::uniform1ui(WebGLUniformLocation*, GC3Duint)
{
LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform1ui()");
}
void WebGL2RenderingContext::uniform2ui(WebGLUniformLocation*, GC3Duint, GC3Duint)
{
LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform2ui()");
}
void WebGL2RenderingContext::uniform3ui(WebGLUniformLocation*, GC3Duint, GC3Duint, GC3Duint)
{
LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform3ui()");
}
void WebGL2RenderingContext::uniform4ui(WebGLUniformLocation*, GC3Duint, GC3Duint, GC3Duint, GC3Duint)
{
LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform4ui()");
}
void WebGL2RenderingContext::uniform1uiv(WebGLUniformLocation*, Uint32List&&, GC3Duint, GC3Duint)
{
LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform1uiv()");
}
void WebGL2RenderingContext::uniform2uiv(WebGLUniformLocation*, Uint32List&&, GC3Duint, GC3Duint)
{
LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform2uiv()");
}
void WebGL2RenderingContext::uniform3uiv(WebGLUniformLocation*, Uint32List&&, GC3Duint, GC3Duint)
{
LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform3uiv()");
}
void WebGL2RenderingContext::uniform4uiv(WebGLUniformLocation*, Uint32List&&, GC3Duint, GC3Duint)
{
LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform4uiv()");
}
void WebGL2RenderingContext::uniformMatrix2x3fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint)
{
LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix2x3fv()");
}
void WebGL2RenderingContext::uniformMatrix3x2fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint)
{
LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix3x2fv()");
}
void WebGL2RenderingContext::uniformMatrix2x4fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint)
{
LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix2x4fv()");
}
void WebGL2RenderingContext::uniformMatrix4x2fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint)
{
LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix4x2fv()");
}
void WebGL2RenderingContext::uniformMatrix3x4fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint)
{
LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix3x4fv()");
}
void WebGL2RenderingContext::uniformMatrix4x3fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint)
{
LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix4x3fv()");
}
void WebGL2RenderingContext::vertexAttribI4i(GC3Duint, GC3Dint, GC3Dint, GC3Dint, GC3Dint)
{
LOG(WebGL, "[[ NOT IMPLEMENTED ]] vertexAttribI4i()");
}
void WebGL2RenderingContext::vertexAttribI4iv(GC3Duint, Int32List&&)
{
LOG(WebGL, "[[ NOT IMPLEMENTED ]] vertexAttribI4iv()");
}
void WebGL2RenderingContext::vertexAttribI4ui(GC3Duint, GC3Duint, GC3Duint, GC3Duint, GC3Duint)
{
LOG(WebGL, "[[ NOT IMPLEMENTED ]] vertexAttribI4ui()");
}
否则,在WebGL1中,它对我有用。在具有MacOS 10.14.6的2014 Macbook Pro和具有iOS 13.1的iPhoneX上进行了测试]
const fs = `
precision highp float;
#define FOO() \
true
void main() {
gl_FragColor = vec4(1.0);
}
`;
const gl = document.createElement('canvas').getContext('webgl');
const sh = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(sh, fs);
gl.compileShader(sh);
const success = gl.getShaderParameter(sh, gl.COMPILE_STATUS);
if (success) {
console.log('pass: shader compiled successfully');
} else {
console.error('fail: shader failed to compile');
}
建议您对> = 32和<= 127进行测试检查,或使用十六进制编辑器或十六进制转储查看您的文件。
关于#define
本身,JavaScript中#define
确实没有什么意义,因为JavaScript与C / C ++具有相当好的字符串操作不同。
const subs = {
width: 100,
height: 200,
}
const fs = `
void main() {
vec2 thingSize = vec2(${subs.width}, ${subs.height});
}
`;
console.log(fs);
甚至
function preprocess(s, subs) {
const re = new RegExp(Object.keys(subs).join('|'), 'g');
return s.replace(re, m => subs[m] || '');
}
const subs = { WIDTH: 123, HEIGHT: 456 };
const fs = preprocess(`
void main() {
vec2 thingSize = vec2(WIDTH, HEIGHT);
}
`, subs);
console.log(fs);
不是说您不应该使用#define
只是指出有很多简单的方法可以在JavaScript中操作字符串,因此GLSL预处理程序不像在C语言中那样有用(OpenGL是基于C的API)