Disable occlusion culling with opaque shader

I’m not really sure about where my problem comes from exactly, so my title may be off…

Basically, I’m trying to draw, with a secondary camera, quite complex figures on quads through their shader, blend all those quads in a specific way and have as result a texture of all those quads. Then I display this texture on a big quad in front of the main camera, with a background behind.

And after 2 days of trying to get the correct configuration for that to work, I feel I’ve tried everything I could think of, without ever achieving the exact result I want.

In the configuration with the closest result, I have my shader as an opaque blend mode (One Zero), but in which I use the refraction texture (Scene Color in Shader Forge) to redraw what’s behind (other quads already drawn). It is set on the Transparent Render Queue (I’ve also tried at verious other values), and everything is correct, except that the camera doesn’t draw the quads culled by other quads (even with the checkbox “Occlusion Culling” disabled on the secondary camera).
If I have two quads at the same position, only one of them is drawed (despite having very large area with an alpha to 0, and the shader in this case using the Scene Color to choose alpha and color).

Edit: I’ve forgotten an important detail: any other “classical” shader rendered by the same secondary camera, even if behind one of my quads, is correctly rendered. Only two quads using that precise shader (different materials though) hide themselves.

Edit 2: The order in which they are drawn does not matter to me, the result is the same. I have tried to set them at different values of Render Queue and change their distance to the camera, with no success.

Edit 3: A picture might be a good idea:

There are two quads here, each of them supposed to display the same white circle, but one of them is hidden by the other one, on a pixel where it’s clearly transparent (the blue part is a moving background).

There are a LOT of other parameters I’ve tried to change, but I’m not totally sure about which ones would be relevant here…
I’m gonna give some precisions I can think about in case it would help:

  • I can’t use an AlphaBlended blend mode, because I need to control very exactly the final alpha and color of each pixel (for example if I draw a same color with a same alpha < 0 on a pixel, I want the alpha to remain the same and the pixel color to be the original color).
  • My secondary camera uses a Clear Solid Color as clear flags, has a higher priority than the main camera and draws in a RenderTexture.
  • I use a simple MeshRenderer with a quad to display this texture in front of the main camera, with a simple Unlit Transparent shader (AlphaBlended).

I feel either it’s not possible, either there’s a very simple solution to my issue, but I can’t figure it out :confused: Any help greatly appreciated!

The shader’s settings (generated with ShaderForge) (removing all the parameters and operations, because there are a LOT of them, but tell me if it could be useful! I’m just pretty confident about the Refraction grabbing part and incorporating it in the main pass):

// Shader created with Shader Forge v1.38
// Shader Forge (c) Neat Corporation / Joachim Holmer - http://www.acegikmo.com/shaderforge/
// Bunch of ShaderForge metadata

Shader "Waves/BorderedWave" {
    Properties {
       //Bunch of properties here
       //Not sure why the cutoff is automatically added by ShaderForge here
        [HideInInspector]_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
    }
    SubShader {
        Tags {
            "IgnoreProjector"="True"
            "Queue"="Transparent+1"
            "RenderType"="Transparent"
            "DisableBatching"="True"
            "PreviewType"="Plane"
        }
        GrabPass{ "Refraction" }
        Pass {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }
            ZWrite Off
      
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #define UNITY_PASS_FORWARDBASE
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdbase
            #pragma only_renderers d3d9 d3d11 glcore gles gles3
            #pragma target 3.0
            uniform sampler2D Refraction;
            //Bunch of other properties

            struct VertexInput {
                float4 vertex : POSITION;
                float2 texcoord0 : TEXCOORD0;
            };

            struct VertexOutput {
                float4 pos : SV_POSITION;
                float2 uv0 : TEXCOORD0;
                float4 projPos : TEXCOORD1;
            };

            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
                o.uv0 = v.texcoord0;
                //Funky manipulations
                return o;
            }
            float4 frag(VertexOutput i) : COLOR {
                //Lots of unholy operations
                return fixed4(finalColor,max(node_2384,node_3331.a));
            }
            ENDCG
        }

       //Can't figure how to remove this pass with ShaderForge, but whatever for now
        Pass {
            Name "ShadowCaster"
            //Useless probably bad operations I should manage to remove someday here
        }
    FallBack "Diffuse"
    CustomEditor "ShaderForgeMaterialInspector"
}

Just to report progress, it seems that it happens because the Refraction Grab pass only happens once before all the quads are drawned, so with my weird manual blend mode (and the shader Blend mode to One Zero), when I was expecting to have the last drawn quad when drawing a new one, I only have the original grap pass, without any quad. As a result, the pixels that I render transparent based on the grab pass erase the last drawn quads.
I’m not sure if it’s very clear or if it will help someone someday, but here it is!
Right now I’m gonna check for a way to make a grab pass before each draw call (must be expensive, but just to try), a friend of mine (who explained all of the above to me) told me about something like “Just Grab”, I’ll write here what I find.

Edit: Ahah that was fast! I just happened to have unchecked the box “Per-object refraction/scene color (expensive)” in Shader forge while trying to optimize the shader a few months ago :slight_smile: It made this named GrabPass, which is why it wasn’t redrawn for each object. Unchecked it, and now it works as intended!