- Home /
Replace GUI texture colour with increased saturation of background?
Hi!
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
Answer by Scribe · Nov 03, 2014 at 01:21 AM
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);
if(Input.GetKeyDown(KeyCode.Q)){
isOn = !isOn;
if(isOn){
camera.SetReplacementShader(s, "");
}else{
camera.ResetReplacementShader();
}
}
}
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
CGPROGRAM
#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;
}else{
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;
}
}
ENDCG
}
Fallback "Transparent/Diffuse"
}
I hope that helps you on your way!
Scribe
Just realised, line 42 in the shader script should be o.Albedo = c.rgb*(1-mC.a) + satC.rgb*mC.a;
for a real saturation effect, but the effect it has now is very similar!
Hi - sorry!
I'm getting a parsing error on the line Shader "Transparent/Saturation$$anonymous$$ask" {
Assets/Scripts/Shader_code.cs(5,35): error CS8025: Parsing error
I've been going through it a while but I just can't work out what's wrong - any ideas?
(Thanks for the code advice by the way! That's so much for helpful than I was hoping for!)
The shader code should not be a C# script as it looks like you have made it, in your project window right click and go to create->shader and replace all of the code in the created shader to what I posted. Then drag that shader asset onto the other script in the inspector!
Thank you so much - that's worked so well, I'm so happy!
You're right, I need to set up the shader code for bump and specular maps, I'll have a look into how I should go about that now :)
I'm glad you managed to get it working! Shader coding is not easy, but you should be able to mostly just copy how the _$$anonymous$$ainTex stuff is used. Good luck :)
Your answer
Follow this Question
Related Questions
GUI and Shader problem on specific Android devices (HTC ONE X) 0 Answers
SetTexture In A UI Material Doesn't Update Immediately 0 Answers
How to create a ripple like effect on the GUI based on ingame data? 0 Answers
Why are all my GUITexture elements semi-transparent? 0 Answers
3, 2, 1 GO! 3 Answers