Shader "Points/Billboard" { Properties { _PointSize("PointSize", Range(0, 0.1)) = 0.01 [Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("Source Blend", Float) = 1 // "One" [Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("Destination Blend", Float) = 0 // "Zero" [Enum(UnityEngine.Rendering.CompareFunction)] _ZTest("Depth Test", Float) = 4 // "LessEqual" [Enum(DepthWrite)] _ZWrite("Depth Write", Float) = 1 // "On" } SubShader { Pass { Blend[_SrcBlend][_DstBlend] ZTest[_ZTest] ZWrite[_ZWrite] CGPROGRAM #pragma target 5.0 #pragma vertex vert #pragma fragment frag #pragma geometry geom #pragma multi_compile_instancing #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float4 color: COLOR; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2g { float4 pos : POSITION; float4 col : COLOR; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct g2f { float4 pos : SV_POSITION; float4 col : COLOR; UNITY_VERTEX_OUTPUT_STEREO }; fixed _PointSize; v2g vert(appdata v) { v2g o; UNITY_SETUP_INSTANCE_ID(v); UNITY_TRANSFER_INSTANCE_ID(v, o); o.pos = mul(unity_ObjectToWorld, v.vertex); o.col = v.color; return o; } [maxvertexcount(4)] void geom(point v2g p[1], inout TriangleStream triStream) { g2f pIn; UNITY_SETUP_INSTANCE_ID(p[0]); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(pIn); float3 up = float3(0, 1, 0); float3 look = _WorldSpaceCameraPos - p[0].pos; float dist = length(look); look.y = 0; look = normalize(look); float3 right = cross(up, look); float halfS = 0.5f * _PointSize * dist; 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[3] = float4(p[0].pos - halfS * right + halfS * up, 1.0f); v[2] = float4(p[0].pos - halfS * right - halfS * up, 1.0f); pIn.pos = UnityObjectToClipPos(v[0]); pIn.col = p[0].col; triStream.Append(pIn); pIn.pos = UnityObjectToClipPos(v[1]); pIn.col = p[0].col; triStream.Append(pIn); pIn.pos = UnityObjectToClipPos(v[2]); pIn.col = p[0].col; triStream.Append(pIn); pIn.pos = UnityObjectToClipPos(v[3]); pIn.col = p[0].col; triStream.Append(pIn); } float4 frag(g2f input) : COLOR { return input.col; } ENDCG } } }