PhotoFilter Shader

Hey,

I am working on a simple shader for my game, a photofilter. I mean photofilter as in the sense of Photoshop. Example: https://news.dphotographer.co.uk/wp-content/uploads/2013/02/main-DP-art.jpg

It mainly overlays a solid color over the entire image. It is coloring everything great but I think I am having an issue with alpha? The transparent pixels in the image are being colored. I want them to continue to be transparent yet. Where am I going wrong?

Thanks in advance!

#if OPENGL
#define SV_POSITION POSITION
#define VS_SHADERMODEL vs_3_0
#define PS_SHADERMODEL ps_3_0
#else
#define VS_SHADERMODEL vs_4_0_level_9_1
#define PS_SHADERMODEL ps_4_0_level_9_1
#endif

Texture2D SpriteTexture;

sampler2D SpriteTextureSampler = sampler_state
{
	Texture = <SpriteTexture>;
};

float4 ColorR;
float4 ColorG;
float4 ColorB;
float4 ColorA;


float4 MainPS(float4 pos : SV_POSITION, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : SV_TARGET0
{

    float4 color = tex2D(SpriteTextureSampler, coords)* color1;
 
    float4 outputColor = color;
    outputColor.r = (color.r + ColorR) / 2;
    outputColor.g = (color.g + ColorG) / 2;  
    outputColor.b = (color.b + ColorB) / 2;
    outputColor.a = (color.a + ColorA) / 2;
 
    return outputColor;
}

technique Desaturate
{
	pass Pass1
	{
		//PixelShader = compile PS_SHADERMODEL MainPS();
		PixelShader = compile PS_SHADERMODEL MainPS();
	}
};

Transparent pixels will still have their RGB set, but if you are alpha blending, and A is 0 or a very low value, then, well, you wont see them…

Thanks. I tried it but it didn’t work. I even ignored the alpha all together because it was originally set to 0, so just leave it, it still was colored.

I am using AlphaBlend. It is so strange because my grayscale and sepia shaders do not manipulate the transparency, just this one.

I hate fx files so much… the lack of good documentation is the worst.

David

How are you setting the alpha blending?

In the Spritebatch. The next batch uses the CachedRenderer and has a AlphaTestEffect applied for stenciling. It works fine for my other fx which is why I am scratching my head. Watch, lol, it is probably something simple I am just overlooking.

        SpriteBatch.SetRenderTarget(CachedRenderer);
        SpriteBatch.Begin(
            blendState: BlendState.AlphaBlend,
            samplerState: SamplerState.PointClamp,
            effect: PhotoFilterEffect,
            transformMatrix: Camera.GetChunkViewMatrix()
        );

Rather than BlendState.AlphaBlend, try BelndState.NonPremultiplied?

Or try adding

if (color.a<0.1)
     discard;

Which will skip pixels whose alpha value in the texture is less than 0.1

@Charles_Humphrey, ah that was close. It fixed the transparency but caused overlapping images to bleed through.

@Stainless, that worked perfectly and while using AlphaBlend yet.

Thanks everyone for your help. I’ll share my current shader code here to help others in the future.

EDIT: Updated the shader, now will evenly photo colorize the image.
Using: BlendState.AlphaBlend
Variable Brightness: YourEffect.Parameters[“Brightness”].SetValue(2f);
Variable RGB: YourEffect.Parameters[“RGB”].SetValue(Color.Red.ToVector3());

#if OPENGL
#define SV_POSITION POSITION
#define VS_SHADERMODEL vs_3_0
#define PS_SHADERMODEL ps_3_0
#else
#define VS_SHADERMODEL vs_4_0_level_9_1
#define PS_SHADERMODEL ps_4_0_level_9_1
#endif

Texture2D SpriteTexture;

sampler2D SpriteTextureSampler = sampler_state
{
	Texture = <SpriteTexture>;
};


float3 RGB;
float Brightness;

float4 MainPS(float4 pos : SV_POSITION, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : SV_TARGET0
{
    float4 color = tex2D(SpriteTextureSampler, coords)* color1;
    float4 grayscale = color;
    grayscale.rgb = ((color.r + color.g + color.b) / 3.0f) * Brightness;
    if (color.a<0.1)
        discard;
    return float4(RGB, color.a) * grayscale;
}

technique PhotoFilter
{
	pass Pass1
	{
		PixelShader = compile PS_SHADERMODEL MainPS();
	}
};
1 Like

Just curious does anyone know of any documentation for FX files? Like where it would state what built-in functions exist like: dot(), saturate(), etc… It is always a struggle to figure out what is available to use.

Thanks,
David

Yea, on my phone at the moment but will get you some links in the morning.

Sorry, got totaly distracted lol

DirectX HLSL

Functions

pretty much all the functions in there will have a GLSL analogue, and if not google it and there will be something similar :slight_smile:

1 Like

Thank you so much!

1 Like