0.2.9 • Published 2 years ago

glsl-canvas-js v0.2.9

Weekly downloads
33
License
MIT
Repository
github
Last release
2 years ago

💎 glsl-canvas

glsl-canvas-js is a typescript porting of GlslCanvas, a javascript library that helps you easily load GLSL Fragment and Vertex Shaders into an HTMLCanvasElement. Originally made by Patricio Gonzalez Vivo author of Book of Shaders and GlslEditor.

Now supporting WebGL2. just add #version 300 es at the very start of the file.

Now supporting nested includes with relative paths.

Examples
Docs

How to use

With link

Load the latest version of glsl-canvas.js on your page by adding this line to your HTML:

<script type="text/javascript" src="https://unpkg.com/glsl-canvas-js/dist/umd/glsl-canvas.min.js"></script>

With npm

If you are using npm package manager type this command on your terminal:

npm install glsl-canvas-js --save

Run with html

Add a canvas element on your page with class name glsl-canvas and assign a shader through a url using the data-fragment-url attribute.
Or write your shader directly in code using the data-fragment attribute.

<canvas class="glsl-canvas" data-fragment-url="fragment.glsl" width="500" height="500"></canvas>

GlslCanvas will automatically load a WebGL context in that <canvas> element, compile the shader and animate it for you.

Run with javascript

Create a <canvas> element and attach a new instance of glsl.Canvas.

const canvas = document.createElement('canvas');
const options = {
  vertexString: `...`,
  fragmentString: `...`,
  alpha: false,
  antialias: true,
  mode: 'flat',
  extensions: ['EXT_shader_texture_lod']
};
const glsl = new glsl.Canvas(canvas, options);

All the .glsl-canvas instances will be stored in the glsl.Canvas.items array.

Import es6 module

import { Canvas } from 'glsl-canvas-js';

const canvas = document.createElement('canvas');
const options = {
  vertexString: `...`,
  fragmentString: `...`,
  alpha: false,
  antialias: true,
  mode: 'flat',
  extensions: ['EXT_shader_texture_lod']
};
const glsl = new Canvas(canvas, options);

Init options

GlslCanvas options inherit from WebGLContextAttributes. Here the complete list.

const glsl = new Canvas(canvas, {
    vertexString: '...',
    fragmentString: '...',
    backgroundColor: 'rgba(0.0, 0.0, 0.0, 0.0)',
    alpha: true,
    antialias: true,
    depth: true,
    desynchronized: false,
    failIfMajorPerformanceCaveat: false,
    powerPreference: 'default',
    premultipliedAlpha: false,
    preserveDrawingBuffer: false,
    stencil: false,
    doubleSided: false,
    extensions: ['EXT_shader_texture_lod'],
    workpath: 'rootfolder',
    mode: 'mesh',
    mesh: 'myfolder/myfile.obj',
    onError: (error) => {}
});

Default Shader Attributes

These attributes are automatically loaded for you.

name
a_positiona vec4 with vertex position.
a_normala vec4 with normal values.
a_texturea vec2 with texture coords mapping.
a_colora vec4 with face color info.

Default Uniforms

These uniforms are automatically loaded for you.

name
u_timea float representing elapsed time in seconds.
u_resolutiona vec2 representing the dimensions of the viewport.
u_mousea vec2 representing the position of the mouse, defined in Javascript with .setMouse({x:[value],y:[value]).
u_texture_Na sampler2D containing textures loaded with the data-textures attribute.

Attributes

name
data-fragmentload a fragment shader by providing the content of the shader as a string
data-vertexload a vertex shader by providing the content of the shader as a string
data-fragment-urlload a fragment shader by providing a valid url
data-vertex-urlload a vertex shader by providing a valid url
data-modesetup one of those modes flat, box, sphere, torus, mesh
data-texturesload a list of texture urls separated by commas (ex: data-textures="color.jpg,normal.png,bump.jpg"). Textures will be assigned in order to uniform sampler2D variables with names following this style: u_texture_0, u_texture_1, u_texture_2, etc.
controlsenable play on over functionality
data-autoplayenable autoplay with controls feature

Events

nameargument
loadGlslCanvas instance
errorError
textureErrorTextureError
renderGlslCanvas instance
overMouseEvent
outMouseEvent
move{ x:, y: }
clickMouseEvent

Methods

nameparameters
loadfragment: string, vertex: string
oneventName: string, callback: Function
setTexturekey: string, target: string or element, options:TextureOptions
setUniformkey: string, ...values: number or string
setUniformsuniforms: { key: string: number[] or string }
play
pause
toggle
destroy

Including dependent files with #include

You can include other GLSL code using a traditional #include "file.glsl" macro.

// example
#include "common/uniforms.glsl"
#include "common/functions.glsl"

void main(){

Multiple buffers

You can use shader buffers by requiring definition with #ifdef or defined directly in .glsl code.
Just ask for BUFFER_N definition and a u_bufferN uniform will be created for you:

uniform sampler2D u_buffer0;

#ifdef BUFFER_0

void main() {
    vec4 color = texture2D(u_buffer0, uv, 0.0);
    ...
    gl_FragColor = color;
}

#else

void main() {
    vec4 color = texture2D(u_buffer0, uv, 0.0);
    ...
    gl_FragColor = color;
}

#endif

Vertex & Fragment shader

You can define both vertex and fragment shader on same file by requiring vertex definition with #ifdef or defined directly in .glsl code.
Just ask for VERTEX definition and the vertex shader will be created for you:

#if defined(VERTEX)

// attribute vec4 a_position; // data/dolphin.obj
attribute vec4 a_position;
attribute vec4 a_normal;
attribute vec2 a_texcoord;
attribute vec4 a_color;

void main(void) {
	v_position = a_position;
	v_position = u_projectionMatrix * u_modelViewMatrix * v_position;
	v_normal = u_normalMatrix * a_normal;
	v_texcoord = a_texcoord;
	v_color = a_color;
	gl_Position = v_position;
}

// fragment shader
#else

void main() {
  ...
}

Tips

You can change the content of the shader as many times you want. Here are some examples:

// load only the fragment shader
let fragment = 'main() { gl_FragColor = vec4(1.0); }';
glsl.load(fragment);

// load a fragment and vertex shader
let vertex = 'attribute vec4 a_position; main(){ gl_Position = a_position; }';
glsl.load(fragment, vertex);

You can also send your custom uniforms to a shader with .setUniform('name', ...values). GlslCanvas will parse the value you provide to determine its type. If the value is a string, GlslCanvas will parse it as the url of a texture.

// assign .5 to 'uniform float u_brightness'
glsl.setUniform('u_brightness', 0.5); 

// assign (.2,.3) to 'uniform vec2 u_position'
glsl.setUniform('u_position', 0.2, 0.3);

// assign a red color to 'uniform vec3 u_color'
glsl.setUniform('u_color', 1.0, 0.0, 0.0); 

// load a new texture and assign it to 'uniform sampler2D u_texture'
glsl.setUniform('u_texture', 'data/texture.jpg');

Examples

You can find some example to start at this page.

Or you can see a live demo at this link actarian.github.io/glsl-canvas/


Collaborate

If you'd like to contribute to this code, you need to:

git clone https://github.com/actarian/glsl-canvas.git
  • Switch to glsl-canvas directory
cd glsl-canvas
  • Install dependencies
npm install
  • Run gulp for development and testing with livereload
gulp
  • Build for production
gulp build --target dist
  • Push to your local fork and make your pull request

Pull requests are welcome and please submit bugs 🐞

Thank you for taking the time to provide feedback and review. This feedback is appreciated and very helpful 🌈

GitHub forks GitHub stars GitHub followers


Contact

Twitter Follow


Release Notes

Changelog here.

0.2.7

2 years ago

0.2.9

2 years ago

0.2.8

2 years ago

0.2.6

3 years ago

0.2.5

3 years ago

0.2.4

3 years ago

0.2.3

3 years ago

0.2.2

4 years ago

0.2.0

4 years ago

0.1.7

4 years ago

0.1.6

5 years ago

0.1.5

5 years ago

0.1.4

5 years ago

0.1.3

5 years ago

0.1.2

5 years ago

0.1.1

5 years ago

0.1.0

5 years ago