WebGL 2.0 vs WebGL 1.0

on February,15 2017, Shadertoy moved to WebGL 2.0. What does it change ?

NB: WebGL 2.0 corresponds to OpenGL ES 3.0 , which is derived from OpenGL 3.3 and 4.2 , minus some features.  Cf specs or quick card, or cheesy slides.  Test availability on your browser, and among users.

What new does it bring to Shadertoy ?

New features, … and new constraints.
And new compatibility issues: see last section there.

New features:

  • Arrays:  (still 1D only )                                example
    • dynamic indexing                              A[k]
    • initialization                                        float[] A = float[] ( 17., 23.4, 56.3, 0., 7. );
    • implicit sizing                                      size = A.length();              \       or float A[]
    • a function can return an array.      float[5] foo() { }
      A reminder that there is very little memory per thread: don’t abuse of arrays !
  • All int operations:                                      examples  1 ,
    • bits and logic: & , | , ^ , >> , << ,  &= , |= , ^= , >>= , <<=
    • unsigneds:   uint, uvec, 1234U, 0x3f800000U  ( but 0b010101 is still missing )
    • % (i.e., mod) , %= , abs()
  • Flow control:
    • while(){},  do{}while(),
      switch(int){case:default:}     Some bugs on Windows. 😦 Avoid return inside.
    • Loops bounds no longer need to be constant.
      (attention: const loops might still be inlined if the compiler thinks it optimizes… even if this cause compiling timeout or too long shader.
      Hack bound if you want to forbid inlining: 100+1e-30*iMouse.x ).
    • Functions can still not be recursive (they are still inlined, since there is no stack on GPU. Or manage one yourself with arrays if you really need. example ).
  • Formatting:
    • defines can be multiline !       continuation to next line mark:   \
      Not compiling on firefox for now 😦  [apparently now fixed]
    • UTF8 allowed (really everywhere ? possible issues on the right of #define )
    • more float check at compilation time.        example
  • New matrix and vector operations and types:
    • mat inverse(), determinant(),  transpose()
    • mat2x2 mat2x3 mat2x4 mat3x2 mat3x3 mat3x4 mat4x2 mat4x3 mat4x4
    • outerProduct()
    • cross(vec2) is still missing. Worse: you can no longer overload it.
  • New math operators:
    • hyperbolic funcs: sinh, cosh, tanh, asinh, acosh, atanh
    • trunc(), round(), roundEven(),  f=modf(v,i), isnan(), isinf()
    • [un]pack[S|U]norm2x16() , [un]packHalf2x16() :  pack vec2 in uint and back
      [U]intBitsToFloat and back: convert to int comprising special floats (NaN, Inf…)
    • be careful: you can no longer overload (e.g. defining min(struct,struct) ).
  • New textures operations:
    • sampler: 2D or 3D
    • textureLod() ( previously an EXT )   the one to use to control MIPmap level 
    • textureGrad()  (previously an EXT)  the one to use if you have dFdX,dFdY
    • texture*Offset()
    • texelFetch()                   avoid any interpolation, e.g., to use a texture as an array
    • textureSize()                 useless since more chars than iChannelResolution[n] :-p

New constraints:     Verify your previews shaders, they might be broken !

  • Globals initialization must really be constant. Uniforms (like iGlobalTime , iResolution, iMouse), and even sqrt(3.) or float a=1.,b=a;  are no longer allowed… but for const variables.
  • It’s now totally forbidden to reuse a reserved keyword (built-in funcs, etc) as variable or function name. You cannot even overload functions. E.g., 
    • min(struct1, struct2) or cross(vec2,vec2) are no longer licit
    • you didn’t know new keyword will exist !
      frequent conflict: sample, smooth, round, inverse …
  • “precision” is no longer allowed… even in comments !
  • texture2D*() is now texture*()   (the team has already patched your shaders for this).
    But guessing the implicit LOD is now an error on windows in non-unrollable loops, and generates a lot of extra code anyway (+ possible compiler freeze). 
    -> now prefer texelFetch or textureLOD (at the price of WebGl1 compatibility).
More GLSL ES 3 reserved keywords:

Possibly/soon available to ShaderToy ?
invariant layout centroid flat smooth
lowp mediump highp precision
sampler2D sampler3D samplerCube
sampler2DShadow samplerCubeShadow
sampler2DArray sampler2DArrayShadow
isampler2D isampler3D isamplerCube isampler2DArray
usampler2D usampler3D usamplerCube usampler2DArray

Keywords reserved for future use:
attribute varying coherent volatile restrict readonly writeonly resource atomic_uint
noperspective patch sample subroutine common partition active
asm class union enum typedef template this goto
inline noinline volatile public static extern external interface
long short double half fixed unsigned superp
input output sizeof cast namespace using
hvec* sampler3DRect  filter

5 thoughts on “WebGL 2.0 vs WebGL 1.0

    • – Compilation is now done in WebGL2 if available
      On webGL2 systems: Some pure webGL1 might no longer work because of more strict rules: as mentioned above in “new constraints”, you can no longer use expressions to initialize globals at declaration; you can no longer overhide build-in functions; there are reserved words (precision, sample, smooth, sample, filter…).
      On non-webGL2 systems: Most shaders using new WebGL2 features won’t work, but for a few compatibility stubs that developers have added (round, trunc, transpose, inverse, determinant, + translation of texture into texture2D)

      Like

  1. I guess yes. But if these shaders no longer work correctly on WebGL2.0, most people will just see an error page, plus it might come that the management hide them out of the public shaders one day. So, be sure to check that all your WebGL1 shaders obey the stricter compiling rules of WebGL2 compilers.

    Like

    • Thanks. So it seems the only fails this change produces will be on a browser having WebGL 1.0 and WebGL 2.0, with a shader that’s not compatible with WebGL 2.0.

      Like

Leave a comment