- Home /
Overlay that creates only black and white underneath.
Hi I'm training myself by making a game atm.
I recently wanted to create an overlay that makes everything underneath black and white, but it is neccessary that this overlay works with some kind of overlay image, or however something like this is called. This is the original picture. This is the overlay-image. (white is transparent) And this is how it shall look combined.
Hopefully you can understand what I want to create after you've seen this pictures. It would be verry helpful if someone could link me some sources where i can read abeout it or videos etc.. It would also be helpful if someone could tell me how the overlay-thingy im searching for is called, because its kind of hard to search the internet for something you don't know the name of ^^.
Best regards
Janis Hansen
It would be some kind of grayscale filter (don't believe it has a specific title, at least not that I'm aware of). You would do this by using a custom image effect shader; in which you take the coloured image and a grayscale version of the image and interpolating between them based on the overlay texture. Shaders are a pretty advanced topic however; image effect shaders in particular. This is mainly because the official documentation is incredibly light (practically non existent for image effects). If you want to learn how to write shaders, and how to setup image effects you can either read over the built in stuff or refer to the Unity Docs.
Here are some basic resources about shaders and image effects;
https://docs.unity3d.com/$$anonymous$$anual/SL-Reference.html
https://docs.unity3d.com/$$anonymous$$anual/PostProcessingWritingEffects.html
Right, you can also calculate the grayscale of the image on-the-fly in the shader. So all you have to do is:
sample the actual texture as color "C"
sample the gradient texture as "t"
calculate the grayscale value "G" from the color "C"
Lerp between "C" and "G" based on "t".
If the "hotspot" of your gradient should not be a fix gradient texture, you could calculate a gradient manually inside the shader based on a screen position / radius and maybe a $$anonymous$$ and max value. That way you would only need a single texture.
Though the question is not clear if you want a static result or if it should be dynamic.
Answer by Namey5 · Sep 11, 2017 at 07:42 AM
Because there really is a lack of image effect documentation and it is pretty simple, here's a basic image effect that does this.
First, here is a C# script that you can attach to your camera;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class GrayscaleFilter : MonoBehaviour
{
private Material mat;
public Texture overlay;
private void OnRenderImage (RenderTexture src, RenderTexture dest)
{
if (!mat)
mat = new Material (Shader.Find ("Hidden/GSF"));
mat.SetTexture ("_Mask", overlay);
Graphics.Blit (src, dest, mat);
}
private void OnDisable ()
{
if (mat)
DestroyImmediate (mat);
}
}
And here is the accompanying shader;
Shader "Hidden/GSF"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Mask ("Overlay", 2D) = "white" {}
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
sampler2D _Mask;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 c = tex2D (_MainTex, i.uv);
fixed4 gs = (c.r + c.g + c.b) / 3;
return lerp (gs, c, tex2D (_Mask, i.uv).r);
}
ENDCG
}
}
}
As you can see, the majority of the actual code is done in about 6 lines.
Answer by N00MKRAD · Sep 11, 2017 at 07:25 AM
This might work:
1) Duplicate your camera and make it render above the other one.
2) Give your duped cam a grayscale image effect.
3) Hardest part: Give the grayscale camera some kind of mask so not everything is gray.
Another way:
1) Duplicate your camera.
2) Give your duped cam a grayscale image effect.
3) Render the grayscale camera to a render texture.
4) Overlay the rendertexture over your normal, color camera and use some kind of shader to get a round mask.
This is unnecessarily complicated and expensive; especially considering image effects capture the camera's render to an RT anyway. If you have the ability to write image effects/shaders, a single one is very easy to implement.
Answer by JanisHansen · Oct 06, 2017 at 03:49 PM
Thanks for your answers.
Namey5: I unfortunately can't get your solution to work. Either my explanation was too bad or I'm just too dump to use shaders. (I have no clue of shaders btw.) To eliminate the first possibility I'll describe my problem more accurate (I think): I'm making a 2D Game and I wan't my character to sometimes be surrounded by an color-consuming aura. Therefore I need some kind of overlay/graphic that i can attach to my character that will render everything underneath it in gray-scales. Also it should be possible regulate the gray-scale/color-intensity by the transparency of the overlay, like my black circular thing on the second picture tries to show. If I just don't understand how to use your shader than I would be thankful if you could explain it to me.
N00MKRAD: I agree that this should somehow work, but I also agree to Namey5 that it would be quite expensive this way.
Anyways: Thanks to you too and hopefully someone will enlighten me.
Best Regards Janis Hansen