Modify Blur shader to only blur a single camera and not ones below it?

As you know, blur will affect all cameras below the one with the effect applied to it. Is there an easy way to change this behavior? I’ve only found one answer that says you can, but it’s about DoF and I have no idea if the same applies to any other blur shader. I’m thinking no… I also, uhh, have almost zero knowledge of shaders.

Here’s what the other guy said – in this question, the person only wanted to leave the skybox camera unaffected.

The solution you quoted checks each pixel to see if it’s at maximum depth before you blur it. Because of that, this solution won’t work for you unless you clear depth before you render the camera you want to blur.

One thing you could do is have the camera you want to blur render to a renderTexture, use Graphics.Blit() to blur that texture, then render that blurred texture to the screen. Let me know if you need any more explanation.

Thanks Gambit! I get the gist of what you’re saying, but my attempts at cobbling together what I found on Google aren’t working quite yet. Not getting any errors but nothing’s showing up on screen with this code below… Am I sorta close or way off?

    Camera _camera;
    public Material mat; // Material with the Hidden/FastBlur shader on it

    void Start () {
        _camera = GetComponent<Camera>();
    }

    void Update () {
        Graphics.Blit (RTImage(_camera), null, mat);
    }

    Texture2D RTImage(Camera cam) {
        RenderTexture currentRT = RenderTexture.active;
        RenderTexture.active = cam.targetTexture;
        cam.Render();
        Texture2D image = new Texture2D(cam.targetTexture.width, cam.targetTexture.height);
        image.ReadPixels(new Rect(0, 0, cam.targetTexture.width, cam.targetTexture.height), 0, 0);
        image.Apply();
        RenderTexture.active = currentRT;
        return image;
    }

You don’t want to put Graphics.Blit() in the Update function, instead put it in the OnRenderImage or OnPostRender function. These functions must be on a script attached to a camera, and they will get called everytime the camera has finished rendering.

I’m not sure what you’re trying to do with your “RTImage” function… it looks like it’ll probably work, but you’re doing a lot of work (like reading pixels out of a texture) on the CPU when the GPU can do graphics operations MUCH faster. You shouldn’t have to call camera.Render, you should only have to Blit render textures. I like to use OnRenderImage to blit my RenderTextures to the screen once they’ve been modified.

Don’t be discouraged, graphics stuff is very touchy.

Makes sense! The RTImage thing was the first thing I found about rendering a camera to a texture, so I just went with it. :stuck_out_tongue: I had no idea OnRenderImage was a thing.

With your advice, it seems like this is all I would need right?

void OnRenderImage (RenderTexture src, RenderTexture dest) {
        Graphics.Blit (src, null, mat);
   }

Unfortunately I’m still not getting anything on screen… What else could be going wrong? Would any of the camera settings be messing it up? That came to mind since the scene I’m using has 3 cameras with specific culling masks, but playing around with those hasn’t changed anything. Or maybe the material is the issue, all it is is a material with the Hidden/FastBlur shader assigned – do I need to do anything else with that?

I’ve hit a roadblock a while ago… Closest I’ve come to making anything work is this code since it at least makes it show up on screen, but the blur from the material isn’t being applied.

void Start ()
    {
        renderTexture = new RenderTexture(Screen.width, Screen.height, 0, RenderTextureFormat.ARGBHalf);
        renderTexture.useMipMap = false;
        renderTexture.filterMode = FilterMode.Point;
        renderTexture.anisoLevel = 0;
        GetComponent<Camera>().targetTexture = renderTexture;
    }
   
    void OnGUI()
    {
        GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), renderTexture, ScaleMode.ScaleToFit, true);
    }
   
    // Update is called once per frame
    void OnRenderImage (RenderTexture src, RenderTexture dest) {
        Graphics.Blit (src, dest, mat, 4);
    }

Since this isn’t actually a shader question anymore, I guess I could try asking somewhere else.