From 37e1d9f3a1fd45352935662b8941f387c98a8bde Mon Sep 17 00:00:00 2001 From: Stanislav Fifik Date: Wed, 11 Dec 2019 15:19:35 +0100 Subject: [PATCH] :sparkles: Lookuptable GradientMap Vignette --- src/nodes/Node.ts | 13 ++++- src/nodes/WebGL/ColorLookupTable.ts | 75 ++++++++++++++++++++++++++++ src/nodes/WebGL/GradientMap.ts | 54 ++++++++++++++++++++ src/nodes/WebGL/Tint.ts | 2 +- src/nodes/WebGL/Vignette.ts | 57 +++++++++++++++++++++ src/nodes/WebGL/WebGl.ts | 48 ++++++++++++++---- src/nodes/WebGL/assets/index.ts | 5 ++ src/nodes/WebGL/assets/lookup.png | Bin 0 -> 2095 bytes src/nodes/index.ts | 3 ++ 9 files changed, 244 insertions(+), 13 deletions(-) create mode 100644 src/nodes/WebGL/ColorLookupTable.ts create mode 100644 src/nodes/WebGL/GradientMap.ts create mode 100644 src/nodes/WebGL/Vignette.ts create mode 100644 src/nodes/WebGL/assets/index.ts create mode 100644 src/nodes/WebGL/assets/lookup.png diff --git a/src/nodes/Node.ts b/src/nodes/Node.ts index 4b83575..ccf0abf 100644 --- a/src/nodes/Node.ts +++ b/src/nodes/Node.ts @@ -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 { name: string @@ -70,19 +74,24 @@ export default class Node { } /** - * 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, diff --git a/src/nodes/WebGL/ColorLookupTable.ts b/src/nodes/WebGL/ColorLookupTable.ts new file mode 100644 index 0000000..29ee49a --- /dev/null +++ b/src/nodes/WebGL/ColorLookupTable.ts @@ -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 { + + 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); + } +} \ No newline at end of file diff --git a/src/nodes/WebGL/GradientMap.ts b/src/nodes/WebGL/GradientMap.ts new file mode 100644 index 0000000..cc73449 --- /dev/null +++ b/src/nodes/WebGL/GradientMap.ts @@ -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 { + + 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); + } +} \ No newline at end of file diff --git a/src/nodes/WebGL/Tint.ts b/src/nodes/WebGL/Tint.ts index 8e35180..62b7264 100644 --- a/src/nodes/WebGL/Tint.ts +++ b/src/nodes/WebGL/Tint.ts @@ -10,7 +10,7 @@ const inputs = { } as NumberVar, } -export default class Sepia extends WebGL { +export default class Tint extends WebGL { constructor() { super('Tint', inputs) diff --git a/src/nodes/WebGL/Vignette.ts b/src/nodes/WebGL/Vignette.ts new file mode 100644 index 0000000..a73ffb9 --- /dev/null +++ b/src/nodes/WebGL/Vignette.ts @@ -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 { + + 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); + } +} \ No newline at end of file diff --git a/src/nodes/WebGL/WebGl.ts b/src/nodes/WebGL/WebGl.ts index 6b5693a..58f0488 100644 --- a/src/nodes/WebGL/WebGl.ts +++ b/src/nodes/WebGL/WebGl.ts @@ -149,6 +149,30 @@ export default class WebGL extends Node>this.in[inputName].value)); + } + } + return textures; + } + _createFrameBuffer(gl: WebGLRenderingContext, {width, height}) { const texture = this.createTexture(gl); @@ -175,8 +199,7 @@ export default class WebGL extends Node extends Node extends Node>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 extends Node { + 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; +})() \ No newline at end of file diff --git a/src/nodes/WebGL/assets/lookup.png b/src/nodes/WebGL/assets/lookup.png new file mode 100644 index 0000000000000000000000000000000000000000..ed814dfbb648c1f43d737c302f94aa8ca04c27e9 GIT binary patch literal 2095 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&t&wwUqN(AjMqlVtXr>wlMb-ud_Qw*BjO ze~Hm~{lB_BgMA?*g9|5v!xRR}DEEhqi(+tvF~0D}kb4?f(V!tt*hO=GD0;j2 znSYTWPfsGk_H$Ls)ENv8vf{}B7%_k|ugJBscNEbzy_8=2=a*mc@>|nQ`_n*A`x9aN zmB{m7SQylHP?rCo*_YUCNX7JW?$-Q=ocVX-41TABJnczDYPEVja~{J179uhY5jnk5 zL{8xpUDL~z$lt~`57*x2PW!*+_V@e$V)eGy|0{oAPB^7q+4;}@B;$`xA~FIIMKY1u zkeEt>$co_An!j`JeYo_Nbu+L8+x%w!6JiR1c`rE`d