# Documentation

The motivation behind this library and more in-depth information about the rendering techniques utilised can be found in this technical report.

## Links

- Repository
- Demo
- Minimal example
- More complex example
- Source code of the demo

## Usage

- To start using cutting-edge 2D graphics, first you have get a renderer instance. This is possible by calling the compile function.
  - For this, some DrawableDescriptors has to be provided.
  - Optionally, default compile settings can overridden using StartupSettings.
- After acquiring a renderer, the drawing of objects can be started through the Renderer interface.

## Extending drawables

> Iñigo Quilez has some great 2D SDF-s

- Subclass Drawable
- Implement its abstract methods
- Add a static property to your class called `descriptor` of type DrawableDescriptors
- Follow the instructions given in Usage

## Useful to know

### Math

The `vec2`, `vec3`, and `vec4` types seen in the documentation come from the glMatrix library and are equivalent to regular JS Arrays or Float32Arrays. So, feel free to give `[x, y]` as an input for functions requiring `vec2`.

### Coordinates

Anywhere, where positions need to be specified, the `y` values grow upwards. That means, when setting the view area, the origin is at the bottom left corner of the display.

### Tile-based rendering

For optimising the evaluation of the distance field, the display is divided up into a grid of tiles. The shaders for each tile are compiled to support a fix maximum number of objects on it. When using the built-in drawables it is possible that after a certain number of on-screen objects new ones won't be visible.

Mitigating this issue is quite easy. Instead of the following code:

    this.renderer = await compile(canvas, [Circle.descriptor, CircleLight.descriptor]);

Modify it to something similar:

    this.renderer = await compile(canvas, [
      {
        ...Circle.descriptor,
        shaderCombinationSteps: [0, 1, 2, 24, 64],
      },
      {
        ...CircleLight.descriptor,
        shaderCombinationSteps: [0, 1, 2, 4],
      },
    ]);

The usage of too large numbers is not advised for compatibility and performance reasons alike.

> Steps are very useful for tile-based rendering, because it is possible for one tile (at a given moment) to be empty or contain just a few objects, while others have a large cluster of objects. The compiled shaders only take into account the necessary number of objects on each tile.