For those of you who have been following my posts as I’ve been trying (for 40+ hours) to get CommandBuffer.Blit() to work right, I believe I may have found one of the reasons why it took me so long. I think there is a bug in CommandBuffer.Blit().
The CommandBuffer.Blit() function, when you specify a custom shader that does NOTHING except COPY the _MainTex (I tried using Internal_BlitCopy.shader, for example), fails to produce the same image that is produced by a call to CommandBuffer.Blit() where no custom shader is specified at all.
For example, these two lines of code do not produce the same result:
// Produces an image saved to texID:
cmdBuffer.Blit(BuiltinRenderTextureType.CameraTarget, texID); //, Internal_BlitCopy);
// Solid grey color is saved to texID:
cmdBuffer.Blit(BuiltinRenderTextureType.CameraTarget, texID, Internal_BlitCopy);
The shader for Internal_BlitCopy being used here, is an exact copy & paste of the shader found at builtin_shader-5.4.1f1\DefaultResourcesExtra\Internal-BlitCopy.shader
This shader should, as indicated by its name, do nothing except copy.
Here is that shader’s code:
Shader "Internal_BlitCopy" { //Shader "Hidden/BlitCopy" {
Properties{ _MainTex("Texture", any) = "" {} }
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
sampler2D _MainTex;
uniform float4 _MainTex_ST;
struct appdata_t {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f {
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
v2f vert(appdata_t v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.texcoord = TRANSFORM_TEX(v.texcoord.xy, _MainTex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
return tex2D(_MainTex, i.texcoord);
}
ENDCG
}
}
Fallback Off
}
As you can see, it does nothing except copy _MainTex, as it should, seeing how it’s the shader that Unity uses internally when doing a Blit().
And yet, if you specify this or any other shader for copying the pixels, it results in a completely grey color with no picture. The copy fails to work right at all.
But if you call CommandBuffer.Blit() and you do not pass in any custom shader, it copies the image just fine (except for the recent bug where it flips the picture up-side-down, but that’s an unrelated issue).
For anyone interested, I’m attaching two example scenes to demonstrate this issue.
In the two attached scenes, it demonstrates the call to CommandBuffer.Blit() with and without passing in the Internal_BlitCopy.shader. There is only one line of code that’s different between the two attached scenes, and that’s the call to CommandBuffer.Blit(), one with the Internal_BlitCopy.shader, and one with no shader.
To reproduce this using the example I’m attaching:
Open the scene named “Blit_WILL_blit.unity” and click play, and observe that an image appears.
Open the scene named “Blit_wont_blit.unity” and click play, and observe a grey screen appears.
Open the source for both “Blit_WILL_blit.cs” and “Blit_wont_blit.cs” and observe the only difference is one line of code, the call to CommandBuffer.Blit(), wherein one uses the custom shader, and one doesn’t.
Open the custom shader, which is included in the attached package at Assets\Internal_BlitCopy.shader, and observe that it is an exact copy of Unity’s builtin “Internal_BlitCopy.shader”, and it does nothing except a simple copy of _MainTex, and it seems to me that there is no reason it should fail to produce the same results as would be expected if you didn’t specify any custom shader at all.
2798343–203052–CommandBufferBlitMisfunctionality.unitypackage (29 KB)