Lookuptable GradientMap Vignette

This commit is contained in:
2019-12-11 15:19:35 +01:00
parent 0ddbec99ed
commit 37e1d9f3a1
9 changed files with 244 additions and 13 deletions

View File

@@ -3,6 +3,10 @@ import { v4 as uuid } from 'uuid';
import {Variables, InputProperties, OutputProperties} from './io/AbstractIOSet';
import {MultiSubject} from '../helpers/listener';
/**
* Elemetar unit of graphfx
* has inputs/outputs which can be connected to other nodes
*/
export default class Node<I extends Variables, O extends Variables> {
name: string
@@ -70,19 +74,24 @@ export default class Node<I extends Variables, O extends Variables> {
}
/**
* Input getters
* Node inputs
*
*/
get in() {
return this.__in;
}
/**
* Output getters
* Node outputs
*
*/
get out() {
return this.__out;
}
/**
* Create json serializable object
*/
serialize() {
return {
id: this.id,

View File

@@ -0,0 +1,75 @@
import WebGL from './WebGl';
import {lookup} from './assets';
import {
NumberVar,
ImageVar,
} from '../io/AbstractIOSet';
const inputs = {
amount: {
type: 'Number',
default: 1,
} as NumberVar,
map: {
type: 'Image',
default: lookup,
} as ImageVar,
};
export default class ColorLookupTable extends WebGL<typeof inputs> {
constructor() {
super('ColorLookupTable', inputs)
}
get frag() {
return `
precision mediump float;
// our texture
uniform sampler2D u_image;
uniform sampler2D u_map;
// the texCoords passed in from the vertex shader.
varying vec2 v_texCoord;
uniform float amount;
void main() {
vec4 textureColor = clamp(texture2D(u_image, v_texCoord), 0.0, 1.0);
mediump vec2 quad1;
float blueColor = textureColor.b * 63.0;
quad1.y = floor(floor(blueColor) / 8.0);
quad1.x = floor(blueColor) - (quad1.y * 8.0);
mediump vec2 quad2;
quad2.y = floor(ceil(blueColor) / 8.0);
quad2.x = ceil(blueColor) - (quad2.y * 8.0);
highp vec2 texPos1;
texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);
texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);
highp vec2 texPos2;
texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);
texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);
lowp vec4 newColor1 = texture2D(u_map, texPos1);
lowp vec4 newColor2 = texture2D(u_map, texPos2);
lowp vec4 newColor = mix(newColor1, newColor2, fract(blueColor));
// gl_FragColor = mix(color, mappedColor, amount);
gl_FragColor = mix(textureColor, newColor, amount);
}
`
}
get amount() {
return this.in.amount.value;
}
async _setParams(gl: WebGLRenderingContext, program: WebGLProgram) {
gl.uniform1f(gl.getUniformLocation(program, "amount"), this.amount);
}
}

View File

@@ -0,0 +1,54 @@
import WebGL from './WebGl';
import {
NumberVar,
ImageVar,
} from '../io/AbstractIOSet';
const inputs = {
amount: {
type: 'Number',
default: 1,
} as NumberVar,
map: {
type: 'Image',
} as ImageVar,
};
export default class GradientMap extends WebGL<typeof inputs> {
constructor() {
super('GradientMap', inputs)
}
get frag() {
return `
precision mediump float;
// our texture
uniform sampler2D u_image;
uniform sampler2D u_map;
// the texCoords passed in from the vertex shader.
varying vec2 v_texCoord;
uniform float amount;
void main() {
vec4 color = texture2D(u_image, v_texCoord);
float luminance = (0.2126*color.r + 0.7152*color.g + 0.0722*color.b);
vec4 mappedColor = texture2D(u_map, vec2(luminance, 0.0));
gl_FragColor = mix(color, mappedColor, amount);
}
`
}
get amount() {
return this.in.amount.value;
}
async _setParams(gl: WebGLRenderingContext, program: WebGLProgram) {
gl.uniform1f(gl.getUniformLocation(program, "amount"), this.amount);
}
}

View File

@@ -10,7 +10,7 @@ const inputs = {
} as NumberVar,
}
export default class Sepia extends WebGL<typeof inputs> {
export default class Tint extends WebGL<typeof inputs> {
constructor() {
super('Tint', inputs)

View File

@@ -0,0 +1,57 @@
import WebGL from './WebGl';
import {
NumberVar
} from '../io/AbstractIOSet';
const inputs = {
amount: {
type: 'Number',
default: 0.5,
} as NumberVar,
size: {
type: 'Number',
default: 0.5,
} as NumberVar,
}
export default class Vignette extends WebGL<typeof inputs> {
constructor() {
super('Vignette', inputs)
}
get frag() {
return `
precision mediump float;
// our texture
uniform sampler2D u_image;
// the texCoords passed in from the vertex shader.
varying vec2 v_texCoord;
uniform float amount;
uniform float size;
void main() {
vec4 color = texture2D(u_image, v_texCoord);
float dist = distance(v_texCoord, vec2(0.5, 0.5));\
color.rgb *= smoothstep(0.8, size * 0.799, dist * (amount + size));
gl_FragColor = color;\
}
`
}
get amount() {
return this.in.amount.value;
}
/**
*
* @param {WebGLRenderingContext} gl
* @param {*} program
*/
_setParams(gl, program) {
gl.uniform1f(gl.getUniformLocation(program, "amount"), this.amount);
}
}

View File

@@ -149,6 +149,30 @@ export default class WebGL<I extends Variables> extends Node<I & (typeof inputs)
return texture;
}
async createTextures(gl: WebGLRenderingContext, program: WebGLProgram) {
let i = 0;
type Texture = {
i: number,
tex: WebGLTexture,
name: string,
location: WebGLUniformLocation,
};
const textures:Texture[] = [];
for (let inputName of Object.keys(this.in.variables)) {
if (this.in[inputName].type === 'Image' && this.in[inputName].value) {
textures.push({
i,
tex: this.createTexture(gl),
name: inputName,
location: gl.getUniformLocation(program, `u_${inputName}`),
})
i+=1;
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, await createImageBitmap(<PoolCanvas<any>>this.in[inputName].value));
}
}
return textures;
}
_createFrameBuffer(gl: WebGLRenderingContext, {width, height}) {
const texture = this.createTexture(gl);
@@ -175,8 +199,7 @@ export default class WebGL<I extends Variables> extends Node<I & (typeof inputs)
]
}
_setParams(gl, program) {
_setParams(gl: WebGLRenderingContext, program: WebGLProgram) {
}
setup() {
@@ -219,8 +242,6 @@ export default class WebGL<I extends Variables> extends Node<I & (typeof inputs)
];
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
this.createTexture(gl);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
@@ -231,10 +252,7 @@ export default class WebGL<I extends Variables> extends Node<I & (typeof inputs)
const resolutionLocation = gl.getUniformLocation(program, "u_resolution");
const flipLocation = gl.getUniformLocation(program, "u_flip_y");
if (this.image) {
// Upload the image into the texture.
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, await createImageBitmap(<PoolCanvas<any>>this.image));
}
const textures = await this.createTextures(gl, program);
const texcoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
@@ -289,15 +307,25 @@ export default class WebGL<I extends Variables> extends Node<I & (typeof inputs)
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer.frameBuffer);
}
passes[iter](gl, program);
// set the resolution
gl.uniform2f(resolutionLocation, gl.canvas.width, gl.canvas.height);
gl.uniform2f(gl.getUniformLocation(program, "u_textureSize"), width, height);
for (let {i, tex, location, name} of textures) {
// console.log('bind', i, name, this.in[name].value, location, [gl.TEXTURE0, gl.TEXTURE1, gl.TEXTURE2, gl.TEXTURE3][i]);
if (this.in[name].value) {
gl.uniform1i(location, i + 2);
gl.activeTexture([gl.TEXTURE2, gl.TEXTURE3][i]);
gl.bindTexture(gl.TEXTURE_2D, tex);
}
}
// Draw the rectangle.
gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.bindTexture(gl.TEXTURE_2D, frameBuffer.texture);
// gl.bindTexture(gl.TEXTURE_2D, frameBuffer.texture);
}
const resultCanvas = canvasPool2D.createCanvas();

