GrabPass problems when using multiple cameras

Hey everyone,

So here’s the problem. We have a dynamic weather system in place in our project to replace the basic skybox approach. Currently this sky is being rendered by the MainCamera and thus our far plane is set to a ridiculous 15000 when 1000 is plenty for everything but the sky. Because of this our depth buffer is losing all precision and thus any other shaders relying on the depth buffer, like SSAO look absolutely horrible.

To fix this I decided to approach the problem by rendering only the sky with one camera (with a depth 1 less than the main camera) and everything else on the main camera. This allows me to keep the far plane on the main camera to a more realistic 1000ish. Of course this now means that the main cameras clear flag is now set to “Depth Only” so it does not immediately clear what I just rendered with the other camera.

The issue that I have now been running into is when any shader (in any queue ie. “Background”, “Geometry”, “Transparent”) in the scene makes use of “GrabPass” the grab pass texture does not contain the sky that I thought was the first thing to be rendered to the texture buffer. This causes the the sky to not be rendered and instead is replaced with a texture buffer that looks like it was not cleared (as it has not since it’s set to “Depth Only”).

I hope I have explained the issue clear enough as I really hope someone out there knows of a solution or another way of accomplishing the same thing??

There is no need for 2 cameras.
One camera with your custom sky mesh, and sky shader has Queue = “Background” will show your sky mesh drawn behind everything even if your far clipping is 1 meter.

Making use of the “Background” queue was one of my initial thoughts as this would have allowed me to continue using a single camera, but even when applying the sky shaders during the Background queue, they were still being culled out if my far plane was not sufficient.

Is there possibly something else that I am needing to set for your suggested method to work correctly? other than simply changing the render queue to Background? To make sure it was not something else in the shaders that was causing an issue, I replaced the shader with a simple one that just put out a solid colour but set to render in the background queue, but unfortunately got the same result.

And thank you for you quick response!

Edit: Oh and I should mention that I am rendering in Deferred Lighting.

Check how the default skybox shader is done. I dont remember exactly but queue=background should be enough. camera far clipping distance has nothing to do with it.

I’m fairly certain that clipping is completely unaffected by render queue. If your sky geometry is outside your camera frustum, it will not be rendered regardless of its queue.

A second camera is a good way of approaching this issue. You can use a skybox camera to render things that are very far away, including the sky. Give that camera a lower depth, push out its clip planes, and give it an appropriate culling mask. Make it a child of your main camera, and have the main camera clear “depth only”.

Thanks Daniel for the response, I definitely agree with your suggested method as that is the exact way that I have been implementing it :). The issue was that when using this method, any shader that uses a grab pass would break the the incoming texture used for the grab pass on the camera that is set to clear depth only. But I have found a solution!

I am still using the method described above but with a small addition and modification. The camera being used to render the sky is now rendering to its own RenderTexture. I am then applying that RenderTexture to a global shader texture property called “_SkyTex”. I then attached a small script to my main camera that is rendering the entire scene minus the sky. Within this script, inside the PreRender() function, I blit the _SkyTex to the primary render surface using a simple shader set to Queue = Background and Tada! it works!

This apparently fixes the GrabPass issue as the sky texture is now most definitely written to the texture surface. I still feel that this might be a bug with Unity but at this point I’m just happy that it’s finally working!

I hope this helps anyone else that runs into a similar problem.

Cheers.

When you use a sky geometry with queue as background, you are not supposed to scale this geometry to insane numbers anyways.
Just make a skybox or whatever you need as 1 unit scale attached to your camera and thats it, it will draw this mesh behind every other object in game.
If you use 2 or more camera solutions, things will get more complicated in future when you want to add more different features.

Sorry for the mild necro… but this is an ongoing issue.

The problem occurs when using 2 or more cameras in deferred rendering mode while also using a shader with grabpass. I’ve found no real way to fix this satisfactorily, however one workaround that may work in some cases is to set the camera with the highest depth value to forward rendering instead of deferred.

Depending on your scene setup this may be fine, however in the case of rendering a skybox as 0xDEADCODE illustrated, you’d have to render the rest of your scene in forward which isn’t ideal in many cases. :confused:

1 Like

Just a quick heads up (since the issue remains and this thread is still the top search result for this issue): One known workaround for the grabpass/multiple camera problem is to make sure that there’s always at least one active object that uses a grabpass shader.
Putting a simple object (I’ve used a plane) with a refraction shader just behind the camera tends to get rid of the problem without affecting performance too much. (Unity 4.3.4)

