I'm trying to follow some examples from shadertoy. I'm using GlslCanvas library from the author of "The Book of Shaders" that I read before but apparently shadertoy uses a bit different setup for webgl. Incompatible uniform variable names aside, I think shadertoy somehow manages to setup WebGL 2 - judging on the use of the following:
dFdx
, dFdy
functions. Shadertoy examples use this without #version
directive in the shader file, at least I'm not seeing shader authors specifying it for them.#extension GL_OES_standard_derivatives : enable
in my webgl setupGlslCanvas
(literally an html importing GlslCanvas
library + a webgl canvas element just as README suggests) I can only use texture2D
while shadertoy examples use just texture
and some more advanced functions like textureGrad
.Judging on the above I think the simple answer is that shadertoy is using WebGL 2 while the library that I use somehow falls back to using WebGL 1 even though the browser is perfectly capable of using Web GL 2
.
However when I tried using #version 300 es
I still got an error. I wonder what is unusual in shadertoy setup?
Is there some magic I can use to enable Web GL 2 for my setup?
I tried reading unpacked library sources but didn't find a solution - the source code suggests that GlslCanvas
resorts to some tricks when reading fragment shader source and using #version
won't work - e.g. lines around this.fragmentString = "#define PLATFORM_WEBGL\n#line 0\n";
.
You're right: Shadertoy uses WebGL 2, and GLSL ES 300 shaders. The reason you don't have to declare #version 300 es
is that Shadertoy does this for you in the background.
On the other hand, when GlslCanvas creates the WebGL context in the create3DContext
function, it always creates a WebGL 1 context, even if your device and browser support WebGL 2. So by default, you can't use GLSL ES 300 shaders with GlslCanvas.
There are multiple solutions for the problem: you can modify GlslCanvas to support WebGL 2, you can use another library that supports WebGL 2, you can use plain WebGL 2, or you can (probably) rewrite the shader from GLSL ES 300 to GLSL ES 100.
Probably the best idea is to create a couple of macros and make your shader compatible with both shader versions. Something like this:
#if __VERSION__ == 300
#define attribute in
#define texture2D texture
// etc.
#else
#define attribute attribute
#define texture2D texture2D
// etc.
#endif