Using Blit with Layermask?

Hello all. I’m experimenting with a pixelate effect

Using Blit on its own works fine (Figure 2), but I want to make the character sprite clearer than everything else.

I’ve tried using a render texture and quad with a two camera, but that only got me so far. Is there a way to make Blit work like the post processing stack where I could choose which layers to effect or not?

Thank you.

Shader Code (credit: Shaderlab)

Shader "Post Processing/Pixelate"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _PixelSize("Pixel Size", Range(0.001, 0.1)) = 1.0
    }
        SubShader
        {
            Tags { "RenderType" = "Opaque" }

            Pass
            {
                CGPROGRAM
                #pragma vertex vert_img
                #pragma fragment frag
                #include "UnityCG.cginc"

                sampler2D _MainTex;
                float _PixelSize;

                fixed4 frag(v2f_img i) : SV_Target
                {
                    fixed4 col;
                    float ratioX = (int)(i.uv.x / _PixelSize) * _PixelSize;
                    float ratioY = (int)(i.uv.y / _PixelSize) * _PixelSize;
                    col = tex2D(_MainTex, float2(ratioX, ratioY));

                    // Convert to grey scale
                    col = dot(col.rgb, float3(0.3, 0.59, 0.11));

                    // Original Gameboy RGB Colors :
                    // 15, 56, 15
                    // 48, 98, 48
                    // 139, 172, 15
                    // 155, 188, 15

                    if (col.r <= 0.25)
                    {
                        col = fixed4(0.06, 0.22, 0.06, 1.0);
                    }
                    else if (col.r > 0.75)
                    {
                        col = fixed4(0.6, 0.74, 0.06, 1.0);
                    }
                    else if (col.r > 0.25 && col.r <= 0.5)
                    {
                        col = fixed4(0.19, 0.38, 0.19, 1.0);
                    }
                    else
                    {
                        col = fixed4(0.54, 0.67, 0.06, 1.0);
                    }

                    return col;
                }

                ENDCG
            }
        }
    }

Processing Code:

[ExecuteInEditMode]
public class CameraRenderPostProcessing : MonoBehaviour
{
    public Material Mat;
    //Layermask here if possible

    public void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        if (Mat != null)
        {
            Graphics.Blit(source, destination, Mat);
        }
       
    }
}

Blit on it’s own does not know which objects are on which layers. I’ve implemented similar thing by first rendering objects on the chosen layer with replacement shader (white unlit) to a separate RenderTexture, which results in a black texture with white object silhouettes, so it can be used as a mask in further postprocessing. Though I’ve used URP and MeshRenderers, not SpriteRenderers, but I think there should be a similar approach.

1 Like