LG is a small tool to call webgl without the confusing boilerplate, but with useful extra builtin variables and functions. I hope this tool can help you run parallel code easily on the browser for demonstration, illustration or teaching purpose.
Here is a list of available things. Commented lines are not implemented yet.
const float pi = 3.14159265359; // π
const float two_pi = 2.*pi; // 2π
uniform vec2 mouse; // the position of the mouse ∈ [-1,1]²
uniform vec2 res; // the resolution of the canvas ∈ ℕ²
float cosinus(float angle); // native cos precision can be very bad depending on hardware
float sinus(float angle); // native sin precision can be very bad depending on hardware
// uniform vec4 scroll; // 2d scroll position ∈ ℝ² + scroll scale ∈ ℝ²
// uniform vec4 scroll_a; // 2d parameter controlled with scroll/middle-click + key_a
// uniform vec4 scroll_b; // 2d parameter controlled with scroll/middle-click + key_b
// uniform vec4 scroll_z; // 2d parameter controlled with scroll/middle-click + key_z
// uniform mat4 rot_a; // rotation controlled with scroll/middle-click + key_a
// uniform mat4 rot_b; // rotation controlled with scroll/middle-click + key_b
// uniform mat4 rot_z; // rotation controlled with scroll/middle-click + key_z
uniform float html_blah; // the value of the html element with id "blah" such as :
//
// you just have to prepend the id with html_
// So far only float are supported, but I intend to introduce
// vec3 and matrices with custom html element such as
//
//
// etc...
LG_VECTORIZE_2(FUNC) // from `float FUNC(floatv)` makes `vec2 FUNC(vec2 v)`
LG_VECTORIZE_3(FUNC) // from `float FUNC(floatv)` makes `vec3 FUNC(vec3 v)`
LG_VECTORIZE_4(FUNC) // from `float FUNC(floatv)` makes `vec4 FUNC(vec4 v)`
LG_MAKE_VEC4_FUNC(T, FUNC) // when `T FUNC(vec4 v)` is defined, this macro will make
// all possible combination of int,float,vec2,vec3,vec4
// such as `T FUNC(vec3 v123, float v4)`
// or `T FUNC(int v1, vec3 v234)`
// even `T FUNC(vec3 v123)` that defaults to v4=0
//
LG_MAKE_VEC3_FUNC(T, FUNC) // same for `T FUNC(vec3 v)`
LG_MAKE_VEC2_FUNC(T, FUNC) // same for `T FUNC(vec2 v)`
//
// remark : we shouldn't need to specify `T` but
// I don't know how not to automate that
//
// remark : we should be able to replace them all with
// a single function `LG_MAKE_VEC_FUNC`
mat4 rot4(vec3 axis, float angle); // rotation matrix
mat3 rot3(vec3 axis, float angle); // rotation matrix
mat2 rot2(float angle); // rotation matrix
float noise(vec4 p); // aperiodic perlin noise (LG_MAKE_VEC4_FUNC enabled)
vec2 noise2(vec4 p); // aperiodic perlin noise (LG_MAKE_VEC4_FUNC enabled)
vec3 noise3(vec4 p); // aperiodic perlin noise (LG_MAKE_VEC4_FUNC enabled)
vec4 noise4(vec4 p); // aperiodic perlin noise (LG_MAKE_VEC4_FUNC enabled)
float rand(vec2 seed); // noise function
float c_len(vec2 z); // |z|
float c_abs(vec2 z); // |z|
float c_ang(vec2 z); // ang(z)
vec2 c_bar(vec2 z); // bar(z)
vec2 c_mul(vec2 z, vec2 w); // z⋅w
vec2 c_inv(vec2 z); // 1/z
vec2 c_log(vec2 z); // log(z)
vec2 c_exp(vec2 z); // exp(z)
vec2 c_exp(float im); // exp(0+i⋅im)
vec2 c_pow(vec2 z, float n); // z^n
vec2 c_pow(vec2 z, vec2 w); // z^w
vec2 c_sin(vec2 z); // sin(z)
vec2 c_cos(vec2 z); // cos(z)
// available colorspaces : srgb,rgb,xyz,xyY,HCV,HSV,HSL,HCY,YCbCr
// important : rgb = linear RGB ≠ sRGB
vec3 rgb2srgb(vec3 rgb); // example of available conversion
vec3 hcy2srgb(vec3 hcy); // example of available conversion
vec3 srgb2hcy(vec3 srgb); // example of available conversion
// etc...
float luminance(vec3 rgb); // luminance of a !! linear !! rgb color
vec3 rgb2srgb_fast(vec3 rgb); // approximated version of rgb2srgb
vec3 srgb2rgb_fast(vec3 srgb); // approximated version of srgb2rgb
float linear2srgb(float channel); // Converts a single linear channel to srgb
float srgb2linear(float channel); // Converts a single srgb channel to rgb
vec3 blackbody(float T); // Temperature (in Kelvin) to rgb or srgb, unclear, TODO
// pos ∈ [-1,+1] × [-1,+1]
// uv ∈ [ 0,+1] × [ 0,+1]
// spheric ∈ [-π,+π] × [-π/2,+π/2]
// vec ∈ ℝ^3
// hammer ∈ [-1,+1] × [-1,+1]
vec2 uv2spheric(vec2 uv); // conversion
vec2 spheric2uv(vec2 spheric); // conversion
// etc...
texture = lg.texture() // make a texture
texture.load("url/to/image.jpg") // load image from url
texture.wrap_s_mirror() // wrap mirror mode only s direction
texture.wrap_t_mirror() // wrap mirror mode only t direction
texture.wrap_mirror() // wrap mirror mode both direction
texture.wrap_s_repeat() // wrap repeat mode only s direction
texture.wrap_t_repeat() // wrap repeat mode only t direction
texture.wrap_repeat() // wrap repeat mode both direction
texture.wrap_s_clamp() // wrap clamp mode only s direction
texture.wrap_t_clamp() // wrap clamp mode only t direction
texture.wrap_clamp() // wrap clamp mode both direction
buffer = lg.buffer() // make a buffer
buffer.set([-1,-1, ..., 1, 1]) // fill the buffer with some numbers
count = 542 // the number of points corresponding to our buffer
// something like (buffer_size/buffer_dimension)
program = lg.program(vs,fs) // compile a GPU program from vert/frag shader
run = program.drawLines(count) // GPU program call function (the program is not called yet)
run = program.drawLineStrip(count) // GPU program call function (the program is not called yet)
run = program.drawLineLoop(count) // GPU program call function (the program is not called yet)
run = program.drawPoint(count) // GPU program call function (the program is not called yet)
run = program.drawTriStrip(count) // GPU program call function (the program is not called yet)
run = program.drawTriFan(count) // GPU program call function (the program is not called yet)
run = program.drawTri(count) // GPU program call function (the program is not called yet)
let vars = { // GPU program args
"position": buffer, // in vec2 position; or similar must be in the vertex shader
"tex": texture, // uniform sampler2D tex; or similar in any shader
"alpha": 1, // uniform float alpha; or similar in any shader
"coord": [1,0], // uniform vec2 coord; or similar in any shader
"xyz": [1,2,3], // uniform vec3 xyz; or similar in any shader
"color": [1,0,0,1], // uniform vec4 color; or similar in any shader
}
run(vars) // actual call of the GPU program
// TODO
// support vertexAttribIPointer
// support framebuffer texture
// lg.scroll_a.fix_axis(true) // keep the ground down for rotation
// lg.scroll_b.fix_axis(true) // keep the ground down for rotation
// lg.scroll_z.fix_axis(true) // keep the ground down for rotation
Geom.quad(20,40) // point list to be drawn with drawTriStrip or drawLineStrip
range(a) // returns [0, 1,...,a-2,a-1]
range(a,b) // returns [a,a+1,...,b-2,b-1]
linspace(a,b,N) // returns [a,a+ε,...,b-ε,b] that has N elements
linspace(N) // returns [0,0+ε,...,1-ε,ε] that has N elements
loop(f) // runs f(time,dt) forever
// returns a function "kill" to be called to stop the loop
canvas_autoresize(canvas) // automatically resizes a canvas resolution