- Home /
Transparent shader in background queue
Hello Unity fellows,
I have a hard time trying to render a transparent object in the "Background" queue. I spent one day searching Unity Forums and Answers for hints, but everything I tested wasn't successful. A bit of a context (because the problem may be complex):
I have an outside environement with sea and sky. I use the "Blended SkyBox" shader to create a skybox, and, I want to add a sun (simple quad with texture). I don't want to use a "far away" object because it requires to have a far away clipping plane, and it is always possible to spot the trick when the sun sets above the sea if the camera is quite high (you see the sun going "through the sea", not "behind").
Thus, I just want to render my sun behind everything, except the sky (rendered in Queue = Background), ie using a Queue="Background+1" tag. Problem is, my sun is round, and thus, my texture is transparent.
I use the following "simple" shader:
Shader "Custom/SunAndMoon" {
Properties
{
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB) Trans. (Alpha)", 2D) = "white" { }
}
SubShader
{
Tags {"Queue"="Background+1" } // OK for Queue=2500 or +. Below, it doesn't work.
Cull Off
Fog { Mode Off }
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
Lighting Off
SetTexture [_MainTex]
{
constantColor [_Color]
Combine texture * constant, texture * constant
}
}
}
}
Actually this shader gives this render:
Funny thing is, if I change the Queue to "Background+1501" it works (Alpha blending is taken into account, see this render:
But it renders the sun after all Geometry, which I don't want. If Queue is "Background +1500" or lower, Alpha Blending doesn't work.
It seems that Queues do additionnal stuff appart from managing rendering order.
Other tests I made:
Using a cutout (AlphaTest Greater 0.2) in Queue = Background+1 -> OK, But I'd like to have the "glow" effect achieved with alpha blending
Disabling skybox, enabling Alpha blending and Queue = Background+1 -> OK This tends to show that the problem is not really with alpha blending but rather with getting the "destination color". With a solid clear color, it's OK. With a skybox it's not, we get that "dark grey color" around the sun spot. Talking about it...
...The "black" around the sun is not pure black. It's some dark grey which might be used by unity to "clear" the viewport. It's NOT related to ambient light, and NOT related to the "clear color" specified in the camera settings (this drives me crazy). I can see it by turning my skybox alpha to 0.
Enabling skybox and Alpha Blending, Queue = Background+1, Disabling ZWrite (because at some point, I'll have to)-> The sun is not visible anymore! But actually, by playing with the skybox alpha, it appears that the sun is rendered BEHIND the sky...
Trying to use a vertex/fragment shader instead of my fixed pipeline shader seemed to work at some point. But when I restarted Unity, the same problem raises again. It may be influenced by shaders order in memory I guess.
Those results don't make any sense at all for me. I must have missed something. Any help from Unity gurus would be greatly appreciated.
Thanks a lot :) and sorry for the long explanation.
You are severely overcomplicating this. What is "Blended SkyBox"?
His concrete problem notwithstanding, I think he raises a very relevant question I'd like to get an answer for too: Those renderQueue numbers. Do they mean anything else than manually setting render order? Is Unity doing something else with them behind the scenes that affects what can be done in each queue interval, eg. transparency in the background queue? If anyone knows or has seen the actual documentation for this, I'd love to see it, too. :)
Aside from what you said they do, low queues sort front-to-back, and high queues sort back-to-front. I don't know the specific numbers; they're undocumented as far as I know. That's all I know of.
@Jessy: you're right for the "over complicating", but I don't know how to put it simpler... :( and I wanted to share those very weird observations I made. The Blended Skybox is a shader I got from http://wiki.unity3d.com/index.php?title=SkyboxBlended. It basically enables to mix 2 skyboxes to achieve a day/night cycle effect. Queue numbers are somehow documented here http://docs.unity3d.com/Documentation/Components/SL-SubshaderTags.html. Basically Background is 1000, Geometry is 2000, AlphaTest is 2450, Transparent is 3000 and Overlay is 4000. The only sorting info is for the Transparent Queue being sorted back to front. Nothing is said for other queues.
@CHPedersen: Your reformulation of the core question of this post is absolutely correct and clearly stated too. I'm not an english native speaker, so sorry if I'm not very clear.
Anyway, thanks Guys for stopping by!
What exactly is meant by back-to-front order in the Transparent queue? I'm under the impression it will render in whatever order I explicitly tell it to, using those renderQueue numbers. Does it refer to distance in camera-space, i.e. the Z-value? So "back-to-front" means it renders furthest away first and then works its way up to the closest object?
Answer by Matou · Mar 29, 2014 at 09:32 AM
Okay! I'm finally back with some kind of solution. I hope this can help some of you out there with the same problem!
I recently made a few bunch of tests on this problem, and I found that the problem doesn't come from the sun shader, but from the use of the standard skybox of Unity. For some reason, be it the skybox of the Render Settings or the Skybox component on a camera, the rendering of the skybox seems to affect the rendering of following transparent elements in the background queue.
Indeed, when I use a custom-made skybox, everything is OK. Here's what I did:
Disable all unity skyboxes (Render Settings and Skybox component of the camera) and set the background of the camera to "solid"
Create a sphere centered on the camera and parent it to the camera
Remove the collider of the sphere, and attach a script which constantly sets the rotation of the sphere to Quaternion.identity
Attach a personal skybox material to the sphere with the shader below
Finally use the sun shader in Background Queue +1 for example, and transparency works well!
This may not be the best shader, but it works:
Shader "Custom/cubemapSkybox"
{
Properties {
_CubeDay("CubeMap Day", CUBE) = "" {}
}
SubShader
{
Tags { "Queue"="Background" "RenderType"="Background" }
LOD 200
Cull Off
ZWrite Off
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
samplerCUBE _CubeDay;
struct v2f
{
float4 pos : SV_POSITION;
float3 norm : TEXCOORD0;
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.norm = v.normal;
return o;
}
half4 frag (v2f i) : COLOR
{
return texCUBE(_CubeDay,i.norm);
}
ENDCG
}
}
FallBack "Diffuse"
}
However, there is a limitation to this technique: when using a reflective water shader, you won't get the skybox in the reflection.
This is because the reflection shader+script create a "reflection" camera by copying the main camera parameters. As the camera doesn't use any skybox (at least any Unity skybox), the reflection camera has no skybox either. If you want a reflected skybox in your water, you need to apply the same trick to the "reflection camera"... and probably invert the Y axis of the normal in the shader in order to have a proper reflection of the skybox.
Hope this helps!
Peace :)
PS1: Ho! And by the way, I have a newer version of Unity now and I couldn't reproduce all the "bugs/strange behaviours" I talked about in my first question.
PS2: For now, I accept my own answer as "THE" answer, but if anyone has a better solution, I'll be glad to hear about it!
Answer by waka324 · Apr 25, 2014 at 06:48 PM
My bet is that your fist shader is missing a few important items:
Tags {"RenderType"="Transparent" } //needed for camera depth-testing.
ZWrite Off //make sure not to write to the depth buffer. Else pixels behind will be occluded.
Let me know how it works!
O$$anonymous$$... I'm aaawfully late (shame on me :( ) and I can't even test your proposition right now because my project changed so much... But, from my memory, I can assure you that I tested those settings.
However, the most strange thing, that makes me think it has nothing to do with this, is that, when I finally got a "good" shader, I tested it with BOTH my home-made skybox and the Unity skybox, and it turned out there was the rendering bug with the Unity skybox, but not with my own skybox, whereas it was with the EXACT same shader.
Thus I think the problem comes from the unity skybox, not from the shader itself.
Anyways, thanks a lot for stopping by. Peace :)
Your answer
Follow this Question
Related Questions
Sun on a skydome 0 Answers
Skybox Problems 1 Answer
How do I make a Skybox scroll by moving left/right in a Platformer 0 Answers
Simple shader works in Editor-view but not in game-view. 0 Answers
Sun Does Not Appear in Skybox 0 Answers