Using emscripten with opengl shaders

I'm having trouble getting the emscripten to work with openGL shaders. The project compiles just fine with emscripten and gcc, but doesn't work when I try to run the emscripten output.

Errors I get from compiling the vertex shader:

ERROR: 0:1: 'core' : invalid version directive 
ERROR: 0:3: 'layout' : syntax error 

      

Errors I get from compiling the fragment shader:

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) 

      

I am compiling this project using the command:

em++ src/*.cpp -Iinclude/ -o test.html -std=c++11 -s USE_GLFW=3 -s FULL_ES3=1

      

Vertex shader source:

#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;
}

      

Fragment shader source:

#version 330 core

in vec3 out_color;

out vec4 color;

void main()
{
      color = vec4(out_color, 1.0);
}

      

Shaders are loaded as char arrays from the output provided xxd -i

I am working in C ++ 11 on linux. The program works fine when I run it natively and I tried to run the emscripten output in both Firefox and Chrome.

Seems to be a problem between different versions. Is there a way to make emscripten work with what I have now, or do I need to write my shaders differently? And if I have to rewrite my shaders, how do I write them?

+3


source to share


2 answers


The shader code must be WebGL shader code to work in a browser. I don't think emscripten converts the shader code (GLSL 3.3 in this case) to GLSL ES 1.0, which is webGL compatible.



You will need to use attribute

instead in

in the vertex shader, varying

for out / in in the vertex / fragment shaders, and use gl_FragColor

as the output variable of the fragment shader. layout

is also not supported, and variables require precise definition. Check out the WebGL cheat page here .

+5


source


In current emscripten, you can use WebGL2 and GLSL ES 3.00. You need to change the lines #version

to

#version 300 es

      

You also need to add the default precision to your fragment shaders.



If it were me, I would just bind my code to glShaderSource

, to be something like

GLint shaderSourceWrapper(GLint shader, const std::string src) {
  #ifdef __EMSCRIPTEN__
    // replace '#version.*' with '#version 300 es' 
    // if it a fragment shader add 'precision highp float'
    // do anything else relevant like warn if there are
    // unsupported #extension directives
  #endif
  glShaderSource(shader, ... )

      

Or even do it in JavaScript level like this

0


source







All Articles