# Solution 1

### Using GrabPass

> GrabPass is a special pass type - it grabs the contents of the screen
> where the object is about to be drawn into a texture. This texture can
> be used in subsequent passes to do advanced image based effects.
> 
> Just GrabPass { } grabs the current screen contents into a texture.
> The texture can be accessed in further passes by _GrabTexture name.
> Note: this form of grab pass will do the time-consuming screen
> grabbing operation for each object that uses it.

`GrabPass { "TextureName" }` grabs the current screen contents into a texture, but will only do that once per frame for the first object that uses the given texture name. The texture can be accessed in further passes by the given texture name. This is a more performant method when you have multiple objects using GrabPass in the scene

so first you should grab behind of object:

    GrabPass{ "_GrabTexture" }

Initializing position and grab position in shader:

        v2f vert(appdata_base v) {
            v2f o;
            // use UnityObjectToClipPos from UnityCG.cginc to calculate 
            // the clip-space of the vertex
            o.pos = UnityObjectToClipPos(v.vertex);
            // use ComputeGrabScreenPos function from UnityCG.cginc
            // to get the correct texture coordinate
            o.grabPos = ComputeGrabScreenPos(o.pos);
            return o;
        }

pixelating results:

        float _PixelSize;
        sampler2D _GrabTexture;
 
        float4 frag(v2f IN) : COLOR
        {
            float2 steppedUV = IN.grabPos.xy / IN.grabPos.w;
            steppedUV /= _PixelSize / _ScreenParams.xy;
            steppedUV = round(steppedUV);
            steppedUV *= _PixelSize / _ScreenParams.xy;
            //Sampling GrabTexture according to screen capture positon, tex2DProj is equivalent to tex2D (grabPos.xy / grabpos.w)
            return tex2D(_GrabTexture, steppedUV);
        }

so this is our pixelate shader:

    Shader "Custom/Pixelate"
    {
        Properties
        {
            _PixelSize("Pixel Size", Float) = 10
        }
     
        SubShader
        {
            Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" }
            Blend Off
            Lighting Off
            Fog{ Mode Off }
            ZWrite Off
            LOD 200
            Cull Off
     
            GrabPass{ "_GrabTexture" }
     
            Pass
            {
                CGPROGRAM
     
                #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"
     
                struct v2f
                {
                    float4 pos : SV_POSITION;
                    float4 grabPos  : TEXCOORD0;
                };
     
     
                v2f vert(appdata_base v) {
                    v2f o;
                    // use UnityObjectToClipPos from UnityCG.cginc to calculate 
                    // the clip-space of the vertex
                    o.pos = UnityObjectToClipPos(v.vertex);
                    // use ComputeGrabScreenPos function from UnityCG.cginc
                    // to get the correct texture coordinate
                    o.grabPos = ComputeGrabScreenPos(o.pos);
                    return o;
                }
                
                float _PixelSize;
                sampler2D _GrabTexture;
     
                float4 frag(v2f IN) : COLOR
                {
                    float2 steppedUV = IN.grabPos.xy / IN.grabPos.w;
                    steppedUV /= _PixelSize / _ScreenParams.xy;
                    steppedUV = round(steppedUV);
                    steppedUV *= _PixelSize / _ScreenParams.xy;
                    //Sampling GrabTexture according to screen capture positon, tex2DProj is equivalent to tex2D (grabPos.xy / grabpos.w)
                    return tex2D(_GrabTexture, steppedUV);
                }
             
                ENDCG
            }
        }
    }

[![enter image description here][1]][1]

# Solution 2

## Using two cameras that [I explained before][2]
1.Make secondary camera

2.On second camera, in Clear Flags set it to Don't clear

[![enter image description here][3]][3]
[![enter image description here][4]][4]

# Solution 3
## Using Command Buffer
we know, that the GPU can work on stuff in parallel. But what’s about the communication between CPU and GPU? Does the CPU has to wait until the GPU finished the job before it can receive new commands?

[![enter image description here][5]][5]

No! because this communication would create bottlenecks (e.g. when the CPU can’t deliver commands fast enough) and would make parallel working impossible.bottleneck, as for how it is named, occurs when there is a limit on how much data is being sent for processing or how much data can be processed at the same time.

The solution is a list where commands can be added by the CPU and read by the GPU – independent from each other! This list is called: Command Buffer.

## What is Command Buffer?

Command buffers hold list of rendering commands ("set render target, draw mesh, ..."). They can be set to execute at various points during camera rendering (see [Camera.AddCommandBuffer][6]), light rendering (see [Light.AddCommandBuffer][7]) or be executed immediately (see [Graphics.ExecuteCommandBuffer][8]).


## How it work?

