UNPKG

webgl-lut-filter

Version:

Use WebGL to render image based on LUT filter image

3 lines (2 loc) 3.76 kB
// https://github.com/lijialiang/webgl-lut-filter v1.1.1 !function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(e="undefined"!=typeof globalThis?globalThis:e||self).lutFilter=r()}(this,(function(){"use strict";return function(e){var r=e.canvas,t=e.filterImage,o=e.image;r.width=o.width,r.height=o.height;var a=r.getContext("webgl",{preserveDrawingBuffer:!0});if(null===a)throw new Error("gl null");var n=a.createShader(a.VERTEX_SHADER);if(null===n)throw new Error("VERTEX_SHADER null");a.shaderSource(n,"\nattribute vec4 a_position;\nattribute vec2 a_texCoord;\n\nvarying vec2 v_texCoord;\n\nvoid main() {\n gl_Position = a_position;\n v_texCoord = 1.0 - a_texCoord;\n}\n"),a.compileShader(n),a.getShaderParameter(n,a.COMPILE_STATUS);var i=a.createShader(a.FRAGMENT_SHADER);if(null===i)throw new Error("FRAGMENT_SHADER null");a.shaderSource(i,"\nprecision mediump float;\n\nvarying vec2 v_texCoord;\nuniform sampler2D u_image0;\nuniform sampler2D u_image1;\n\nvoid main() {\n vec4 textureColor = texture2D(u_image0, v_texCoord);\n float blueColor = textureColor.b * 63.0;\n vec2 quad1;\n quad1.y = floor(floor(blueColor) / 8.0);\n quad1.x = floor(blueColor) - (quad1.y * 8.0);\n vec2 quad2;\n quad2.y = floor(ceil(blueColor) / 8.0);\n quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n vec2 texPos1;\n texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);\n texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);\n vec2 texPos2;\n texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);\n texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);\n lowp vec4 newColor1 = texture2D(u_image1, texPos1);\n lowp vec4 newColor2 = texture2D(u_image1, texPos2);\n lowp vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n gl_FragColor = mix(textureColor, vec4(newColor.rgb, textureColor.w), 1.0);\n}\n"),a.compileShader(i),a.getShaderParameter(i,a.COMPILE_STATUS);var E=a.createProgram();if(null===E)throw new Error("program null");a.attachShader(E,n),a.attachShader(E,i),a.linkProgram(E);var T=a.getAttribLocation(E,"a_position"),l=a.getAttribLocation(E,"a_texCoord"),u=a.createBuffer();a.bindBuffer(a.ARRAY_BUFFER,u),a.bufferData(a.ARRAY_BUFFER,new Float32Array([-1,1,-1,-1,1,-1,1,-1,1,1,-1,1]),a.STATIC_DRAW),a.enableVertexAttribArray(T),a.vertexAttribPointer(T,2,a.FLOAT,!1,0,0);var _=a.createBuffer();a.bindBuffer(a.ARRAY_BUFFER,_),a.bufferData(a.ARRAY_BUFFER,new Float32Array([0,1,0,0,1,0,1,0,1,1,0,1]),a.STATIC_DRAW),a.enableVertexAttribArray(l),a.vertexAttribPointer(l,2,a.FLOAT,!1,0,0);var R=a.getUniformLocation(E,"u_image0"),x=a.getUniformLocation(E,"u_image1"),A=a.createTexture();a.bindTexture(a.TEXTURE_2D,A),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_WRAP_S,a.CLAMP_TO_EDGE),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_WRAP_T,a.CLAMP_TO_EDGE),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_MIN_FILTER,a.NEAREST),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_MAG_FILTER,a.NEAREST),a.texImage2D(a.TEXTURE_2D,0,a.RGBA,a.RGBA,a.UNSIGNED_BYTE,o);var d=a.createTexture();a.bindTexture(a.TEXTURE_2D,d),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_WRAP_S,a.CLAMP_TO_EDGE),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_WRAP_T,a.CLAMP_TO_EDGE),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_MIN_FILTER,a.NEAREST),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_MAG_FILTER,a.NEAREST),a.texImage2D(a.TEXTURE_2D,0,a.RGBA,a.RGBA,a.UNSIGNED_BYTE,t),a.clearColor(0,0,0,0),a.clear(a.COLOR_BUFFER_BIT),a.useProgram(E),a.uniform1i(R,0),a.uniform1i(x,1),a.activeTexture(a.TEXTURE0),a.bindTexture(a.TEXTURE_2D,A),a.activeTexture(a.TEXTURE1),a.bindTexture(a.TEXTURE_2D,d),a.drawArrays(a.TRIANGLES,0,6)}}));