How do the pixel shaders work?

This forum is currently in read-only mode.
  • Alrighty, just a quick question for the devs. I'd love to have a 'sharpen' effect, so that what I'm concepting in Photoshop and the game actually match up 100%.

    So I googled around and found this:

    http://www.coniserver.net/wiki/index.php/Shaders

    Seems like there are a bunch of .fx shaders on there - can we reuse that stuff in Construct? I looked into the sharpen.fx file and compared it to the .fx files in Construct and they do seem pretty similar in terms of code, but I have no idea whether they can be made compatible and if so, how.

  • I've been wondering too that how easily do FX from other game engines or games work in Construct

  • Okay, a programmer buddy of mine helped me with this one:

    // Sharpen
    // Bozo Bajozo
    // PS 2.0
    // A simple Sharpen Shader.
    
    //#BORDER-MODE : prevent pixel influence from outside box area.
    
    // Foreground texture
    texture ForegroundTexture;
    
    // Foreground sampler
    sampler2D foreground = sampler_state {
        Texture = (ForegroundTexture);
        MinFilter = Linear;
        MagFilter = Linear;
        MipFilter = Linear;
    };
    
    float pixelWidth;
    float pixelHeight;
    
    // Effect function
    float4 EffectProcess( float2 Tex : TEXCOORD0 ) : COLOR0
    {
    	float strength = 10;
    	float4 Color;
    
    	Color = tex2D( foreground, Tex.xy);
    	Color -= tex2D( foreground, Tex.xy+0.0001)*strength;
    	Color += tex2D( foreground, Tex.xy-0.0001)*strength;
    	
    	Color.a = 1.0;
    
    	return Color;
    }
    
    // ConstructEffect
    technique ConstructEffect
    {
        pass p0
        {
            VertexShader = null;
            PixelShader = compile ps_2_0 EffectProcess();
        }
    }[/code:1om0gxb2]
    
    You can set the strength using the strength value in there.
    
    The problem is that the effect is a different one that Photoshop uses. It makes everything looks kinda embossy, which isn't really what I want.
  • If you want it to look the same, you need to look up the algorithm photoshop uses and reproduce it.

    Some hints:

    • Get rid of the #border-mode line if it looks the same without it, the shader will run faster
    • If you want to get the next adjacent pixel to the lower right, tex2D( foreground, Tex.xy+0.0001) won't do that. Texture coordinates are percentages of the texture size, so you're actually going 0.01% further along the texture which probably isn't what you want. However if you did Tex.xy + float2(pixelWidth, pixelHeight), that's the offset you need to move one pixel.

    If you always move an integer number of pixels along, you can also get rid of linear sampling and use point sampling instead, which runs slightly faster.

  • Okay, so here's the Photoshop version of Sharpen:

    // Sharpen
    // Elvis Presley
    // PS 2.0
    // A simple Sharpen Shader.
    
    //#BORDER-MODE : prevent pixel influence from outside box area.
    
    // Foreground texture
    texture ForegroundTexture;
    
    // Foreground sampler
    sampler2D foreground = sampler_state {
        Texture = (ForegroundTexture);
        MinFilter = Linear;
        MagFilter = Linear;
        MipFilter = Linear;
    };
    
    float pixelWidth;
    float pixelHeight;
    
    // Effect function
    float4 EffectProcess( float2 Tex : TEXCOORD0 ) : COLOR0
    {
    	// Strength should be from 0.0 to 1.0
    	float strength = 0.1;
    	float4 color;
    
    	color = 9.0 * tex2D( foreground, Tex.xy);
    	color -= tex2D( foreground, Tex.xy + float2(pixelWidth, pixelHeight));
    	color -= tex2D( foreground, Tex.xy + float2(0.0, pixelHeight));
    	color -= tex2D( foreground, Tex.xy + float2(-pixelWidth, pixelHeight));
    	color -= tex2D( foreground, Tex.xy + float2(-pixelWidth, 0));
    
    	color -= tex2D( foreground, Tex.xy + float2(-pixelWidth, -pixelHeight));
    	color -= tex2D( foreground, Tex.xy + float2(0, -pixelHeight));
    	color -= tex2D( foreground, Tex.xy + float2(pixelWidth, -pixelHeight));
    	color -= tex2D( foreground, Tex.xy + float2(pixelWidth, 0));
    	color = color * strength + (1.0 - strength) * tex2D( foreground, Tex.xy);
    	color.a = 1.0;
    
    	return color;
    }
    
    // ConstructEffect
    technique ConstructEffect
    {
        pass p0
        {
            VertexShader = null;
            PixelShader = compile ps_2_0 EffectProcess();
        }
    }[/code:qyrrf7dn]
    
    You can set the strengh in there. I set it to 0.1, so that the rendered image looks identical to my concept in Photoshop - you can set it to whatever you want 
    
    Thanks to my buddy Henry Korol for this 
    
    Can we implement this in the next Construct version? Having a sharpen filter is definitely useful
  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • OK, I made a few tweaks like being able to change the strength and supporting transparency:

    // Sharpen
    // Elvis Presley
    // PS 2.0
    // A simple Sharpen Shader.
    
    // Foreground texture
    texture ForegroundTexture;
    
    // Foreground sampler
    sampler2D foreground = sampler_state {
        Texture = (ForegroundTexture);
        MinFilter = Point;
        MagFilter = Point;
        MipFilter = Point;
    };
    
    //#PARAM percent strength 0.1 : Strength : Strength of the effect.
    float strength;
    
    float pixelWidth;
    float pixelHeight;
    
    // Effect function
    float4 EffectProcess( float2 Tex : TEXCOORD0 ) : COLOR0
    {
       float4 color;
    
       color = 9.0 * tex2D( foreground, Tex.xy);
       color -= tex2D( foreground, Tex.xy + float2(pixelWidth, pixelHeight));
       color -= tex2D( foreground, Tex.xy + float2(0.0, pixelHeight));
       color -= tex2D( foreground, Tex.xy + float2(-pixelWidth, pixelHeight));
       color -= tex2D( foreground, Tex.xy + float2(-pixelWidth, 0));
    
       color -= tex2D( foreground, Tex.xy + float2(-pixelWidth, -pixelHeight));
       color -= tex2D( foreground, Tex.xy + float2(0, -pixelHeight));
       color -= tex2D( foreground, Tex.xy + float2(pixelWidth, -pixelHeight));
       color -= tex2D( foreground, Tex.xy + float2(pixelWidth, 0));
       color = color * strength + (1.0 - strength) * tex2D( foreground, Tex.xy);
       //color.a = 1.0;
    
       return color;
    }
    
    // ConstructEffect
    technique ConstructEffect
    {
        pass p0
        {
            VertexShader = null;
            PixelShader = compile ps_2_0 EffectProcess();
        }
    }[/code:akpn529n]
    
    This is in the next build as "sharpen.fx", so you can cut and paste that in and carry on using it in 0.99.
  • Neat! Now Elvis can rest in peace.

    Can anyone look into that scratched film shader? That'd be a nice one to have, Henry told me that it's a bit more complex and involves textures, so can we still use that one in Construct?

    I have no idea what the effect looks like, but it'd be neat to explore. I think David once created something like that using events, but if we can have a simple inheritance layer on top of our layouts and use a canvas object with an fx shader, it'd be super easy to use.

  • Wouldn't mind seeing the toon shader, crystal, or bloom either.

    heck there are lot of nice effects there.

  • They all look fairly easy to convert into shaders.

  • They all look fairly easy to convert into shaders.

    Go right ahead!

  • Tom, if you've got a couple of film grain textures I could have a shot at making a film grain effect. I'm useless with art though. I guess you'd need a bunch of black-and-white textures that have just the film grain pattern on them, then I could use that with an effect to process the background, and switch randomly between the textures to give the effect of frames going by.

  • Ooh this is starting to be interesting!

    And to be honest FX code looks so simple that I could try to learn it a bit to make few FXs ^^ Maybe some day...

  • Tom, if you've got a couple of film grain textures I could have a shot at making a film grain effect. I'm useless with art though. I guess you'd need a bunch of black-and-white textures that have just the film grain pattern on them, then I could use that with an effect to process the background, and switch randomly between the textures to give the effect of frames going by.

    Funny thing is I completed 'Ico' a couple of days ago and figured out today that once you play through it, you get a couple of post processing effects to play around with.

    I think the old film / grain effect works through a couple of layers. You have the grain itself, which just animates randomly (David had something like this set through a simple event in an older cap). Then, you have a couple of burns and stuff - means: black blotches and burnmarks that you barely notice, cause the film runs at 24fps. You do see them, but they're quickly gone again. And then you also see a few light stripes 'walking' from left to right sometimes. I have no idea how they're generated, but my wild guess is that that's just light shining through the roll of film. And then the film also sometimes loses its sharpness - I guess that's because the filmroll is probably moving around slightly while being played - but that's a wild guess again.

    Also, there's vignetting, which means that the sides of the screen gradually become darker and darker.

    Valve has put up a bit of info on what they did for Left 4 Dead on their blog:

    http://www.l4d.com/blog/post.php?id=1962

    Interesting stuff.

    I'll try to come up with a Photoshop composition that has those layers in one simple .psd, so you could play around with it. Another thing that'd certainly help to get this old'ish look would be if we could affect the opacity of a sprite through the sine behavior - So we could let things flicker and fade in / out, etc. randomly.

    Also, have you looked at the fx file they provided on that site? Maybe that effects looks cool enough already?

  • I don't have Photoshop, by the way

  • Film grain should be relatively easy. Using a prerendered texture like this: <img src="http://dl.getdropbox.com/u/666516/noise.png">

    Or even better would be rgb noise generation like what the image manipulator can do, except with an alpha channel.

    Now for the vignette, thats a bit harder as its based on screen size.

    Here is an overlay for a top layer(based on 640x480 screen): http://dl.getdropbox.com/u/666516/vig.png

    Example in gimp:http://dl.getdropbox.com/u/666516/vig.xcf

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)