将 emscripten 与 opengl 着色器一起使用
Using emscripten with opengl shaders
我无法让 emscripten 使用 openGL 着色器。该项目使用 emscripten 和 gcc 编译得很好,但是当我尝试 运行 emscripten 输出时失败。
我在编译顶点着色器时遇到的错误:
ERROR: 0:1: 'core' : invalid version directive
ERROR: 0:3: 'layout' : syntax error
编译片段着色器时出现的错误:
ERROR: 0:1: 'core' : invalid version directive
ERROR: 0:3: 'in' : storage qualifier supported in GLSL ES 3.00 only
ERROR: 0:3: '' : No precision specified for (float)
ERROR: 0:5: 'out' : storage qualifier supported in GLSL ES 3.00 only
ERROR: 0:5: '' : No precision specified for (float)
我正在使用以下命令编译这个项目:
em++ src/*.cpp -Iinclude/ -o test.html -std=c++11 -s USE_GLFW=3 -s FULL_ES3=1
顶点着色器源:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 in_color;
uniform mat4 model;
uniform mat4 projection;
out vec3 out_color;
void main()
{
gl_Position = projection * model * vec4(position, 1.0f);
out_color = in_color;
}
片段着色器源代码:
#version 330 core
in vec3 out_color;
out vec4 color;
void main()
{
color = vec4(out_color, 1.0);
}
着色器作为 char 数组从 xxd -i
提供的输出中加载 我正在 linux 上使用 c++11。该程序在我 运行 本机时工作得很好并且我已经尝试 运行 在 Firefox 和 Chromium 中使用 emscripten 输出。
好像是不同版本之间的问题。有没有办法让 emscripten 与我目前拥有的东西一起工作,或者我必须以不同的方式编写我的着色器?如果我必须重写我的着色器,我应该如何编写它们?
着色器代码必须是 WebGL 着色器代码才能在浏览器上运行。我认为 emscripten 不会将着色器代码(在本例中为 GLSL 3.3)转换为与 webGL 兼容的 GLSL ES 1.0。
您必须在顶点着色器中使用 attribute
而不是 in
,在 vertex/fragment 着色器中使用 varying
代替 out/in,并使用 gl_FragColor
作为片段着色器的输出变量。 layout
也不支持,变量需要精确定义。检查 WebGL 作弊 sheet here.
在当前的 emscripten 中,您可以使用 WebGL2 和 GLSL ES 3.00。您需要将 #version
行更改为
#version 300 es
您还需要为片段着色器添加默认精度。
如果是我,我会把我的代码包装成 glShaderSource
就像
GLint shaderSourceWrapper(GLint shader, const std::string src) {
#ifdef __EMSCRIPTEN__
// replace '#version.*' with '#version 300 es'
// if it's a fragment shader add 'precision highp float'
// do anything else relevant like warn if there are
// unsupported #extension directives
#endif
glShaderSource(shader, ... )
甚至 JavaScript 水平 like this
我无法让 emscripten 使用 openGL 着色器。该项目使用 emscripten 和 gcc 编译得很好,但是当我尝试 运行 emscripten 输出时失败。
我在编译顶点着色器时遇到的错误:
ERROR: 0:1: 'core' : invalid version directive
ERROR: 0:3: 'layout' : syntax error
编译片段着色器时出现的错误:
ERROR: 0:1: 'core' : invalid version directive
ERROR: 0:3: 'in' : storage qualifier supported in GLSL ES 3.00 only
ERROR: 0:3: '' : No precision specified for (float)
ERROR: 0:5: 'out' : storage qualifier supported in GLSL ES 3.00 only
ERROR: 0:5: '' : No precision specified for (float)
我正在使用以下命令编译这个项目:
em++ src/*.cpp -Iinclude/ -o test.html -std=c++11 -s USE_GLFW=3 -s FULL_ES3=1
顶点着色器源:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 in_color;
uniform mat4 model;
uniform mat4 projection;
out vec3 out_color;
void main()
{
gl_Position = projection * model * vec4(position, 1.0f);
out_color = in_color;
}
片段着色器源代码:
#version 330 core
in vec3 out_color;
out vec4 color;
void main()
{
color = vec4(out_color, 1.0);
}
着色器作为 char 数组从 xxd -i
提供的输出中加载 我正在 linux 上使用 c++11。该程序在我 运行 本机时工作得很好并且我已经尝试 运行 在 Firefox 和 Chromium 中使用 emscripten 输出。
好像是不同版本之间的问题。有没有办法让 emscripten 与我目前拥有的东西一起工作,或者我必须以不同的方式编写我的着色器?如果我必须重写我的着色器,我应该如何编写它们?
着色器代码必须是 WebGL 着色器代码才能在浏览器上运行。我认为 emscripten 不会将着色器代码(在本例中为 GLSL 3.3)转换为与 webGL 兼容的 GLSL ES 1.0。
您必须在顶点着色器中使用 attribute
而不是 in
,在 vertex/fragment 着色器中使用 varying
代替 out/in,并使用 gl_FragColor
作为片段着色器的输出变量。 layout
也不支持,变量需要精确定义。检查 WebGL 作弊 sheet here.
在当前的 emscripten 中,您可以使用 WebGL2 和 GLSL ES 3.00。您需要将 #version
行更改为
#version 300 es
您还需要为片段着色器添加默认精度。
如果是我,我会把我的代码包装成 glShaderSource
就像
GLint shaderSourceWrapper(GLint shader, const std::string src) {
#ifdef __EMSCRIPTEN__
// replace '#version.*' with '#version 300 es'
// if it's a fragment shader add 'precision highp float'
// do anything else relevant like warn if there are
// unsupported #extension directives
#endif
glShaderSource(shader, ... )
甚至 JavaScript 水平 like this