Unity Billboard shader
Shader "CPC_UnlitBillboard" { Properties { [Toggle]_USE_CPB("USE_CPB", Float) = 0 _TextureSample0("Texture Sample 0", 2D) = "white" {} _AlphaClipThreshold("AlphaClipThreshold", Float) = 0.1 _Color0("Color 0", Color) = (0,0,0,0) _Emission("Emission", Float) = 0 _EmissivePow("EmissivePow", Float) = 0 [Toggle]_USE_DFade_Inverse("USE_DFade_Inverse", Float) = 1 _FadeDist("FadeDist", Float) = 40 [HideInInspector] _texcoord("", 2D) = "white" {} [HideInInspector] __dirty("", Int) = 1 } SubShader { //Tags { "RenderType" = "Opaque" } Tags { "RenderType" = "TransparentCutout" "Queue" = "Transparent+0" } Cull Back LOD 100 Pass { ZTest Off Blend SrcAlpha OneMinusSrcAlpha Cull Off CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_instancing #include "UnityCG.cginc" #include "UnityShaderVariables.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float4 color : COLOR; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; float4 color : COLOR0; UNITY_VERTEX_INPUT_INSTANCE_ID // necessary only if you want to access instanced properties in fragment Shader. }; struct Input { float4 screenPosition : TEXCOORD1; float3 worldPos : TEXCOORD2; }; sampler2D _TextureSample0; float4 _TextureSample0_ST; UNITY_INSTANCING_BUFFER_START(Props) UNITY_DEFINE_INSTANCED_PROP(float4, _Color0) UNITY_DEFINE_INSTANCED_PROP(half, _USE_CPB) UNITY_DEFINE_INSTANCED_PROP(float, _Emission) UNITY_DEFINE_INSTANCED_PROP(float, _EmissivePow) UNITY_DEFINE_INSTANCED_PROP(float, _USE_DFade_Inverse) UNITY_DEFINE_INSTANCED_PROP(float, _FadeDist) UNITY_DEFINE_INSTANCED_PROP(float, _AlphaClipThreshold) UNITY_INSTANCING_BUFFER_END(Props) inline float Dither4x4Bayer(int x, int y) { const float dither[16] = { 1, 9, 3, 11, 13, 5, 15, 7, 4, 12, 2, 10, 16, 8, 14, 6 }; int r = y * 4 + x; return dither[r] / 16; // same # of instructions as pre-dividing due to compiler magic } v2f vert(appdata v, out Input g) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_TRANSFER_INSTANCE_ID(v, o); // necessary only if you want to access instanced properties in the fragment Shader. float4 worldOrigin = mul(UNITY_MATRIX_M, float4(0, 0, 0, 1)); float4 viewOrigin = float4(UnityObjectToViewPos(float3(0, 0, 0)), 1); float4 worldPos = mul(UNITY_MATRIX_M, v.vertex); g.screenPosition = ComputeScreenPos(v.vertex); g.worldPos = worldPos; float4 viewPos = worldPos - worldOrigin + viewOrigin; // the tutorial's way of doing it for billboarding //float4 viewPos = mul(UNITY_MATRIX_V, worldPos); // the normal way, basically turns it into an unlit shader float4 clipsPos = mul(UNITY_MATRIX_P, viewPos); o.vertex = clipsPos; o.uv = TRANSFORM_TEX(v.uv, _TextureSample0); return o; } fixed4 frag(v2f i) : SV_Target { // sample the texture //fixed4 col = UNITY_ACCESS_INSTANCED_PROP(Props, _Color0) * tex2D(_TextureSample0, i.uv); half2 b1 = (mul(unity_WorldToObject, half4(_WorldSpaceCameraPos.xyz, 1.0))).xy; half t1 = ((atan2(b1.x, b1.y) / UNITY_PI) * 180.0); half t2 = 0; if (t1 >= 0.0) t2 = t1; else t2 = t1 + 360.0; half v1 = floor((t2 / 360.0) * 8.0); half2 r1 = half2(v1 * 0.25, 0); half2 r2 = half2((v1 - 4.0) * 0.25, 0.5); half2 r3 = 0; if (v1 >= 4.0) r3 = r1; else r3 = r2; half2 uv1 = i.uv * float2(0.25, 0.5) + r3; half4 tex2D1 = tex2D(_TextureSample0, UNITY_ACCESS_INSTANCED_PROP(Props, _USE_CPB) ? uv1 : i.uv); fixed4 col = UNITY_ACCESS_INSTANCED_PROP(Props, _Color0) * tex2D1; UNITY_SETUP_INSTANCE_ID(i); // necessary only if any instanced properties are going to be accessed in the fragment Shader. return col; //return col; } ENDCG } } }
댓글
댓글 쓰기