The command buffer makes it possible that CPU and GPU can work independent from each other. When the CPU wants something to be rendered, it can push that command into the queue and when the GPU has free resources, it can take the command out of the list and execute it (but the list works as a [FIFO][9] – so the GPU can only take the oldest item in the list (which was first/earlier added than all others) and work on that).

By the way: there are different commands possible. One example is a draw call, another would be to change the render state.

[![enter image description here][10]][10]

[https://vulkan-tutorial.com/Drawing_a_triangle/Drawing/Command_buffers][11]

[https://developer.nvidia.com/engaging-voyage-vulkan][12]

[![enter image description here][13]][13]

Let's Start to use command buffer
[![enter image description here][14]][14]
Masking part of character with sphere:

     Stencil
         {
             Ref 1
             Comp Always
             Pass Replace
         }

[![enter image description here][15]][15]

create a command:

    var commandBuffer = new CommandBuffer();
    commandBuffer.name = "pixelate";

[![enter image description here][16]][16]

Temporarily copy the rendering result to the Render Texture:

      int tempTextureIdentifier = Shader.PropertyToID("_PostEffect");
            commandBuffer.GetTemporaryRT(tempTextureIdentifier, -1, -1);
            commandBuffer.Blit(BuiltinRenderTextureType.CameraTarget, tempTextureIdentifier);

[![enter image description here][17]][17]

Apply the rendering result to the material that you want to apply image effects:

    commandBuffer.Blit(tempTextureIdentifier, BuiltinRenderTextureType.CameraTarget, material);

[![enter image description here][18]][18]

Release temporary render texture:

    commandBuffer.ReleaseTemporaryRT(tempTextureIdentifier);
[![enter image description here][19]][19]

Register where you want to add the command buffer
Below is a high-level overview of how Cameras use the Forward or Deferred pipeline to render a Scene in Unity.

 - Black boxes represent an internal Unity process. Blue boxes represent
 - a CameraEvent where you can add Command Buffers.

[![enter image description here][20]][20]

    camera.AddCommandBuffer(CameraEvent.BeforeImageEffects, commandBuffer);

[![enter image description here][21]][21]


add Image effects to where Ref is equal to 1

 

       Stencil
        {
            Ref 1
            Comp Equal
        }

[![enter image description here][22]][22]

adding color to pixelated area

[![enter image description here][23]][23]

## More Examples!
pixelating specific objects

[![enter image description here][24]][24]

grayscale where that is not equal to Ref 1

    Stencil
    {
        Ref 1
        Comp NotEqual
    }

[![enter image description here][25]][25]


References:

[https://simonschreibt.de/gat/renderhell-book1/][26]

[https://gurutaka-log.com/commandbuffer-stencilbuffer][27]


  [1]: https://i.sstatic.net/XrC7P.gif
  [2]: https://gamedev.stackexchange.com/questions/152230/unity-post-processing-effect-conflicts-with-ui-image-blur-shader/152375#152375
  [3]: https://i.sstatic.net/f7yG7.jpg
  [4]: https://i.sstatic.net/tDasf.jpg
  [5]: https://i.sstatic.net/d8aXa.gif
  [6]: https://docs.unity3d.com/ScriptReference/Camera.AddCommandBuffer.html
  [7]: https://docs.unity3d.com/ScriptReference/Light.AddCommandBuffer.html
  [8]: https://docs.unity3d.com/ScriptReference/Graphics.ExecuteCommandBuffer.html
  [9]: http://en.wikipedia.org/wiki/FIFO
  [10]: https://i.sstatic.net/DypMO.gif
  [11]: https://vulkan-tutorial.com/Drawing_a_triangle/Drawing/Command_buffers
  [12]: https://developer.nvidia.com/engaging-voyage-vulkan
  [13]: https://i.sstatic.net/qGhUW.jpg
  [14]: https://i.sstatic.net/pMiQR.png
  [15]: https://i.sstatic.net/JcvHR.png
  [16]: https://i.sstatic.net/T0xnn.png
  [17]: https://i.sstatic.net/SZ9tb.png
  [18]: https://i.sstatic.net/D2eIw.png
  [19]: https://i.sstatic.net/nvIEH.png
  [20]: https://i.sstatic.net/YizkI.png
  [21]: https://i.sstatic.net/BLUXz.png
  [22]: https://i.sstatic.net/fzKDi.png
  [23]: https://i.sstatic.net/NSh4N.png
  [24]: https://i.sstatic.net/jgDFE.png
  [25]: https://i.sstatic.net/7LeEj.png
  [26]: https://simonschreibt.de/gat/renderhell-book1/
  [27]: https://gurutaka-log.com/commandbuffer-stencilbuffer