phiさんのfuwaパーティクルからビルボード以外の機能を除去したバッチングありでビルボードが可能なコードです。クリップ空間でビルボードをしている。
GitHub - phi16/VRC_storage: assets distribution
//original-code //https://github.com/phi16/VRC_storage#fuwaparticle Shader "Arumogina-Phi16/BillboardOnClip"{ Properties{ _Size ("Particle Size", Float) = 1.0 } SubShader{ Tags { "RenderType"="Transparent" "Queue"="Transparent" } LOD 100 Cull Off Blend SrcAlpha One ZWrite Off Pass{ CGPROGRAM #pragma vertex vert #pragma geometry geom #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2g { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct g2f { float4 vertex : SV_POSITION; float2 uv : TEXCOORD0; }; float _Size; v2g vert (appdata v){ v2g o; o.vertex = v.vertex; o.uv = v.uv.xy; return o; } [maxvertexcount(4)] void geom (triangle v2g vg[3], inout TriangleStream<g2f>stream) { g2f o; float size = 1.0; float3 p = 0, v = 0; //quadの中心点 float3 quad_center = (vg[0].vertex.xyz + vg[1].vertex.xyz)/2; p = quad_center; float4 vp1 = UnityObjectToClipPos(float4(p, 1)); //height/width float aspectRatio = - UNITY_MATRIX_P[0][0] / UNITY_MATRIX_P[1][1]; float2 vd = float2(1,0); float2 vn = float2(0,1); float sz = _Size; vd *= sz, vn *= sz; vd.x *= aspectRatio, vn.x *= aspectRatio; /* 基本的な原理: メッシュがクリップ空間に変換された場合の中心点を取得=>vp1 その中心点から4方向に伸ばした頂点をappendすることでquadになる。 この点はクリップ空間、つまり2dの画面上伸ばしてるのでBillboardと同様になる */ o.uv = float2(-1,-1); o.vertex = vp1+float4(vd+vn,0,0); stream.Append(o); o.uv = float2(-1,1); o.vertex = vp1+float4(vd-vn,0,0); stream.Append(o); o.uv = float2(1,-1); o.vertex = vp1+float4(-vd+vn,0,0); stream.Append(o); o.uv = float2(1,1); o.vertex = vp1+float4(-vd-vn,0,0); stream.Append(o); stream.RestartStrip(); } fixed4 frag (g2f i) : SV_Target{ return 1; } ENDCG } } }