Replace GUI texture colour with increased saturation of background?


I was wondering whether anyone had any pointers as to how the best way to go about this.

The central grey rectangle shape in the centre of the image is a photoshop .png which I have attached to a GUI texture.
But instead of it being a transparent colour laid over the top of the background - I want the colour instead to be an increased saturation of the game scene.

I’m struggling to find the best way to go about this - I’ve been looking into using shaders, but I can’t work out how to apply it to only the shape of the box you can see below.
(And ideally with a fading gradient as can be seen in the photoshop image - with the increased saturation replacing the grey)

Sorry for the newbie question - I was just hoping for some tips as to where to direct my search, as I’m struggling at the moment!

All the best, Laurien



Hey there!

If you have unity pro you can do this quite easily with RenderTextures and Image Effects, however if you are like me and don’t have pro, the easiest way I can get to work reasonably well is to use Camera.SetReplacementShader with some for of saturation shader and mask image. Below I have added my test shader code and the code that you would attach to your main camera. You will probably need to add some more functionality to the shader code for bump and specular maps as I can see you have those in your scene screenshot but this should get you some way towards your target!

The code to attach to your main camera:

This code toggles the saturation effect on pressing ‘Q’, in the inspector you need to set the shader to a variation on the shader attached below, the mask to some texture such as the one you attached in the screenshot above and you should set f to control how strongly the masked area should be saturated!

public Shader s;
public Texture mask;
public float f = 1;
bool isOn = false;
void Start(){
	Shader.SetGlobalTexture("_MaskTex", mask);
	f = Mathf.Clamp(f, 0, 5);
	Shader.SetGlobalFloat("_Sat", f);

void Update(){
	f = Mathf.Clamp(f, 0, 5);
	Shader.SetGlobalFloat("_Sat", f);
		isOn = !isOn;
			camera.SetReplacementShader(s, "");

The shader code:

You will need to add bump map and specular map functionality to this based on how the other shaders in your scene are set-up but it should still ~work~ as it is.

Shader "Transparent/SaturationMask" {
	Properties {
		_Color ("Main Color", Color) = (1,1,1,1)
		_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
		_MaskTex ("Mask Texture", 2D) = "white" {}
		_Sat ("Saturation", Range(0, 5.0)) = 0

	SubShader {
		Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
		LOD 200
		Cull Off

		#pragma surface surf Lambert alpha

		sampler2D _MainTex;
		sampler2D _MaskTex;
		fixed4 _Color;
		float _Sat;

		struct Input {
			float2 uv_MainTex;
			float4 screenPos;

		void surf (Input IN, inout SurfaceOutput o) {
			fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
			float2 screenUV = IN.screenPos.xy / IN.screenPos.w;
			fixed4 mC = tex2D(_MaskTex, screenUV);
			if(mC.a == 0){
				o.Albedo = c.rgb;
				o.Alpha = c.a;
				float s = _Sat;
				float d = sqrt(c.r*c.r+c.g*c.g+c.b*c.b);
				fixed4 satC = c;
				satC.r = d + (c.r-d)*s;
				satC.g = d + (c.g-d)*s;
				satC.b = d + (c.b-d)*s;
				o.Albedo = c.rgb + satC*mC.a;
				o.Alpha = c.a;
	Fallback "Transparent/Diffuse"

I hope that helps you on your way!