Vertex Billboard Shader Depth?

Hi there,

So I’m currently testing out an RTS idea and have been looking for efficient ways of displaying large numbers of models in a scene. Much experimentation has ended up with me doing this:

1.Capturing a model on camera

2.Writing Camera to a Render Texture

3.Using a basic mesh with a vertex shader to display multiple billboards
(this displays a seperate billboard on each of the mesh’s vertices)

4.Using the model camera’s render texture as the billboard texture

This actually worked pretty well initially as you can see:

Unfortunately there seems to be a depth issue when the mesh is viewed from opposite it’s normals like so:

So here is my question, Is there a way to solve this while keeping the vertex shader?

Any help would be greatly appreciated, Gonna post the shader code here in case there is anything wrong with it

		_SpriteTex ("Base (RGBA)", 2D) = "white" {}
		_Size ("Size", Range(0, 3)) = 0.5
	}
	
	SubShader 
	{
		 Tags { }
			 
			 ZWrite Off
			 Blend SrcAlpha OneMinusSrcAlpha
//			 Cull Back
//			 Offset 1, 1 
				LOD 200
		
		Pass
		{
			
				
			CGPROGRAM
				#pragma target 5.0
				#pragma vertex VS_Main
				#pragma fragment FS_Main
				#pragma geometry GS_Main
				
				#include "UnityCG.cginc" 

				// **************************************************************
				// Data structures												*
				// **************************************************************
				struct GS_INPUT
				{
					float4	pos		: POSITION;
					float3	normal	: NORMAL;
					float2  tex0	: TEXCOORD0;
					float3 viewT : TEXCOORD1;
				};

				struct FS_INPUT
				{
					float4	pos		: POSITION;
					float2  tex0	: TEXCOORD0;
					
				};


				// **************************************************************
				// Vars															*
				// **************************************************************

				float _Size;
				float4x4 _VP;
				Texture2D _SpriteTex;
				SamplerState sampler_SpriteTex;

				// **************************************************************
				// Shader Programs												*
				// **************************************************************

				// Vertex Shader ------------------------------------------------
				GS_INPUT VS_Main(appdata_base v)
				{
					GS_INPUT output = (GS_INPUT)0;
					output.pos =  mul(_Object2World, v.vertex);
					output.normal = normalize(v.normal);
					output.tex0 = float2(0, 0);
//					

					return output;
					
					    
				}
				


				// Geometry Shader -----------------------------------------------------
				[maxvertexcount(4)]
				void GS_Main(point GS_INPUT p[1], inout TriangleStream<FS_INPUT> triStream)
				{
					float3 up = float3(0, 1, 0);
					float3 look = _WorldSpaceCameraPos - p[0].pos;
					look.y = 0;
					look = normalize(look);
					float3 right = cross(up, look);
					
					float halfS = 0.5f * _Size;
							
					float4 v[4];
					v[0] = float4(p[0].pos + halfS * right - halfS * up, 1.0f);
					v[1] = float4(p[0].pos + halfS * right + halfS * up, 1.0f);
					v[2] = float4(p[0].pos - halfS * right - halfS * up, 1.0f);
					v[3] = float4(p[0].pos - halfS * right + halfS * up, 1.0f);

					float4x4 vp = mul(UNITY_MATRIX_MVP, _World2Object);
					FS_INPUT pIn;
					pIn.pos = mul(vp, v[0]);
					pIn.tex0 = float2(1.0f, 0.0f);
					triStream.Append(pIn);

					pIn.pos =  mul(vp, v[1]);
					pIn.tex0 = float2(1.0f, 1.0f);
					triStream.Append(pIn);

					pIn.pos =  mul(vp, v[2]);
					pIn.tex0 = float2(0.0f, 0.0f);
					triStream.Append(pIn);

					pIn.pos =  mul(vp, v[3]);
					pIn.tex0 = float2(0.0f, 1.0f);
					triStream.Append(pIn);
				}
				



				// Fragment Shader -----------------------------------------------
				float4 FS_Main(FS_INPUT input) : COLOR
				{
					return _SpriteTex.Sample(sampler_SpriteTex, input.tex0);
				}
				
			ENDCG
		}

		
	} 
	Fallback "Diffuse"
}

Read this page…

Although I haven’t done much with shaders recently, I’m pretty confident you will need to turn ZWrite on (line 9).

Let me know if this helps :slight_smile: