Skip to content

actarian/glsl-canvas

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

71 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ’Ž 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_position a vec4 with vertex position.
a_normal a vec4 with normal values.
a_texture a vec2 with texture coords mapping.
a_color a vec4 with face color info.

Default Uniforms

These uniforms are automatically loaded for you.

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

Attributes

name
data-fragment load a fragment shader by providing the content of the shader as a string
data-vertex load a vertex shader by providing the content of the shader as a string
data-fragment-url load a fragment shader by providing a valid url
data-vertex-url load a vertex shader by providing a valid url
data-mode setup one of those modes flat, box, sphere, torus, mesh
data-textures load 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.
controls enable play on over functionality
data-autoplay enable autoplay with controls feature

Events

name argument
load GlslCanvas instance
error Error
textureError TextureError
render GlslCanvas instance
over MouseEvent
out MouseEvent
move { x:, y: }
click MouseEvent

Methods

name parameters
load fragment: string, vertex: string
on eventName: string, callback: Function
setTexture key: string, target: string or element, options:TextureOptions
setUniform key: string, ...values: number or string
setUniforms uniforms: { [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.