Hello, im trying to make a billboard shader with alpha blending but i don't know a single line of this : p The blending was really easy using shader lab syntax to get working and i found a billboard shader on the internet but the problem is it only works when i have one on the screen at a time. As soon as i add another one both turn invisible. Also i wonder how its possible to change the scale of the billboard and if its possible to optimize it further. Here is the code: Code (csharp): Shader "Alpha Billboard" { Properties { _TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5) _MainTex ("Particle Texture", 2D) = "white" {} } Category { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } Blend SrcAlpha OneMinusSrcAlpha AlphaTest Greater .01 Cull Off SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; fixed4 _TintColor; struct appdata_t { float4 vertex : POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; }; struct v2f { float4 vertex : POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; }; v2f vert (appdata_t v) { v2f o; o.vertex = mul(UNITY_MATRIX_P, mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0)) + float4(v.vertex.x, v.vertex.y, 0.0, 0.0)); o.color = v.color; o.texcoord = float4(v.vertex.x + 0.5, v.vertex.y + 0.5, 0.0, 0.0); return o; } fixed4 frag (v2f i) : COLOR { return 2.0f * i.color * _TintColor * tex2D(_MainTex, i.texcoord); } ENDCG } } } }
how do you change the values to make them invisible? Maybe you acces all elements that got that material attached.
I don't want anything invisible (except for the alpha), thats the problem. As soon as i try to add another instance both will turn invisible : /
I once got the same porblem too, and never figure it out [Edit]:http://forum.unity3d.com/threads/181287-Billboard-sprite-shader
Seems like many had this issue but not a single reply from a dev or moderator : / If anyone could point me to another working billboard shader that would also be appreciated : )
I can't check it now, but I see a few possible problems. First, though it's probably not your issue, change Code (csharp): o.texcoord = float4(v.vertex.x + 0.5, v.vertex.y + 0.5, 0.0, 0.0); to Code (csharp): o.texcoord = float2(v.vertex.x + 0.5, v.vertex.y + 0.5); as the compiler can do something unexpected with implicit truncation. Then the shader doesn't turn off zwite. I'm not sure if unity does it automatically if rendertype is transparent, but I gues not. Writing to zbuffer in transparent queue can bring to front background objects resulting in strange issues. Try if this helps. I'm writing this on a tablet :wink: Code (csharp): Shader "Alpha Billboard" { Properties { _TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5) _MainTex ("Particle Texture", 2D) = "white" {} _Scale("Scale", float) = 1.0 } Category { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } Blend SrcAlpha OneMinusSrcAlpha AlphaTest Greater .01 Cull Off // important ZWrite off SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; fixed4 _TintColor; float _Scale; struct appdata_t { float4 vertex : POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; }; struct v2f { float4 vertex : POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; }; v2f vert (appdata_t v) { v2f o; o.vertex = mul(UNITY_MATRIX_P, mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0)) + float4(v.vertex.x, v.vertex.y, 0.0, 0.0)*_Scale); o.color = v.color; o.texcoord = float2(v.vertex.x + 0.5, v.vertex.y + 0.5); return o; } fixed4 frag (v2f i) : COLOR { return 2.0f * i.color * _TintColor * tex2D(_MainTex, i.texcoord); } ENDCG } } } } Remember semitransparency may be tricky.
Thanx you a lot for the help! Scale works very good, but ZWrite Off makes the whole thing look very strange and something is off with the depth causing some trunks to be rendered in front of some of the "leaves", but only on the left side for some reason. Works better without that flag. Everything works very well if i create separate materials for every mesh by instantiating everything in code, but then i cant use dynamic batching and get loads of drawcalls. Why cant i use the same material for multiple instances? Is this some kind of Unity bug? Also, any idea how i get lightning to update properly on the billboards? Example is day/night cycle.
Actually the batching itself is the problem here. As all batched meshes are combined into a single mesh, the null point changes of course. However this billboard shader requires the null point to be in the middle of your sprite.
It seems that is why all these werid things happens, could you explain more details, Like when would the batching happens? even if i dont create meshes as particles
Generally if dynamic batching is enabled (Project->Player Settings) meshes with the same material (sharedMaterial) and not to many vertices will be batched (there are exceptions like non-uniform scaling, shadows and other). Batching means that all affected meshes will be merged into one big mesh which is faster to render. Local vertex coordinates and tangents will be adjusted accordingly as now the center/null point of the mesh has been moved/rotated. Subsequently vertex shader which rely on a defined center will render incorrectly (like the shader above).
Ah, it's really batching! I really fixed this bug, but with some "hack", I re-created a material for each sprite object
Set static flag on objects - this will change batching algorithm to friendly with billboard technique. But in this case you will not be able to change position of objects..