1 Like

Oh god… The problem is still present in Unity 4.6.1f… The bug is in the Unity bug database (for a few months now).

I also wanted to say that LeShadow solution works. One must simply place an object with grabpass right behind the main camera. A silly solution but a working one.

LeShadow’s solution does work, here is the shader I wrote:

Shader "Custom/Bugfix Grabpass"
{
    Properties
    {
    }

    Category
    {
        Tags
        {
            "Queue"="Geometry+10000"
            "IgnoreProjector"="True"
            "RenderType"="Transparent"
        }

        SubShader
        {   
            GrabPass
            {
            }
        }
    }
}

I then attached a gameobject that I labeled “bugfix_grabpass_renderer” to my camera that has a Mesh Renderer and Mesh Filter. I loaded in a quad mesh, and the above material, and placed the gameobject at (localposition) (0, 0, 1), 1 unit in front of the camera. Works fine in 4.5.5p4.

In order to get image effects to work (by default, the lower depth cameras pass their direct output, not their image effect output, to the next camera), you can add the script written by Andy222 from this thread: Deferred Renderer + Multiple Cameras + Posts/SSAO = Bugged! (UFPS, OnRenderImage()) - Unity Engine - Unity Discussions

The content of the script, incase the link breaks, is:

using System.Collections;
using UnityEngine;

// fixes the deferred lighting missing final copy&resolve, so the next camera gets the correctly final processed image in the temp screen RT as input
// NOTE: The script must be the last in the image effect chain, so order it in the inspector!
[ExecuteInEditMode]
public class CopyToScreenRT : MonoBehaviour
{
    private RenderTexture activeRT; // hold the org. screen RT

    private void OnPreRender()
    {
        if (camera.actualRenderingPath == RenderingPath.DeferredLighting) 
        {
            activeRT = RenderTexture.active;
        }
        else 
        {
            activeRT = null;
        }
    }

    private void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        if (camera.actualRenderingPath == RenderingPath.DeferredLighting && activeRT) 
        {
            if (src.format == activeRT.format) 
            {
                Graphics.Blit(src, activeRT);
            }
            else 
            {
                Debug.LogWarning("Cant resolve texture, because of different formats!");
            }
        }

        // script must be last anyway, so we don't need a final copy?
        Graphics.Blit(src, dest); // just in case we are not last!
    }
}

The script should be attached after the image effects are applied by the camera, ie, last in the image effect stack.

I got the same problem but cant solve it with this workaround. My setup is the same that the initial post but I need 3 main cameras, so 3 for far distance and 3 for close distance. I try the plane with the above shader and what happens is that a bit of delay in the image suddenly appears but its the result is pretty ugly. It´s funny that a problem so big in the deferred pipeline that happen since more than a year has no fix or official answer by unity developers. By the way, all the problems that I find in unity had no response, so sad with unity limitations, having to work in Unity is a pain when you try to do some AAA content.

1 Like

Yea. I am constantly facing Unity bugs with no resolution. This engine is simply not capable of creating AAA looking games. Sooner or later you will be blocked by some bugged feature or by a lack of it…

While I understand your frustrations I gotta say it’s unfair to rule it out of AAA quality content. It’s not Unity thats makes that AAA content, it’s you. You might look to other engines as being a AAA engine. I’m pretty sure Unreal Engine its one of them. But do you really think that every time some AAA dev team is doing something more “creative” with Unreal that the engine already has something in place to solve it? of course not… They go through similar problems. If anything you should be complaining about the lack of official support, while I understand answering the same questions over and over again must be painful and that not all questions are easy to answer there should be a more proactive approach from unity, even if that meant educating people on how to make the question.

I’ve been in your place many times before, and it simply sucks, but I’m not blaming on the engine itself for my lack of understanding it, I blame the documentation and the support, and i gotta hand it to the community for the amazing support.

1 Like

