# gl-renderer

> Drawing patterns with glsl shaders on modern browsers.

Latest version **0.14.0** (published 2022-04-12) · MIT license · 0 weekly downloads

## Install

```sh
npm install gl-renderer
pnpm add gl-renderer
yarn add gl-renderer
bun add gl-renderer
```

## Health

**Score 20/100 (F)** — status: abandoned.

Positive: esm support; no vulnerabilities.

Warnings: low downloads; no types; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.14.0 |
| Published | 2022-04-12 |
| First published | 2019-06-15 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | ESM + CommonJS |
| Dependencies | 1 |
| Unpacked size | 192 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | akira_cn, spritejs |

## Links

- npm: https://www.npmjs.com/package/gl-renderer
- npm.io page: https://npm.io/package/gl-renderer

## Dependencies (1)

- [@babel/runtime](https://npm.io/package/@babel/runtime.md) ^7.7.6

## Recent versions

- 0.14.0 (latest) — 2022-04-12
- 0.13.6 — 2020-08-09
- 0.13.5 — 2020-07-14
- 0.13.4 — 2020-06-11
- 0.13.3 — 2020-05-09
- 0.13.2 — 2020-05-03
- 0.13.1 — 2020-04-27
- 0.13.0 — 2020-04-26
- 0.12.8 — 2020-04-26
- 0.12.7 — 2020-04-26
- 0.12.5 — 2020-03-14
- 0.12.4 — 2020-02-05
- 0.12.3 — 2020-02-04
- 0.12.2 — 2020-02-04
- 0.12.1 — 2020-02-04
- … 54 more at https://npm.io/package/gl-renderer/versions

## README

# gl-renderer

A lightweight webgl renderer.

The underlying Library of [glsl-doodle](https://doodle.webgl.group/).

## Usage

In browser:

```html
<script src="https://unpkg.com/gl-renderer/dist/gl-renderer.js"></script>
```

With NPM:

```bash
npm install gl-renderer
```

## Quick Start

index.frag

```glsl
#ifdef GL_ES
precision mediump float;
#endif

uniform vec3 color;

void main() {
  gl_FragColor.rgb = color;
  gl_FragColor.a = 1.0;
}
```

index.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Demo</title>
  <script src="https://unpkg.com/gl-renderer/dist/gl-renderer.js"></script>
</head>
<body>
  <canvas id="gl-canvas" width="512" height="512"></canvas>
  <script>
  (async function () {
    const glCanvas = document.getElementById('gl-canvas');
    const renderer = new GlRenderer(glCanvas);

    // load fragment shader and createProgram
    const program = await renderer.load('./index.frag');
    renderer.useProgram(program);

    // set color to RED
    renderer.uniforms.color = [1, 0, 0];

    renderer.render();
  }());
  </script>
</body>
</html>
```

You will see a canvas 512 pixels wide and 512 pixels high in red.

## API Reference

### constructor(canvas, options = {})

Create renderer options with specified canvas element and options.

The options:

- autoUpdate: Force renderer to update when uniforms or meshdata changes. Default value is true.
- vertexPosition: Attribute name of position in vertex shader. Default value is 'a_vertexPosition'.
- vertexTextureCoord: Attribute name of texture coordinate in vertext shader. Default value is 'a_vertexTextureCoord'.
- Other webgl context options: [See MDN](https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/getContext).
- webgl2: Use webgl2 context. Default value is false.

### renderer.createProgram(fragment[, vertex])

Create a program with specified fragment shader and vertex shader.

```js
const fragmentShader = `
#ifdef GL_ES
precision mediump float;
#endif

void main() {
  gl_FragColor = vec4(1, 0, 0, 1);
}
`;

const program = renderer.createProgram(fragmentShader);
render.useProgram(program);
```

If you don't specified vertex shader, a default vertex shader will be loaded.

```glsl
attribute vec4 a_vertexPosition;

void main() {
  gl_PointSize = 1.0;
  gl_Position = a_vertexPosition;
}
```

or

```glsl
attribute vec4 a_vertexPosition;
attribute vec2 a_vertexTextureCoord;
varying vec2 vTextureCoord;

void main() {
  gl_PointSize = 1.0;
  gl_Position = a_vertexPosition;
  vTextureCoord = a_vertexTextureCoord;
}
```

It depends whether you use texture samplers in your fragment shader or not.

### _async_ renderer.compile(fragment[, vertex])

gl-render allows you to use `#pragma include` statment to load and include other shaders.

base.glsl

```glsl
highp float random(vec2 co) {
    highp float a = 12.9898;
    highp float b = 78.233;
    highp float c = 43758.5453;
    highp float dt= dot(co.xy ,vec2(a,b));
    highp float sn= mod(dt,3.14);
    return fract(sin(sn) * c);
}
```

```js
const fragmentShader = `
#ifdef GL_ES
precision mediump float;
#endif

#pragma include "./base.glsl"

void main() {
  gl_FragColor = random(gl_FragCoord.xy) * vec4(1, 0, 0, 1);
}
`;

const program = await render.compile(fragmentShader);
renderer.useProgram(program);
```

### _async_ renderer.load(fragmentURL[, vertexURL])

Load fragment shader and vertex shader from url.

```js
const program = await renderer.load('./index.glsl');

renderer.useProgram(program);
```

### renderer.useProgram(program[, attributeDescriptor])

Sets the specified Program as part of the current rendering state.

### renderer.createTexture(image)

Wrap a image object (or canvas) to a webgl texture.

```js
function loadImage(src) {
  const img = new Image();
  img.crossOrigin = 'anonymous';
  return new Promise((resolve) => {
    img.onload = function () {
      resolve(img);
    };
    img.src = src;
  });
}

(async function () {
  const glCanvas = document.getElementById('gl-canvas');
  const renderer = new GlRenderer(glCanvas);

  const image = await loadImage('http://path.to.image/image.png');
  const texture = renderer.createTexture(image);

  const program = await renderer.load('./index.frag');
  renderer.useProgram(program);
  // bind texture to samplerMyTex
  renderer.uniforms.samplerMyTex = texture;

  renderer.render();
}());
```

### renderer.loadTexture(src)

Load image from source url and create a texture.

```js
(async function () {
  const glCanvas = document.getElementById('gl-canvas');
  const renderer = new GlRenderer(glCanvas);

  const texture = await renderer.loadTexture('http://path.to.image/image.png');

  const program = await renderer.load('./index.frag');
  renderer.useProgram(program);
  // bind texture to samplerMyTex
  renderer.uniforms.samplerMyTex = texture;

  renderer.render();
}());
```

### renderer.setMeshData(meshData)

Set a list of meshData.

```js
const meshData = [mesh0, mesh1, mesh2...];
```

A mesh object contains the following properties:

- positions : _Required_. The vertex positions of the geometry.
- cells: _Required_. The indices of the vertexes.
- textureCoord: The texture coordinates.
- attributes: The attributes passed into the shaders.
- uniforms: The changed uniform values.
- instanceCount: Set instanceCount for webgl2 context to draw instanced arrays.

index.vert

```glsl
attribute vec3 a_vertexPosition;
attribute vec3 a_color;

varying vec3 vColor;

void main() {
  gl_PointSize = 1.0;
  gl_Position.xyz = a_vertexPosition;
  gl_Position.w = 1.0;
  vColor = a_color;
}
```

index.frag

```glsl
#ifdef GL_ES
precision mediump float;
#endif

varying vec3 vColor;

void main() {
  gl_FragColor = vec4(vColor, 1.0);
}
```

```js
(async function () {
  const glCanvas = document.getElementById('gl-canvas');
  const renderer = new GlRenderer(glCanvas);

  const program = await renderer.load('./index.frag', './index.vert');
  renderer.useProgram(program, {
    a_color: {
      type: 'UNSIGNED_BYTE',
      normalize: true,
    },
  });

  const vertexColors = [
    [255, 0, 0],
    [255, 0, 0],
    [255, 255, 0],
  ];

  renderer.setMeshData([
    {
      positions: [[-1.0, -1.0, 0.0], [-1.0, 1.0, 0.0], [1.0, 1.0, 0.0]],
      cells: [[0, 1, 2]],
      attributes: {
        a_color: vertexColors,
      },
    },
    {
      positions: [[0.5, 0.5, 0], [-0.5, 0.8, 0], [1, -1, 0]],
      cells: [[0, 1, 2]],
      attributes: {
        a_color: vertexColors,
      },
    },
  ]);

  renderer.render();
}());
```

### renderer.render(clearBuffer = true)

Clear and re-draw canvas. If clearBuffer set to true(default is true), renderer will automately clear color buffer before render.

### renderer.uniforms

The uniform declarations in the fragment shader will be automatically bind to renderer.uniforms.

index.frag

```glsl
#ifdef GL_ES
precision mediump float;
#endif

uniform float u_time;

void main() {
  gl_FragColor = 0.5 * (1.0 + sin(0.00314 * u_time)) * vec4(1, 0, 0, 1);
}
```

```js
(async function () {
  const glCanvas = document.getElementById('gl-canvas');
  const renderer = new GlRenderer(glCanvas);

  const program = await renderer.load('./index.frag');
  renderer.useProgram(program);

  const startTime = Date.now();

  renderer.uniforms.u_time = 0;

  requestAnimationFrame(function update() {
    renderer.uniforms.u_time = Date.now() - startTime;
    requestAnimationFrame(update);
  });

  renderer.render();
}());
```

### renderer.update()

Cause canvas to clear and re-draw in next frame. Change **uniforms** or set meshData will force renderer update automatically.

---
_Source: https://npm.io/package/gl-renderer · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
