Shader Canvas

A graphics framework for specialists

Low-level tags for your high-level graphics projects.

  Shader Canvas starts with this tag
  Its children tags define what will
  be rendered.

  These tags match the low-level WebGL

  It can support multiple graphical API
  backends in the future.
  Start the WebGl backend
  (the only one supported for now)

  Inside this element, each tag
  corresponds to its low level
  WebGL function.

  List the actions to perform when
  drawing. Each tag matches the
  corresponding WebGL function.
      <clear-color red="0" green="0" blue="0" alpha="1"></clear-color>
  The <clear-color> matches the
  WebGL "clearColor()" function

  There is one of these for each
  WebGL function.
      <clear-flags mask="COLOR_BUFFER_BIT"></clear-flags>
  The <clear-flags> matches the
  WebGL "clearFlags()" function

  Each tag has attributes according
  to the names given to the function
  arguments in the WebGL spec.

      <use-program src="simple-triangle">
  Likewise <use-program> matches the
  "useProgram()" function.
  The "src" attribute can reference
  the tag name that defines the
  WebGL program to use.

  In this case <use-program> will
  look for the <simple-triangle>
  program, defined below.
        <draw-vao src="triangle-vao"></draw-vao>
  Any tag inside <use-program>
  has the program bound to it.

  Here, <draw-vao> is calling the
  WebGL draw function for the
  Vertex Array Object defined
  below at the tag <triangle-vao>.
  (VAO stands for Vertex Array Object).

  Besides the <draw-calls> the 
  <webgl-canvas> can have 4 containers:
   - <webgl-programs>
      * every child will be a program
   - <webgl-buffers>
      * every child will be a buffer
   - <webgl-textures>
      * every child will be a texture
   - <webgl-vertex-array-objects>
      * every child will be a

  Their direct children tag names can
  be used as a reference in the "src"
  attribute of other tags.
  Inside the <webgl-programs> container
  you can define the WebGL programs
  by specifying a unique tag name to
  each program.
  Here starts the program
  "simple-triangle". Any name could
  be set.
  A WebGL program has a vertex-shader
  and a fragment-shader.
            #version 300 es
            in vec4 a_position;
            void main() {
                gl_Position = a_position;
            #version 300 es
            precision highp float;
            out vec4 outColor;
            void main() {
              outColor = vec4(1, 0, 1, 1);

  <webgl-vertex-array-objects> works
  like <webgl-programs>: you can put
  any name here as a child tag,
  provided it is unique.

  Other tags can then reference this
  name in their "src" attributes.
  Here a Vertex Array Object
  called "triangle-vao" is being
        <bind-buffer src="triangle-vertices">
  <bind-buffer> corresponds to the
  WebGL function "bindBuffer()"

  It is referencing the tag 
  "triangle-vertices" which is
  a buffer defined below
  in <webgl-buffers>
          <vertex-attrib-pointer variable="a_position" size="2">
  Any child of <bind-buffer> will
  have the referenced buffer bound.

  Here the <vertex-attrib-pointer>
  will use the "vertexAttribPointer()"
  function for the buffer set at the
  <triangle-vertices> tag.

  <webgl-buffers> is a container like
  <webgl-vertex-array-objects> and 

  It is used to set buffers and their
  data. In WebGL the buffers data is
  separated from their meaning and usage.

  <webgl-programs> and <webgl-textures>
  can provide meaning and use the
  buffers declared here.
        <buffer-data src="#trianglePoints"></buffer-data>
  The tag <buffer-data> is equivalent
  to the "bufferData" WebGL function.

  The "src" attribute can also be an
  element query string (used in the
  "querySelector" function), as well as
  a url that can point to the data to load.


<!-- The data for the buffer -->
<div id="trianglePoints">[-0.7, 0, 0, 0.5, 0.7, 0]</div>

One tag per low-level function

A declarative syntax for graphics API's has several benefits and disadvantages.



Composable modules

With <shader-canvas>, you can also create custom abstractions and compositions through modules.

With the module system, you can:

<shader-canvas> uses no dependencies and has ~80KB of JavaScript (~15KB minified and gzipped).

Customizable high-level abstractions

Shader Canvas allows you to work as high-level as you need.

You might want to redo the low-level triangle approach from the code above with an abstraction like this:

  <buffer-2d variable="vertex2d">
    [-0.7,   0,
        0, 0.5,
      0.7,   0]
    #version 300 es
    void main() {
      gl_Position = vertex2d;
    #version 300 es
    precision highp float;
    out vec4 outColor;

    void main() {
      outColor = vec4(1, 0, 1, 1);

With the Shader Canvas module system you can declaratively, through HTML tags, create these kind of abstractions and new tags.

Read more about Shader Canvas in the documentation page.