I understand everything you have said and I agree. There is no “perfect game engine”. Every single one of them have some flaws, every single one of them have some bugs. I have worked with few other engines so I’m fully aware of that. On the other hand, while I’m working with other engines which have their source code exposed I am simply fixing these issues on the go or accepting their existence if it’s not something I can fix on my own. I have already some Unity titles released and believe me when I’m saying: Unity is not capable of generating anything related to AAA-graphics simply because it is not designed to do so. It is a great tool but not for pretty games. Unity5 may change this but still… There are some major issues which are related to the way Unity renderer and graphics pipeline is coded in general. But I don’t perceive it as a flaw. Unity came a long way from mobile engine to multiplatform engine and it’s doing great. What’s bugging me a lot is… fixing bugs. I have been using Shuriken from day 1 and there are still some fundamental bugs that are not fixed or even adressed (some of them are few years old). Also the bug like this with grabpass which is really important and sitting deep inside Unity’s renderer but wasn’t fixed since 2013 :slight_smile:

I blame the fact that Unity limitations are pretty noticeable once you have to make AAA content (or try to). I´m forced to use Unity in my company because in the beginning ,many years ago, we were a tiny team and we need to create a small software with many features with a close delivery time. Since the team grew and we need to go further with both , the contents and the features, we began to face the big flaws of this engine. First, there is no 64bit version, with huge projects thats a big problem, memory limitations ,some memory leaks and the static memory that mono needs… Scene loading and peaks of cpu or even freeze… Old physics version… No serialization on inherit classes… The terrain (anyone that fight with it knows what I mean)… The 64 limit in shader keywords… Now the multi camera deferred bug…
Seriously dude, Unity is amazing, I really love it when I have to create games in a gameJam or casual mobile games with my mates, but its a pain when I have to work with it in a huge project daily. The worst part is not the limitation, its the lack of information or directly that this bugs aren’t even planned to be fixed( I talk about fixing , not just increasing the limitations thresholds). I can copy here lots of links to this forum with all the limitations I talked about, and in all of them the same pattern ( i say this because you talked about " answering the same questions " and “educating people on how to make the question”, that really offend me dude):

  • One user expose the problem, well documented, with package reproducing the problem and files explaining what happens
  • One or two post of “bump” stuff
  • One reply from one user that explain why the problem happens with a more technical approach
  • If you are lucky, one reply of a dirty workaround
  • The most the cases, some replies of people that can’t / don’t know solve the problem with that workaround
  • Maybe that dirty workaround works but you can’t use it in your project because is directly linked to a specific context
  • No official response from unity devs or an official response saying that :
  1. It is a core mighty feature that would break Unity if its changed
  2. It is a limitation that would be fixed in Unity “your version” + 1 by increasing the “limit value” x 2

By the way, don´t misundertand me, I´m not saying that Unity Forum, documentation (well some maybe yes) and community are bad, it´s useful most of the time but, in my experience, Its pretty amateur. You can make incredible applications with Unity using many assets in the asset Store, but I miss some coherence with some basic features that you find in other Engines as core default tools.

1 Like

@ph0b0s sorry if i offended you, wasn’t trying to, in fact i wasn’t even specifying anyone in particular, the “same questions” argument is that if you stay around in the forums enough time you’ll notice that some questions get asked a lot of times and others are asked with no context or details about any given problem, i wasn’t even referring to this thread in particular.

Because unity gets a high influx of novice developers it’s normal that this happens, what i was trying to say is that i don’t really blame the engine because a lot of times the problems people have it’s not the engine failing to do something right, it’s us not really getting what we are doing wrong, and yes, there are cases like this one where it all points to the engine, but whatever the case might be i still point the finger to the lack of support. This problem not being addressed or fixed after all this time is far more concerning than it’s existence. People not getting their answer even if it’s a simple question is also lack of support.

Currently my votes on the feedback page are all for improving the terrains system. It’s clunky, slow, outdated and even has a few bugs in it. But the biggest problem is the fact that it stayed this way for so long and even now we don’t have any prospect of a serious update. Unity 5 brings a lot of great new features but i’m not sure if they are more important than fixing some of the deep problems the engine has.

Also, I don’t know what you guys consider AAA content but i’ve seen enough games done in Unity that fit my definition of AAA content, be it graphics, gameplay or any other content.

1 Like

This bug still exists in Unity 5 RC3

Still an issue. I’ve had to remove all refraction from my oculus game due to it. Love to see this issue fixed.

I am using the Realistic Effects Pack from the Asset store. I have this problem with their distortion shaders. I have a first person main camera and a weapons camera. The distortion effect uses a grab pass and so I get the problem described above.

@chingwa your solution worked for me, thx. I set the weapons camera to forward rendering.