ShaderDSL.js: Writing shaders in JavaScript

If you have been playing with WebGL you probably have heard of GLSL, the shading language used with OpenGL and as a result WebGL. Due to its origin, GLSL is not very web developer friendly with a C style syntax, statically typed and an implicit data passing model (re:varying registers).

This is what a typical GLSL shader usually looks like:

As a recall, a shader program is made of a vertex (for vertices position) and a fragment (pixel color) shader. As you can see, it really is just C code embedded in the page, which may feel a little unnatural to most web developers. That’s why we recently started a little experiment, to make shader programming a little easier and more web friendly, so please meet ShaderDSL.js, a project initiated and led by Krzysztof Palacz at Adobe.

With ShaderDSL.js, you would describe your shader program like this:

Note that we are using Gladder here, a little WebGL wrapper, but if you look at the way we expressed our shader program, you can notice a few things, data is passed explicitly (function parameters, return statement, etc.) and the built-in function calls like sin becomes Math.sin, which again will look more familiar to JavaScript developers. Also, line 15 and 16 in the code above could just be free variables in the body of the kernel.

ShaderDSL

ShaderDSL.js presentation including demo.

So how does it work behind the scenes?

The current prototype relies on a hack of the RiverTrail JavaScript to OpenCL compiler to generate GLSL. If you don’t know about RiverTrail, it is an Intel project aiming at leveraging the GPU for general computations, like parallelizing loops across multiple GPU cores to accelerate execution. The ShaderDSL compiler itself is implemented in JavaScript with no browser extension, which means that it can work in all browsers, not just Firefox, when type inference fails – RiverTrail fallbacks to JavaScript easily, prototype fails.

If you want to play with ShaderDSL.js, check the github repo. In the future, we could have a proper spec of the supported language subset – somewhere between asm.js and Cajita. Some domain-specific conveniences: operator overloading, swizzling and maybe maximum consistency between JS running on CPU and GPU – a DSL with both JS and GLSL backends?

Posted on September 2, 2013 by Thibault Imbert · 6 comments
  • Pingback: Psaní WebGL shaderů mnohem přívětivější formou dík… | Matěj Šimek - Blog

  • http://marcinignac.com Marcin Ignac

    It’s an interesting approach but I would to see naming conventions follow more the original GLSL. For example vector.x instead of vector[0] or texture2D.sample instead texture2D.create(????).

  • Nicolas Cannasse

    Reminds me HxSL approach ;) http://haxe.org/manual/hxsl, I’m still planning to fully support GLSL output in the near future.

    • Thibault Imbert

      Very cool to hear Nicolas.

  • Bartek Drozdz

    I’m not sure whether this is a good approach. I understand the educational purpose here and the hope that it will maybe make more developers want to try writing shaders but I don’t think offering a JS syntax for shader is a solution.

    GLSL is a nice high level language with powerful features like overloaded operators, which is in my opinion crucial to write advanced mathematical formulas. The JS version takes it all away and offers a confusing and hard to read syntax instead. GLSL is based on C, but it is not C and it does not come with all the hurdles of C programming (pointers, memory management etc…) – so there is no need to scare people by comparing it to C. GLSL syntax is actually easy to learn.

    Having to write your GLSL code embedded in script tags is not very handy – I agree, but there are other ways to deal with this, like loading GLSL files with AJAX for example.

    The hard part is understanding how shaders work. As a person with no computer science background I know how long it took me to start to realize how it works – especially how parameters and variables are passed around and what parallel processing means. The other difficult thing is the math – you can’t write cool shader effects if you do not know your math. None of this problems will be solved by a switch from GLSL syntax to JS syntax.

    • Thibault Imbert

      I think it is a good exercise to think about easier ways to write shaders. I agree with you that GLSL is easier to learn than C, but still, some areas are a little obscure to people at first and yes they could learn, but I like the idea of looking at it with a fresh eye and try to make it better. You mention how parameters and variables are passed, some of these things are implicit and most web developers would probably feel better with a more explicit syntax. Now you could argue that people authoring shaders are generally more advanced developers who can deal with this. That’s fair.