I’m trying to render a background image by rendering a full-screen quad (-1;-1 to 1;1). To get going, I currently use a simple shader that simply returns red. I set the Queue to Background, ZWrite off and return a depth of 1 so the quad is lying behind everything else. This is working for opaque objects, but not for transparent ones. In the image below there a few sphere using an “ordinary” geometry shader and two transparent objects (dragon and plane) with a transparent shader.
I’m probably missing a step/configuration, but which one?
I’m guessing the Background queue value is incorrect. Try something like Geometry+10 instead. It should be rendered in between Geometry and Transparent.
Thanks, but that didn’t help. And it’s not because of the Unity bug that changing the queue doesn’t affect existing materials - I create the material in script and assign my shader.
Btw, why do you think it should be rendered between Geometry and Transparent? Being a background image, shouldn’t it be rendered first?
And just in case: This is on OSX 10.11 using Unity 5.4b16
Because that would be a waste of performance/fillrate. Pixels of the background can be skipped where opaque pixels are drawn. As a general rule, opaque is front to back, transparent is back to front.
Ah, very true, I didn’t think about that. I will probably still have to draw every pixel - this will become a shader doing atmospheric scattering, and I need data for every pixel even if it’s not drawn. Still, thanks for the hint.
Here’s my (simple get-going) shader (here again using the Background queue):
Shader "MyShader/GetGoing" {
SubShader {
Tags {
"Queue" = "Background"
}
Pass {
ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
struct vertInput {
float4 pos : POSITION;
float2 texcoord : TEXCOORD0;
};
struct vertOutput {
float4 pos : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
vertOutput vert (vertInput v)
{
vertOutput o;
o.pos = v.pos;
#if !UNITY_UV_STARTS_AT_TOP
o.pos.y *= -1;
#endif
o.texcoord = v.texcoord;
return o;
}
void frag(vertOutput i, out float4 col:COLOR, out float depth:smile:EPTH)
{
col = float4(1.0, 0.0, 0.0, 0.5);
depth = 1.0;
}
ENDCG
}
}
FallBack Off
}
Well, considering that the transparent parts probably also don’t do a ZWrite, the draw order of the transparent parts and the background determines the final outcome. I see nothing special about the shader (just wanted to check whether it had any blending enabled), so I can only come to the conclusion that the background is drawn after the transparent parts, which is simply not the correct order.