View File

@@ -0,0 +1,5 @@
export const lookup = (() => {
const img = new Image();
img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAIAAAB7GkOtAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAuJAAALiQE3ycutAAAH0klEQVR4nO3dQWorMRBFUQnU+7D3v8m/g3xwDwpxzyHDBB6eXGoQa6+1zp8/z/9+YfbP9zr222+//fb/9OdnARAkAABRAgAQJQAAUQIAECUAAFECABAlAABRAgAQJQAAUWc90xMAmOACAIgSAIAoAQCIEgCAKAEAiBIAgCgBAIgSAIAoAQCIEgCAKAEAiBIAgCgBAIgSAIAoAQCIEgCAKAEAiBIAgCgBAIgSAIAoj8IDRLkAAKIEACBKAACiBAAgSgAAogQAIEoAAKIEACBKAACiBAAgSgAAogQAIEoAAKIEACBKAACiBAAgSgAAogQAIEoAAKIEACDKo/AAUS4AgCgBAIgSAIAoAQCIEgCAKAEAiBIAgCgBAIgSAIAoAQCIOmt/hie8dXvBbt9/+3eJ3P752z/r7v0uAIAoAQCIEgCAKAEAiBIAgCgBAIgSAIAoAQCIEgCAKAEAiDrX/yc/AD9xAQBECQBAlAAARAkAQJQAAEQJAECUAABECQBAlAAARAkAQJQAAEQJAECUAABECQBAlAAARAkAQJQAAEQJAECUAABECQBAlEfhAaJcAABRAgAQJQAAUQIAECUAAFECABAlAABRAgAQJQAAUQIAECUAAFECABAlAABRAgAQJQAAUQIAECUAAFECABAlAABRAgAQ5VF4gCgXAECUAABECQBAlAAARAkAQJQAAEQJAECUAABECQBAlAAARJ21v9MbXrq9YPbPsn+W/ZNcAABRAgAQJQAAUQIAECUAAFECABAlAABRAgAQJQAAUQIAEHXWMz0BgAkuAIAoAQCIEgCAKAEAiBIAgCgBAIgSAIAoAQCIEgCAKAEAiBIAgCgBAIgSAIAoAQCIEgCAKAEAiBIAgCgBAIgSAIAoAQCI8ig8QJQLACBKAACiBAAgSgAAogQAIEoAAKIEACBKAACiBAAgSgAAogQAIEoAAKIEACBKAACiBAAgSgAAogQAIEoAAKIEACBKAACiPAoPEOUCAIgSAIAoAQCIEgCAKAEAiBIAgCgBAIgSAIAoAQCIEgCAqLP2Z3jCW7cXzP5Z9s+yf5ILACBKAACiBAAgSgAAogQAIEoAAKIEACBKAACiBAAgSgAAos56picAMMEFABAlAABRAgAQJQAAUQIAECUAAFECABAlAABRAgAQJQAAUQIAECUAAFECABAlAABRAgAQJQAAUQIAECUAAFECABAlAABRHoUHiHIBAEQJAECUAABECQBAlAAARAkAQJQAAEQJAECUAABECQBAlAAARAkAQJQAAEQJAECUAABECQBAlAAARAkAQJQAAEQJAECUR+EBolwAAFECABAlAABRAgAQJQAAUQIAECUAAFECABAlAABRAgAQddb+Tm946faC2T/L/ln2T3IBAEQJAECUAABECQBAlAAARAkAQJQAAEQJAECUAABECQBA1FnP9AQAJrgAAKIEACBKAACiBAAgSgAAogQAIEoAAKIEACBKAACiBAAgSgAAogQAIEoAAKIEACBKAACiBAAgSgAAogQAIEoAAKIEACDKo/AAUS4AgCgBAIgSAIAoAQCIEgCAKAEAiBIAgCgBAIgSAIAoAQCIEgCAKAEAiBIAgCgBAIgSAIAoAQCIEgCAKAEAiBIAgCgBAIjyKDxAlAsAIEoAAKIEACBKAACiBAAgSgAAogQAIEoAAKIEACBKAACiztqf4Qlv3V4w+2fZP8v+SS4AgCgBAIgSAIAoAQCIEgCAKAEAiBIAgCgBAIgSAIAoAQCIOuuZngDABBcAQJQAAEQJAECUAABECQBAlAAARAkAQJQAAEQJAECUAABECQBAlAAARAkAQJQAAEQJAECUAABECQBAlAAARAkAQJQAAER5FB4gygUAECUAAFECABAlAABRAgAQJQAAUQIAECUAAFECABAlAABRAgAQJQAAUQIAECUAAFECABAlAABRAgAQJQAAUQIAECUAAFEehQeIcgEARAkAQJQAAEQJAECUAABECQBAlAAARAkAQJQAAEQJAEDUWfszPOGt2wtm/6zb99/+XS63f/5373cBAEQJAECUAABECQBAlAAARAkAQJQAAEQJAECUAABECQBA1Ln+P8kB+IkLACBKAACiBAAgSgAAogQAIEoAAKIEACBKAACiBAAgSgAAogQAIEoAAKIEACBKAACiBAAgSgAAogQAIEoAAKIEACBKAACiPAoPEOUCAIgSAIAoAQCIEgCAKAEAiBIAgCgBAIgSAIAoAQCIEgCAKAEAiBIAgCgBAIgSAIAoAQCIEgCAKAEAiBIAgCgBAIgSAIAoj8IDRLkAAKIEACBKAACiBAAgSgAAogQAIEoAAKIEACBKAACiBAAg6qz9nd7w0u0Fs3+W/bPsn+QCAIgSAIAoAQCIEgCAKAEAiBIAgCgBAIgSAIAoAQCIEgCAqLOe6QkATHABAEQJAECUAABECQBAlAAARAkAQJQAAEQJAECUAABECQBAlAAARAkAQJQAAEQJAECUAABECQBAlAAARAkAQJQAAEQJAECUR+EBolwAAFECABAlAABRAgAQJQAAUQIAECUAAFECABAlAABRAgAQJQAAUQIAECUAAFECABAlAABRAgAQJQAAUQIAECUAAFECABDlUXiAKBcAQJQAAEQJAECUAABECQBAlAAARAkAQJQAAEQJAECUAABE/QMG3RnB0DbgjQAAAABJRU5ErkJggg==';
return img;
})()

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -13,6 +13,9 @@ export {default as HSV} from './WebGL/HSV';
export {default as Sepia} from './WebGL/Sepia';
export {default as GreenScreen} from './WebGL/Greenscreen';
export {default as Channels} from './WebGL/Channels';
export {default as GradientMap} from './WebGL/GradientMap';
export {default as ColorLookupTable} from './WebGL/ColorLookupTable';
export {default as Vignette} from './WebGL/Vignette';
// export {default as Blur} from './WebGL/Blur';
// Math
export {default as Numbers} from './Math/Numbers';