Created
January 19, 2018 09:28
-
-
Save kaiware007/8ebad2d28638ff83b6b74970a4f70c9a to your computer and use it in GitHub Desktop.
Simple Billboard shader for Unity
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Shader "Unlit/Billboard" | |
{ | |
Properties | |
{ | |
_MainTex ("Texture", 2D) = "white" {} | |
} | |
SubShader | |
{ | |
Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "DisableBatching" = "True" } | |
ZWrite Off | |
Blend SrcAlpha OneMinusSrcAlpha | |
Pass | |
{ | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
// make fog work | |
#pragma multi_compile_fog | |
#include "UnityCG.cginc" | |
struct appdata | |
{ | |
float4 vertex : POSITION; | |
float2 uv : TEXCOORD0; | |
}; | |
struct v2f | |
{ | |
float2 uv : TEXCOORD0; | |
UNITY_FOG_COORDS(1) | |
float4 pos : SV_POSITION; | |
}; | |
sampler2D _MainTex; | |
float4 _MainTex_ST; | |
v2f vert (appdata v) | |
{ | |
v2f o; | |
o.pos = UnityObjectToClipPos(v.vertex); | |
o.uv = v.uv.xy; | |
// billboard mesh towards camera | |
float3 vpos = mul((float3x3)unity_ObjectToWorld, v.vertex.xyz); | |
float4 worldCoord = float4(unity_ObjectToWorld._m03, unity_ObjectToWorld._m13, unity_ObjectToWorld._m23, 1); | |
float4 viewPos = mul(UNITY_MATRIX_V, worldCoord) + float4(vpos, 0); | |
float4 outPos = mul(UNITY_MATRIX_P, viewPos); | |
o.pos = outPos; | |
UNITY_TRANSFER_FOG(o,o.vertex); | |
return o; | |
} | |
fixed4 frag (v2f i) : SV_Target | |
{ | |
// sample the texture | |
fixed4 col = tex2D(_MainTex, i.uv); | |
// apply fog | |
UNITY_APPLY_FOG(i.fogCoord, col); | |
return col; | |
} | |
ENDCG | |
} | |
} | |
} |
Shader "Unit/Fx_BillBoard"
{
Properties
{
[Enum(UnityEngine.Rendering.BlendMode)]_Src("Src", Float) = 1
[Enum(UnityEngine.Rendering.BlendMode)]_Dst("Dst", Float) = 1
_MainTex("MainTex", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" "Queue"="Transparent" "PreviewType"="Plane" }
LOD 100
CGINCLUDE
#pragma target 3.0
ENDCG
Blend [_Src] [_Dst], SrcAlpha OneMinusSrcAlpha
AlphaToMask Off
Cull Off
ColorMask RGBA
ZWrite Off
ZTest LEqual
Stencil
{
Ref 255
CompFront Always
PassFront Keep
FailFront Keep
ZFailFront Keep
CompBack Always
PassBack Keep
FailBack Keep
ZFailBack Keep
}
Pass
{
Name "Unlit"
Tags { "LightMode"="ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_instancing
#include "UnityCG.cginc"
#include "UnityShaderVariables.cginc"
struct appdata
{
float4 vertex : POSITION;
float4 color : COLOR;
float3 ase_normal : NORMAL;
float4 ase_tangent : TANGENT;
float4 ase_texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
#ifdef ASE_NEEDS_FRAG_WORLD_POSITION
float3 worldPos : TEXCOORD0;
#endif
float4 ase_texcoord1 : TEXCOORD1;
float4 ase_color : COLOR;
};
uniform float _Src;
uniform float _Dst;
uniform sampler2D _MainTex;
uniform float4 _MainTex_ST;
v2f vert ( appdata v )
{
v2f o;
//Calculate new billboard vertex position and normal;
float3 upCamVec = normalize ( UNITY_MATRIX_V._m10_m11_m12 );
float3 forwardCamVec = -normalize ( UNITY_MATRIX_V._m20_m21_m22 );
float3 rightCamVec = normalize( UNITY_MATRIX_V._m00_m01_m02 );
float4x4 rotationCamMatrix = float4x4( rightCamVec, 0, upCamVec, 0, forwardCamVec, 0, 0, 0, 0, 1 );
v.ase_normal = normalize( mul( float4( v.ase_normal , 0 ), rotationCamMatrix )).xyz;
v.ase_tangent.xyz = normalize( mul( float4( v.ase_tangent.xyz , 0 ), rotationCamMatrix )).xyz;
//This unfortunately must be made to take non-uniform scaling into account;
//Transform to world coords, apply rotation and transform back to local;
v.vertex = mul( v.vertex , unity_ObjectToWorld );
v.vertex = mul( v.vertex , rotationCamMatrix );
v.vertex = mul( v.vertex , unity_WorldToObject );
o.ase_texcoord1.xy = v.ase_texcoord.xy;
o.ase_color = v.color;
//setting value to unused interpolator channels and avoid initialization warnings
o.ase_texcoord1.zw = 0;
o.vertex = UnityObjectToClipPos(v.vertex);
#ifdef ASE_NEEDS_FRAG_WORLD_POSITION
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
#endif
return o;
}
fixed4 frag (v2f i ) : SV_Target
{
float2 uv_MainTex = i.ase_texcoord1.xy * _MainTex_ST.xy + _MainTex_ST.zw;
float4 finalColor = tex2D( _MainTex, uv_MainTex);
return finalColor;
}
ENDCG
}
}
}
Same code, but rewritten to match URP shader style.
float3 vpos = TransformObjectToWorldDir(IN.vertex, false); float3 worldCoord = GetObjectToWorldMatrix()._m03_m13_m23; float3 viewPos = TransformWorldToView(worldCoord) + vpos; OUT.vertex = TransformWViewToHClip(viewPos);
Here's an URP version using the code above https://gist.github.com/alhvi/f117a7d36bf581d8dfa0906fbb48daca
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Third line should be:
float3 viewPos = TransformWorldToView(worldCoord) + float3(-vpos.x, vpos.y, vpos.z);
otherwise what we see is the back of plane (set to "cull back" then you will see)