GLSL WebGL2错误多行宏Safari 12和ios12,WebGL:INVALID_VALUE:shaderSource:字符串非ASCII

问题描述 投票:0回答:1

我正在尝试编译使用多行预处理器宏的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);
}
compiler-errors macros glsl shader webgl2
1个回答
1
投票

[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)

© www.soinside.com 2019 - 2024. All rights reserved.