将 emscripten 与 opengl 着色器一起使用

Posted

技术标签:

【中文标题】将 emscripten 与 opengl 着色器一起使用【英文标题】:Using emscripten with opengl shaders 【发布时间】:2015-07-09 20:26:27 【问题描述】:

我无法让 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);

着色器作为字符数组从xxd -i 提供的输出中加载,我在 linux 上使用 c++11 工作。该程序在我本地运行时运行良好,并且我尝试在 Firefox 和 chromium 中运行 emscripten 输出。

似乎是不同版本之间的问题。有没有办法让 emscripten 使用我目前拥有的东西,或者我必须以不同的方式编写我的着色器?如果我必须重写我的着色器,我应该如何编写它们?

【问题讨论】:

尝试从#version 中删除core;无论如何,它是默认值。 我删除了core,它消除了有关核心的错误,但其余错误仍然存​​在。 【参考方案1】:

着色器代码必须是 WebGL 着色器代码才能在浏览器上运行。我认为 emscripten 不会将着色器代码(在这种情况下为 GLSL 3.3)转换为与 webGL 兼容的 GLSL ES 1.0。

您必须在顶点着色器中使用attribute 而不是in,在顶点/片段着色器中使用varying 用于输出/输入,并使用gl_FragColor 作为片段着色器的输出变量。 layout 也不支持,变量需要精确定义。查看 WebGL 备忘单here。

【讨论】:

【参考方案2】:

在当前的 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 着色器一起使用的主要内容,如果未能解决你的问题,请参考以下文章

如何将 QPainter 和 OpenGL 与着色器与 Qt5.9 并行使用

无法让 openGL 的 glDrawElements 与几何着色器一起使用

为啥我在 emscripten 使用“#version 300 es”得到“不支持的着色器版本”?

跨多个着色器的 OpenGL 统一

OpenGL:为啥我不能将单个浮点数从顶点着色器传递到片段着色器?

OpenGL着色器没有将变量从顶点传递到片段着色器