Search Unity

Using Blit with Layermask?

Discussion in 'Image Effects' started by MichaelKTBigNicheGames, Aug 2, 2020.

  1. MichaelKTBigNicheGames

    MichaelKTBigNicheGames

    Joined:
    Feb 26, 2019
    Posts:
    18
    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)

    Code (CSharp):
    1. Shader "Post Processing/Pixelate"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex("Texture", 2D) = "white" {}
    6.         _PixelSize("Pixel Size", Range(0.001, 0.1)) = 1.0
    7.     }
    8.         SubShader
    9.         {
    10.             Tags { "RenderType" = "Opaque" }
    11.  
    12.             Pass
    13.             {
    14.                 CGPROGRAM
    15.                 #pragma vertex vert_img
    16.                 #pragma fragment frag
    17.                 #include "UnityCG.cginc"
    18.  
    19.                 sampler2D _MainTex;
    20.                 float _PixelSize;
    21.  
    22.                 fixed4 frag(v2f_img i) : SV_Target
    23.                 {
    24.                     fixed4 col;
    25.                     float ratioX = (int)(i.uv.x / _PixelSize) * _PixelSize;
    26.                     float ratioY = (int)(i.uv.y / _PixelSize) * _PixelSize;
    27.                     col = tex2D(_MainTex, float2(ratioX, ratioY));
    28.  
    29.                     // Convert to grey scale
    30.                     col = dot(col.rgb, float3(0.3, 0.59, 0.11));
    31.  
    32.                     // Original Gameboy RGB Colors :
    33.                     // 15, 56, 15
    34.                     // 48, 98, 48
    35.                     // 139, 172, 15
    36.                     // 155, 188, 15
    37.  
    38.                     if (col.r <= 0.25)
    39.                     {
    40.                         col = fixed4(0.06, 0.22, 0.06, 1.0);
    41.                     }
    42.                     else if (col.r > 0.75)
    43.                     {
    44.                         col = fixed4(0.6, 0.74, 0.06, 1.0);
    45.                     }
    46.                     else if (col.r > 0.25 && col.r <= 0.5)
    47.                     {
    48.                         col = fixed4(0.19, 0.38, 0.19, 1.0);
    49.                     }
    50.                     else
    51.                     {
    52.                         col = fixed4(0.54, 0.67, 0.06, 1.0);
    53.                     }
    54.  
    55.                     return col;
    56.                 }
    57.  
    58.                 ENDCG
    59.             }
    60.         }
    61.     }
    Processing Code:

    Code (CSharp):
    1. [ExecuteInEditMode]
    2. public class CameraRenderPostProcessing : MonoBehaviour
    3. {
    4.     public Material Mat;
    5.     //Layermask here if possible
    6.  
    7.     public void OnRenderImage(RenderTexture source, RenderTexture destination)
    8.     {
    9.         if (Mat != null)
    10.         {
    11.             Graphics.Blit(source, destination, Mat);
    12.         }
    13.        
    14.     }
    15. }
     

    Attached Files:

  2. Oxeren

    Oxeren

    Joined:
    Aug 14, 2013
    Posts:
    121
    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.
     
    Marrlie likes this.