ErekT's Forum Posts

  • It works for me now after swapping the NodeWebkit object for nwjs. Curious where the nwJS.UserFolder is at exactly tho. nwJS preview apparently uses its own location too.

  • Wow thanks! It works very nice here

    So I guess the new x_coef and y_coef are necessary for the shader to know what pixel rate to scale by?

    Now I just need to figure out how to get it to blend with the alpha channel as well, so far I just grabbed the original alpha and applied that I should see if I can update it to the newest xBR version too, this one's a bit old I think.

    zenox98:

    You have 'high quality' and 'point sampling' turned on? It should work if you apply the effect to either a layout, layer or object and input the original game res width and height. I just went with the default x_coef/y_coef. Also had to add a 'precision mediump float;' at the top to get it to compile but since you didn't get an error I guess you already took care of that.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Gigatron

    Thanks man I got an xBR shader semi-working with that tool. Very nice.

    Original shader:

    const float coef        = 2.0;
    const vec3  rgbw        = vec3(14.352, 28.176, 5.472);
    
    const   vec2 OGLSize    = vec2( 1024.0, 512.0);
    const   vec2 OGLInvSize = vec2( 0.0009765625, 0.001953125); 
    const   vec2 dx         = vec2( 0.0009765625, 0.0);
    const   vec2 dy         = vec2( 0.0, 0.001953125 );
    const   vec2 x2         = vec2( 0.001953125 , 0.0);
    const   vec2 y2         = vec2( 0.0 , 0.00390625 );
    const   vec4 xy         = vec4( 0.0009765625, 0.001953125,-0.0009765625,-0.001953125);  
    const   vec4 zw         = vec4( 0.001953125 , 0.001953125,-0.001953125 ,-0.00390625 );  
    const   vec4 wz         = vec4( 0.0009765625, 0.00390625 ,-0.0009765625,-0.00390625 );  
    
    vec4 df(vec4 A, vec4 B)
    {
        return abs(A-B);
    }
    
    vec4 weighted_distance(vec4 a, vec4 b, vec4 c, vec4 d, vec4 e, vec4 f, vec4 g, vec4 h)
    {
        return (df(a,b) + df(a,c) + df(d,e) + df(d,f) + 4.0*df(g,h));
    }
    
    uniform sampler2D OGL2Texture;
    
    void main()
    {
        vec4  edr, edr_left, edr_up; bvec4 px; // px = pixel, edr = edge detection rule
        vec4  interp_restriction_lv1, interp_restriction_lv2_left, interp_restriction_lv2_up;
        bvec4 nc; // new_color
        vec4  fx, fx_left, fx_up; // inequations of straight lines.
        
        vec2 fp  = fract(gl_TexCoord[0].xy*OGLSize);
        vec2 TexCoord_0 = gl_TexCoord[0].xy-fp*OGLInvSize;
    
        vec3 A  = texture2D(OGL2Texture, TexCoord_0 + xy.zw ).xyz;
        vec3 B  = texture2D(OGL2Texture, TexCoord_0     -dy ).xyz;
        vec3 C  = texture2D(OGL2Texture, TexCoord_0 + xy.xw ).xyz;
        vec3 D  = texture2D(OGL2Texture, TexCoord_0 - dx    ).xyz;
        vec3 E  = texture2D(OGL2Texture, TexCoord_0         ).xyz;
        vec3 F  = texture2D(OGL2Texture, TexCoord_0 + dx    ).xyz;
        vec3 G  = texture2D(OGL2Texture, TexCoord_0 + xy.zy ).xyz;
        vec3 H  = texture2D(OGL2Texture, TexCoord_0     +dy ).xyz;
        vec3 I  = texture2D(OGL2Texture, TexCoord_0 + xy.xy ).xyz;
        vec3 A1 = texture2D(OGL2Texture, TexCoord_0 + wz.zw ).xyz;
        vec3 C1 = texture2D(OGL2Texture, TexCoord_0 + wz.xw ).xyz;
        vec3 A0 = texture2D(OGL2Texture, TexCoord_0 + zw.zw ).xyz;
        vec3 G0 = texture2D(OGL2Texture, TexCoord_0 + zw.zy ).xyz;
        vec3 C4 = texture2D(OGL2Texture, TexCoord_0 + zw.xw ).xyz;
        vec3 I4 = texture2D(OGL2Texture, TexCoord_0 + zw.xy ).xyz;
        vec3 G5 = texture2D(OGL2Texture, TexCoord_0 + wz.zy ).xyz;
        vec3 I5 = texture2D(OGL2Texture, TexCoord_0 + wz.xy ).xyz;
        vec3 B1 = texture2D(OGL2Texture, TexCoord_0 - y2    ).xyz;
        vec3 D0 = texture2D(OGL2Texture, TexCoord_0 - x2    ).xyz;
        vec3 H5 = texture2D(OGL2Texture, TexCoord_0 + y2    ).xyz;
        vec3 F4 = texture2D(OGL2Texture, TexCoord_0 + x2    ).xyz;
    
        vec4 b  = vec4(dot(B ,rgbw), dot(D ,rgbw), dot(H ,rgbw), dot(F ,rgbw));
        vec4 c  = vec4(dot(C ,rgbw), dot(A ,rgbw), dot(G ,rgbw), dot(I ,rgbw));
        vec4 d  = b.yzwx;
        vec4 e  = vec4(dot(E,rgbw));
        vec4 f  = b.wxyz;
        vec4 g  = c.zwxy;
        vec4 h  = b.zwxy;
        vec4 i  = c.wxyz;
        vec4 i4 = vec4(dot(I4,rgbw), dot(C1,rgbw), dot(A0,rgbw), dot(G5,rgbw));
        vec4 i5 = vec4(dot(I5,rgbw), dot(C4,rgbw), dot(A1,rgbw), dot(G0,rgbw));
        vec4 h5 = vec4(dot(H5,rgbw), dot(F4,rgbw), dot(B1,rgbw), dot(D0,rgbw));
        vec4 f4 = h5.yzwx;
        
        vec4 Ao = vec4( 1.0, -1.0, -1.0, 1.0 );
        vec4 Bo = vec4( 1.0,  1.0, -1.0,-1.0 );
        vec4 Co = vec4( 1.5,  0.5, -0.5, 0.5 );
        vec4 Ax = vec4( 1.0, -1.0, -1.0, 1.0 );
        vec4 Bx = vec4( 0.5,  2.0, -0.5,-2.0 );
        vec4 Cx = vec4( 1.0,  1.0, -0.5, 0.0 );
        vec4 Ay = vec4( 1.0, -1.0, -1.0, 1.0 );
        vec4 By = vec4( 2.0,  0.5, -2.0,-0.5 );
        vec4 Cy = vec4( 2.0,  0.0, -1.0, 0.5 );
        
        // These inequations define the line below which interpolation occurs.
        fx      = vec4(greaterThan(Ao*fp.y+Bo*fp.x,Co));
        fx_left = vec4(greaterThan(Ax*fp.y+Bx*fp.x,Cx)); 
        fx_up   = vec4(greaterThan(Ay*fp.y+By*fp.x,Cy)); 
    
        interp_restriction_lv1      = vec4(notEqual(e,f))*vec4(notEqual(e,h));
        interp_restriction_lv2_left = vec4(notEqual(e,g))*vec4(notEqual(d,g));
        interp_restriction_lv2_up   = vec4(notEqual(e,c))*vec4(notEqual(b,c));
    
        edr      = vec4(lessThan(weighted_distance( e, c, g, i, h5, f4, h, f), weighted_distance( h, d, i5, f, i4, b, e, i)))*interp_restriction_lv1;
        edr_left = vec4(lessThanEqual(coef*df(f,g),df(h,c)))*interp_restriction_lv2_left; 
        edr_up   = vec4(greaterThanEqual(df(f,g),coef*df(h,c)))*interp_restriction_lv2_up;
        
        nc = bvec4 (edr*(max(max(fx, edr_left*fx_left), edr_up*fx_up)));
    
        px = lessThanEqual(df(e,f),df(e,h));
    
        vec3 res = nc.x ? px.x ? F : H : nc.y ? px.y ? B : F : nc.z ? px.z ? D : B : nc.w ? px.w ? H : D : E;    
        gl_FragColor.xyz = res;    
    }[/code:255nvcq0]
    
    Conversion (tinkered around to try and make it work properly):
    fx:
    [code:255nvcq0]#ifdef GL_ES
    precision mediump float;
    #endif
    
    uniform highp float WindowsWidth;
    uniform highp float WindowsHeight;
    
    uniform mediump sampler2D samplerFront;
    varying mediump vec2 vTex;
    uniform mediump float seconds;
    uniform mediump float date;
    uniform mediump float pixelWidth;
    uniform mediump float pixelHeight;
    vec2 iResolution = vec2( 1./pixelWidth, 1./pixelHeight);
    
    const float coef        = 2.0;
    const vec3  rgbw        = vec3(14.352, 28.176, 5.472);
    
    //const vec2 dx         = vec2( 0.0009765625, 0.0);
    //const vec2 dy         = vec2( 0.0, 0.001953125 );
    //const vec2 x2         = vec2( 0.001953125 , 0.0);
    //const vec2 y2         = vec2( 0.0 , 0.00390625 );
    //const vec4 xy         = vec4( 0.0009765625, 0.001953125,-0.0009765625,-0.001953125);  
    //const vec4 zw         = vec4( 0.001953125 , 0.001953125,-0.001953125 ,-0.00390625 );  
    //const vec4 wz         = vec4( 0.0009765625, 0.00390625 ,-0.0009765625,-0.00390625 );  
    
    vec4 df(vec4 A, vec4 B)
    {
        return abs(A-B);
    }
    
    vec4 weighted_distance(vec4 a, vec4 b, vec4 c, vec4 d, vec4 e, vec4 f, vec4 g, vec4 h)
    {
        return (df(a,b) + df(a,c) + df(d,e) + df(d,f) + 4.0*df(g,h));
    }
    
    void main()
    {
    //	float x = 0.5 * (1.0 / WindowsWidth);
    //	float y = 0.5 * (1.0 / WindowsHeight);
    
    	vec2 dx         = vec2( 0.0009765625, 0.0);//vec2(x, 0.0);//
    	vec2 dy         = vec2( 0.0, 0.001953125 );//vec2(0.0, y);//
    	vec2 x2         = vec2( 0.001953125 , 0.0);//vec2(y, 0);//
    	vec2 y2         = vec2(0.0, 0.00390625);//vec2( 0.0 , y*2.0 );//
    	vec4 xy         = vec4( 0.0009765625, 0.001953125,-0.0009765625,-0.001953125);//vec4( x, y,-x,-y);//  
    	vec4 zw         = vec4( 0.001953125 , 0.001953125,-0.001953125 ,-0.00390625 );//vec4( y , y,-y ,-(y*2.0) );//  
    	vec4 wz         = vec4( 0.0009765625, 0.00390625 ,-0.0009765625,-0.00390625 );  //vec4( x, y*2.0 ,-x,-(y*2.0) );//
    
        vec4  edr, edr_left, edr_up; bvec4 px; // px = pixel, edr = edge detection rule
        vec4  interp_restriction_lv1, interp_restriction_lv2_left, interp_restriction_lv2_up;
        bvec4 nc; // new_color
        vec4  fx, fx_left, fx_up; // inequations of straight lines.
        
    	lowp float alpha = texture2D(samplerFront, vTex).a;
    
        vec2 fp  = fract(vTex.xy*vec2(WindowsWidth,WindowsHeight));
        vec2 TexCoord_0 = vTex.xy-fp*vec2(0.0009765625, 0.001953125);//vec2(x, y);
    
        vec3 A  = texture2D(samplerFront, TexCoord_0 + xy.zw ).xyz;
        vec3 B  = texture2D(samplerFront, TexCoord_0     -dy ).xyz;
        vec3 C  = texture2D(samplerFront, TexCoord_0 + xy.xw ).xyz;
        vec3 D  = texture2D(samplerFront, TexCoord_0 - dx    ).xyz;
        vec3 E  = texture2D(samplerFront, TexCoord_0         ).xyz;
        vec3 F  = texture2D(samplerFront, TexCoord_0 + dx    ).xyz;
        vec3 G  = texture2D(samplerFront, TexCoord_0 + xy.zy ).xyz;
        vec3 H  = texture2D(samplerFront, TexCoord_0     +dy ).xyz;
        vec3 I  = texture2D(samplerFront, TexCoord_0 + xy.xy ).xyz;
        vec3 A1 = texture2D(samplerFront, TexCoord_0 + wz.zw ).xyz;
        vec3 C1 = texture2D(samplerFront, TexCoord_0 + wz.xw ).xyz;
        vec3 A0 = texture2D(samplerFront, TexCoord_0 + zw.zw ).xyz;
        vec3 G0 = texture2D(samplerFront, TexCoord_0 + zw.zy ).xyz;
        vec3 C4 = texture2D(samplerFront, TexCoord_0 + zw.xw ).xyz;
        vec3 I4 = texture2D(samplerFront, TexCoord_0 + zw.xy ).xyz;
        vec3 G5 = texture2D(samplerFront, TexCoord_0 + wz.zy ).xyz;
        vec3 I5 = texture2D(samplerFront, TexCoord_0 + wz.xy ).xyz;
        vec3 B1 = texture2D(samplerFront, TexCoord_0 - y2    ).xyz;
        vec3 D0 = texture2D(samplerFront, TexCoord_0 - x2    ).xyz;
        vec3 H5 = texture2D(samplerFront, TexCoord_0 + y2    ).xyz;
        vec3 F4 = texture2D(samplerFront, TexCoord_0 + x2    ).xyz;
    
        vec4 b  = vec4(dot(B ,rgbw), dot(D ,rgbw), dot(H ,rgbw), dot(F ,rgbw));
        vec4 c  = vec4(dot(C ,rgbw), dot(A ,rgbw), dot(G ,rgbw), dot(I ,rgbw));
        vec4 d  = b.yzwx;
        vec4 e  = vec4(dot(E,rgbw));
        vec4 f  = b.wxyz;
        vec4 g  = c.zwxy;
        vec4 h  = b.zwxy;
        vec4 i  = c.wxyz;
        vec4 i4 = vec4(dot(I4,rgbw), dot(C1,rgbw), dot(A0,rgbw), dot(G5,rgbw));
        vec4 i5 = vec4(dot(I5,rgbw), dot(C4,rgbw), dot(A1,rgbw), dot(G0,rgbw));
        vec4 h5 = vec4(dot(H5,rgbw), dot(F4,rgbw), dot(B1,rgbw), dot(D0,rgbw));
        vec4 f4 = h5.yzwx;
        
        vec4 Ao = vec4( 1.0, -1.0, -1.0, 1.0 );
        vec4 Bo = vec4( 1.0,  1.0, -1.0,-1.0 );
        vec4 Co = vec4( 1.5,  0.5, -0.5, 0.5 );
        vec4 Ax = vec4( 1.0, -1.0, -1.0, 1.0 );
        vec4 Bx = vec4( 0.5,  2.0, -0.5,-2.0 );
        vec4 Cx = vec4( 1.0,  1.0, -0.5, 0.0 );
        vec4 Ay = vec4( 1.0, -1.0, -1.0, 1.0 );
        vec4 By = vec4( 2.0,  0.5, -2.0,-0.5 );
        vec4 Cy = vec4( 2.0,  0.0, -1.0, 0.5 );
        vec4 Ci = vec4(0.25, 0.25, 0.25, 0.25);
        
        // These inequations define the line below which interpolation occurs.
        fx      = vec4(greaterThan(Ao*fp.y+Bo*fp.x,Co));
        fx_left = vec4(greaterThan(Ax*fp.y+Bx*fp.x,Cx)); 
        fx_up   = vec4(greaterThan(Ay*fp.y+By*fp.x,Cy)); 
    
        interp_restriction_lv1      = vec4(notEqual(e,f))*vec4(notEqual(e,h));
        interp_restriction_lv2_left = vec4(notEqual(e,g))*vec4(notEqual(d,g));
        interp_restriction_lv2_up   = vec4(notEqual(e,c))*vec4(notEqual(b,c));
    
        edr      = vec4(lessThan(weighted_distance( e, c, g, i, h5, f4, h, f), weighted_distance( h, d, i5, f, i4, b, e, i)))*interp_restriction_lv1;
        edr_left = vec4(lessThanEqual(coef*df(f,g),df(h,c)))*interp_restriction_lv2_left; 
        edr_up   = vec4(greaterThanEqual(df(f,g),coef*df(h,c)))*interp_restriction_lv2_up;
        
        nc = bvec4 (edr*(max(max(fx, edr_left*fx_left), edr_up*fx_up)));
    
        px = lessThanEqual(df(e,f),df(e,h));
    
        vec3 res = nc.x ? px.x ? F : H : nc.y ? px.y ? B : F : nc.z ? px.z ? D : B : nc.w ? px.w ? H : D : E;    
        gl_FragColor.xyz = res;    
    	gl_FragColor.a = alpha;
    }[/code:255nvcq0]
    xml:
    [code:255nvcq0]<?xml version="1.0" encoding="UTF-8" ?>
    <c2effect>
    	<!-- About -->
    	<id>XBR</id>			<!-- Never change the ID.  Change the name instead -->
    	<name>xBR</name>
    	<category>Advanced Effect Layout</category>
    	<description>Use this effect on individual sprites or the whole layout. Based on code by Hyllian and Anata</description>
    	<author>Hyllian</author>
    	
    	<!-- Settings -->
    	
    	<!-- Extend the bounding box for effect processing by a number of pixels to show the edges
    		 of effects which go beyond the object edges, e.g. blur and warp. -->
    	<extend-box-horizontal>10</extend-box-horizontal>
    	<extend-box-vertical>10</extend-box-vertical>
    	
    	<!-- Set to true if the background is sampled (samplerBack is referenced at all in the shader) -->
    	<blends-background>false</blends-background>
    	
    	<!-- Set to true if the background is not sampled at 1:1 with the foreground (e.g. the
    		 background texture co-ordinates are modified in some way by the shader, as done
    		 by Glass and Lens) -->
    	<cross-sampling>false</cross-sampling>
    	
    	<!-- Set to true if the effect changes over time, e.g. Noise or Warp effects. -->
    	<animated>false</animated>
    	
    	<!-- Parameters -->
    	<parameters>
    		<param>
    			<name>Width</name>
    			<description>Destination X</description>
    			<type>float</type>
    			<initial>0</initial>
    			<uniform>WindowsWidth</uniform>
    		</param>
    		<param>
    			<name>Height</name>
    			<description>Destination Y</description>
    			<type>float</type>
    			<initial>0</initial>
    			<uniform>WindowsHeight</uniform>
    		</param>
    	</parameters>
    </c2effect>[/code:255nvcq0]
    
    Use it on a layout and input the game target resolution in the Width and Height fields. So far it'll smooth along one angle but not the other. And no luck yet getting it to work properly on an object basis.
    
    EDIT:
    Posted the wrong shader, fixed now
  • You use "Families" extensively yes?

    Um... no?

    Do you mean I could use families as sort of a proxy to avoid tying events to objects directly?

  • ErekT Tell me about your #1. How would you use this?

    Sometimes I need to replace an object, but if it's tied to a lot of event code the only way, that I know of at least, is to redo all those events for the replacement object manually. Very tedious.

  • Good suggestions! I'll add a couple from my preference list:

    1)

    Option to keep events that reference a null object, and retarget object references in events.

    2)

    Sprite atlas support in the editor.

    I'd be a happy man if these made it in and I'd gladly pay 300$ or more for them.

  • 0.13 seems to have worse webgl performance than 0.12, my intel iris could handle 0.12 fine but now there's stutter.

  • I messed around in package and package-win.json quite a bit with nothing happening. Not a sausage. But then I remembered; my project uses the node-webkit object and not the nwjs object! They're functionally identical as far as I know but only nwjs will access package-win.json in the nwjs folder obviously. Hoo man. Now it works.

    Thanks for all the help

  • I'm already using it :-/

    This is what I get before going fullscreen:

    ... and this is The Next Penelope using a custom res:

  • Hmm, I tried changing width and height in the different json files but it didn't make a difference. Good guess tho, thanks I think I'll try to contact the guy who made Last Penelope next and ask how he did it.

  • Yeah, for a split second there I see a window that then gets blown up to fullscreen. Ideally I'd like to have it run at fullscreen immediately but I know there's a way to customize the resolution for that loader window too. I've seen it done before in the C2 game The Last Penelope. Thanks for helping out btw

  • Oh okay, so the loader window is supposed to be set to Window Size from the project settings? That's not what's happening here. I have fullscreen set to Letterbox Scale but the runtime still starts out in a small window until it's finished loading. And yep, I want it to start in fullscreen right away.

  • Yeah the initial loader window is set to something like 350x280 resolution and then when the loader layout starts out the game goes fullscreen like it's supposed to. That's normal behaviour right?

  • Like the title says, I need to change the default loader window size to a higher resolution. It's possible, I just don't know how. Something in index.html or c2runtime.js maybe? Help?

  • Thanks a bunch for that It's interesting to see how you structure things by breaking them up into separate functions.

    I made some progress with my own conversion as well. It doesn't blend with the background like it should and there's some hefty artifacting going on, but it's a start.

    Gigatron:

    ErekT:

    There's also some kind of interpolation weirdness in both our conversions (mine especially) that needs addressing.

    Finally, if I want to assign the shader to a separate layer that affects everything underneath I need to read from samplerBack, do shader magic to it, and then write the result to samplerFront which represents the layer in question. Right?

    /////////////////////////////////////////////////////////
    // FXAA effect
    
    #ifndef FXAA_REDUCE_MIN
        #define FXAA_REDUCE_MIN   (1.0/ 128.0)
    #endif
    #ifndef FXAA_REDUCE_MUL
        #define FXAA_REDUCE_MUL   (1.0 / 8.0)
    #endif
    #ifndef FXAA_SPAN_MAX
        #define FXAA_SPAN_MAX     8.0
    #endif
    
    precision lowp float;
    
    varying mediump vec2 vTex;
    uniform lowp sampler2D samplerFront;
    uniform lowp sampler2D samplerBack;
    uniform mediump vec2 destStart;
    uniform mediump vec2 destEnd;
    
    uniform highp float WindowsWidth;
    uniform highp float WindowsHeight;
    
    void main(void)
    {
        lowp vec4 front = texture2D(samplerFront, vTex);
        lowp vec4 back = texture2D(samplerBack, mix(destStart, destEnd, vTex));
    
        mediump vec2 resolution = vec2(WindowsWidth, WindowsHeight);
        mediump vec2 inverseVP = vec2(1.0 / WindowsWidth, 1.0 / WindowsHeight);
        vec3 rgbNW = texture2D(samplerFront, vTex + (vec2(-1.0,-1.0)/resolution)).xyz;
        vec3 rgbNE = texture2D(samplerFront, vTex + (vec2(1.0,-1.0)/resolution)).xyz;
        vec3 rgbSW = texture2D(samplerFront, vTex + (vec2(-1.0,1.0)/resolution)).xyz;
        vec3 rgbSE = texture2D(samplerFront, vTex + (vec2(1.0,1.0)/resolution)).xyz;
        vec3 rgbM  = texture2D(samplerFront, vTex).xyz;
    
        vec3 luma = vec3(0.299, 0.587, 0.114);
        float lumaNW = dot(rgbNW, luma);
        float lumaNE = dot(rgbNE, luma);
        float lumaSW = dot(rgbSW, luma);
        float lumaSE = dot(rgbSE, luma);
        float lumaM  = dot(rgbM,  luma);
    
        float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
        float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
        
        mediump vec2 dir;
        dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
        dir.y =  ((lumaNW + lumaSW) - (lumaNE + lumaSE));
        
        float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
                              (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
        
        float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
        dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
                  max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
                  dir * rcpDirMin)) / resolution;
        
        vec3 rgbA = 0.5 * ( 
    	texture2D(samplerFront, vTex + dir * (1.0 / 3.0 - 0.5)).xyz +
            texture2D(samplerFront, vTex + dir * (2.0 / 3.0 - 0.5)).xyz);
        vec3 rgbB = rgbA * 0.5 + 0.25 * (
            texture2D(samplerFront, vTex + dir * -0.5).xyz +
            texture2D(samplerFront, vTex + dir * 0.5).xyz);
    
        float lumaB = dot(rgbB, luma);
        if((lumaB < lumaMin) || (lumaB > lumaMax))
            gl_FragColor.xyz=rgbA;
        else
            gl_FragColor.xyz=rgbB;
    
    }
    [/code:1rpu4wdf]