phaser4-rex-plugins
Version:
2 lines (1 loc) • 8.7 kB
JavaScript
var e,t;e=void 0,t=function(){const e="rexFilterToonify";class t extends Phaser.Renderer.WebGL.RenderNodes.BaseFilterShader{static FilterName=e;constructor(t){super(e,t,null,"#pragma phaserTemplate(shaderName)\n\n#ifdef GL_FRAGMENT_PRECISION_HIGH\n#define highmedp highp\n#else\n#define highmedp mediump\n#endif\nprecision highmedp float;\n\n// Scene buffer\nuniform sampler2D uMainSampler; \nvarying vec2 outTexCoord;\nuniform vec2 texSize;\n\n// Effect parameters\nuniform float edgeThreshold; // 0.2;\nuniform vec3 hsvStep;\nuniform vec3 edgeColor; // (0, 0, 0);\nvec3 RGBToHSV(vec3 color) {\n float minv, maxv, delta;\n vec3 res;\n minv = min(min(color.r, color.g), color.b);\n maxv = max(max(color.r, color.g), color.b);\n res.z = maxv; // v\n\n delta = maxv - minv;\n if( maxv != 0.0 ) {\n res.y = delta / maxv; // s\n } else {\n // s = 0, v is undefined\n res.y = 0.0;\n res.x = -1.0;\n return res;\n }\n\n if( color.r == maxv ) {\n res.x = ( color.g - color.b ) / delta; // between yellow & magenta\n } else if( color.g == maxv ) {\n res.x = 2.0 + ( color.b - color.r ) / delta; // between cyan & yellow\n } else {\n res.x = 4.0 + ( color.r - color.g ) / delta; // between magenta & cyan\n }\n\n res.x = res.x * 60.0; // degrees\n if( res.x < 0.0 ) {\n res.x = res.x + 360.0;\n }\n \n return res;\n}\nfloat AvgRGB(vec4 color) {\n return (color.r + color.g + color.b)/3.0;\n}\n#define EDGEGAIN 5.0\nbool IsEdge(vec2 coords, vec2 texSize, float threshold) {\n if (threshold > 1.0) {\n return false;\n }\n\n vec2 tc = coords * texSize;\n \n float pixel[9];\n int k = 0;\n float delta;\n\n // read neighboring pixel intensities\n pixel[0] = AvgRGB( texture2D( uMainSampler, (tc + vec2(float(-1), float(-1))) / texSize ) );\n pixel[1] = AvgRGB( texture2D( uMainSampler, (tc + vec2(float(-1), float( 0))) / texSize ) );\n pixel[2] = AvgRGB( texture2D( uMainSampler, (tc + vec2(float(-1), float( 1))) / texSize ) );\n pixel[3] = AvgRGB( texture2D( uMainSampler, (tc + vec2(float( 0), float(-1))) / texSize ) );\n pixel[4] = AvgRGB( texture2D( uMainSampler, (tc + vec2(float( 0), float( 0))) / texSize ) );\n pixel[5] = AvgRGB( texture2D( uMainSampler, (tc + vec2(float( 0), float( 1))) / texSize ) );\n pixel[6] = AvgRGB( texture2D( uMainSampler, (tc + vec2(float( 1), float(-1))) / texSize ) );\n pixel[7] = AvgRGB( texture2D( uMainSampler, (tc + vec2(float( 1), float( 0))) / texSize ) );\n pixel[8] = AvgRGB( texture2D( uMainSampler, (tc + vec2(float( 1), float( 1))) / texSize ) );\n\n // average color differences around neighboring pixels\n delta = (abs(pixel[1]-pixel[7])+\n abs(pixel[5]-pixel[3]) +\n abs(pixel[0]-pixel[8])+\n abs(pixel[2]-pixel[6])\n )/4.0;\n\n return (clamp(delta*EDGEGAIN, 0.0, 1.0) >= threshold);\n}\nvec3 HSVToRGB(float h, float s, float v) {\n int i;\n float f, p, q, t;\n vec3 res;\n if( s == 0.0 ) {\n // achromatic (grey)\n res.x = v;\n res.y = v;\n res.z = v;\n return res;\n }\n\n h /= 60.0; // sector 0 to 5\n i = int(floor( h ));\n f = h - float(i); // factorial part of h\n p = v * ( 1.0 - s );\n q = v * ( 1.0 - s * f );\n t = v * ( 1.0 - s * ( 1.0 - f ) ); \n if (i == 0) {\n res.x = v;\n res.y = t;\n res.z = p;\n } else if (i == 1) {\n res.x = q;\n res.y = v;\n res.z = p;\n } else if (i == 2) {\n res.x = p;\n res.y = v;\n res.z = t;\n } else if (i == 3) {\n res.x = p;\n res.y = q;\n res.z = v;\n } else if (i == 4) {\n res.x = t;\n res.y = p;\n res.z = v;\n } else { // i == 5\n res.x = v;\n res.y = p;\n res.z = q;\n }\n return res;\n}\n\n#pragma phaserTemplate(fragmentHeader)\n\nvoid main() {\n float hStep = hsvStep.x;\n float sStep = hsvStep.y;\n float vStep = hsvStep.z;\n\n vec4 front = texture2D(uMainSampler, outTexCoord); \n vec3 colorLevel;\n if ((hStep > 0.0) || (sStep > 0.0) || (vStep > 0.0)) {\n vec3 colorHsv = RGBToHSV(front.rgb); \n if (hStep > 0.0) {\n colorHsv.x = min(floor((colorHsv.x / hStep) + 0.5) * hStep, 360.0);\n }\n if (sStep > 0.0) {\n colorHsv.y = min(floor((colorHsv.y / sStep) + 0.5) * sStep, 1.0);\n }\n if (vStep > 0.0) {\n colorHsv.z = min(floor((colorHsv.z / vStep) + 0.5) * vStep, 1.0);\n }\n colorLevel = HSVToRGB(colorHsv.x, colorHsv.y, colorHsv.z);\n } else {\n colorLevel = front.rgb;\n }\n\n vec3 outColor = (IsEdge(outTexCoord, texSize, edgeThreshold))? edgeColor : colorLevel;\n gl_FragColor = vec4(outColor, front.a);\n}\n")}setupUniforms(e,t){const n=this.programManager;n.setUniform("edgeThreshold",e.edgeThreshold),n.setUniform("hsvStep",[e.hueStep,e.satStep,e.valStep]),n.setUniform("edgeColor",[e._edgeColor.redGL,e._edgeColor.greenGL,e._edgeColor.blueGL]),n.setUniform("texSize",[t.width,t.height])}}const n=Phaser.Utils.Objects.GetValue,r=Phaser.Display.Color.IntegerToRGB,s=Phaser.Display.Color;class o extends Phaser.Filters.Controller{static FilterName=e;constructor(t,n){super(t,e),this.edgeThreshold=0,this.hueLevels=0,this._satLevels=0,this._valLevels=0,this._edgeColor=new s,this.resetFromJSON(n)}resetFromJSON(e){return this.setEdgeThreshold(n(e,"edgeThreshold",.2)),this.setHueLevels(n(e,"hueLevels",0)),this.setSatLevels(n(e,"satLevels",0)),this.setValLevels(n(e,"valLevels",0)),this.setEdgeColor(n(e,"edgeColor",0)),this}setEdgeThreshold(e){return this.edgeThreshold=e,this}setHueLevels(e){return this.hueLevels=e,this}get hueStep(){return this.hueLevels>0?360/this.hueLevels:0}get satLevels(){return this._satLevels}set satLevels(e){this._satLevels=e}setSatLevels(e){return this.satLevels=e,this}get satStep(){return this._satLevels>0?1/this._satLevels:0}get valLevels(){return this._valLevels}set valLevels(e){this._valLevels=e}setValLevels(e){return this.valLevels=e,this}get valStep(){return this._valLevels>0?1/this._valLevels:0}get edgeColor(){return this._edgeColor}set edgeColor(e){"number"==typeof e&&(e=r(e)),this._edgeColor.setFromRGB(e)}setEdgeColor(e){return this.edgeColor=e,this}}const l=Phaser.Game;var i=function(e){return e instanceof l};const a=Phaser.Scene;var v=function(e){return e instanceof a},f=function(e,t){var n,r=t.FilterName,s=(n=e,null==n||"object"!=typeof n?null:i(n)?n:i(n.game)?n.game:v(n)?n.sys.game:v(n.scene)?n.scene.sys.game:void 0).renderer.renderNodes;return!s.hasNode(r)&&(s.addNodeConstructor(r,t),!0)},h=function(e,t){return void 0===t&&(t=!1),e.filters||e.enableFilters().focusFilters(),t?e.filters.external:e.filters.internal};const c=Phaser.Utils.Array.SpliceOne;class u extends Phaser.Plugins.BasePlugin{setFilterClass(e,t){return this.FilterClass=e,this.ControllerClass=t,this}setFilterListMethod(e,t){return function(e,t){var n=Phaser.GameObjects.Components.FilterList.prototype;n[e]||(n[e]=t)}(e,t),this}start(){var e=this.game.events;e.once("destroy",this.destroy,this),this.game.isRunning?f(this.game,this.FilterClass):e.once("ready",(function(){f(this.game,this.FilterClass)}),this)}add(e,t,n=!1){return function(e,t,n,r){void 0===n&&(n={});var s=h(e,r),o=s.add(new t(s.camera,n));return n.name&&(o.name=n.name),o}(e,this.ControllerClass,t,n)}remove(e,t,n=!1){return function(e,t,n,r){var s=h(e,r).list;if(void 0===n)for(var o=s.length-1;o>=0;o--)(i=s[o])instanceof t&&(i.destroy(),c(i,o));else{o=0;for(var l=s.length;o<l;o++){var i;(i=s[o])instanceof t&&i.name===n&&(i.destroy(),c(i,o))}}}(e,this.ControllerClass,t,n),this}get(e,t,n=!1){return function(e,t,n,r){var s=h(e,r).list;if(void 0===n){for(var o=[],l=0,i=s.length;l<i;l++)(a=s[l])instanceof t&&o.push(a);return o}for(l=0,i=s.length;l<i;l++){var a;if((a=s[l])instanceof t&&a.name===n)return a}}(e,this.ControllerClass,t,n)}}var d=function(e){return null==e||""===e||0===e.length},p=function(e,t,n,r){if(void 0===r&&(r="."),"object"==typeof e){if(d(t)){if(null==n)return;"object"==typeof n&&(e=n)}else{"string"==typeof t&&(t=t.split(r));var s=t.pop(),o=function(e,t,n){var r=e;if(d(t));else{var s;"string"==typeof t&&(t=t.split("."));for(var o=0,l=t.length;o<l;o++){var i;null!=r[s=t[o]]&&"object"==typeof r[s]||(i=o===l-1?void 0===n?{}:n:{},r[s]=i),r=r[s]}}return r}(e,t);o[s]=n}return e}};return p(window,"RexPlugins.Filters.ToonifyFilter",t),p(window,"RexPlugins.Filters.ToonifyController",o),class extends u{constructor(e){super(e),this.setFilterClass(t,o),this.setFilterListMethod("addRexToonify",(function(e){return this.add(new o(this.camera,e))}))}}},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).rextoonifyfilterplugin=t();