シェーダーを作る際に、いちいち検索してやり方を調べるのがめんどくさかったので、コピペで基本的なシェーダーを作れるようにしました。
基本Unlitシェーダー想定です。
適用したい効果をコピペしてシェーダーを組み立ててください。
クリックすると展開します
↑のデフォルトテンプレートに↓の中で追加したい要素を追加していく形になります。
<不透明>
SubShader内
Tags { “RenderType”=”Opaque” }
<透明>
SubShader内
Tags { “RenderType” = “Transparent” }
Blend SrcAlpha OneMinusSrcAlpha //透明色の重ね方は←を変更する
<カットアウト>
Properties
_Cutoff (“Alpha cutoff”, Range(0,1)) = 0.5
SubShader内
Tags {“Queue”=”AlphaTest” “RenderType”=”TransparentCutout”}
Blend SrcAlpha OneMinusSrcAlpha
frag内
fixed4 c = カットアウトしたいテクスチャや色;
clip(c.a – _Cutoff);
<テクスチャ>
Properties
_MainTex (“MainTexture”, 2D) = “white” {}
vert内
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
frag内
fixed4 c = tex2D(_MainTex, i.uv);
<カラー>
Properties
_MainColor(“MainColor”,Color) = (1,1,1)
frag内
fixed4 c = 適用したい色、テクスチャなど * _MainColor;
<フォッグ>
vert内
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
UNITY_TRANSFER_FOG(o,o.vertex);
frag内
UNITY_APPLY_FOG(i.fogCoord, 最終的な計算が終わった色);
<ライト>
Pass内
Tags { “LightMode”=”ForwardBase”}
#include “Lighting.cginc”
v2f内
float3 normal : TEXCOORD1;
float4 diffuse : COLOR0;
vert内
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.normal = UnityObjectToWorldNormal(v.normal);
float3 lightDir = _WorldSpaceLightPos0.xyz; //ライトの方向
float3 normal = normalize(i.normal); //ポリゴンの法線方向
float luminance = saturate(dot(normal, lightDir)); //光具合
frag内
fixed4 c = fixed4(ライトを適用したい色やテクスチャ * _LightColor0 * luminance , アルファ値);
<ライトの範囲拡大>
トゥーンシェーダーなどに使用する手法。明るい範囲を広くする。↑のライトを実装した後frag内のluminanceを↓のように書き換える
frag内
float luminance = saturate(dot(normal, lightDir) * 0.5 + 0.5); //光具合
<影を落とす>
↓のパスをそのまま追加する。
追加する新たなパス
Pass
{
Tags {“LightMode”=”ShadowCaster”}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_shadowcaster
#include “UnityCG.cginc”
struct v2f {
V2F_SHADOW_CASTER;
};
v2f vert(appdata_base v)
{
v2f o;
TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
return o;
}
float4 frag(v2f i) : SV_Target
{
SHADOW_CASTER_FRAGMENT(i)
}
ENDCG
}
<影を受ける>
Pass内
Tags { “LightMode”=”ForwardBase”}
#pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap novertexlight
#include “AutoLight.cginc”
appdata内
float2 lightmapUV : TEXCOORD1;
v2f内
float4 pos : SV_POSITION; //←vertexをposに書き換えなければいけない
float3 worldPos : TEXCOORD2;
#ifdef UNITY_HALF_PRECISION_FRAGMENT_SHADER_REGISTERS
UNITY_LIGHTING_COORDS(TEXCOORDの使ってない番号,使ってない番号+1)
#else
UNITY_SHADOW_COORDS(TEXCOORDの使ってない番号)
#endif
vert内
v2f o;
UNITY_INITIALIZE_OUTPUT(v2f, o);
o.pos = UnityObjectToClipPos(v.vertex);
UNITY_TRANSFER_LIGHTING(o,v.lightmapUV.xy);
frag内
//attenuationという名前出ないとダメ。この中に受ける影のデータが来ている
UNITY_LIGHT_ATTENUATION(attenuation, i, i.worldPos);
fixed4 c = 影を落としたい色やテクスチャ * attenuation;
<環境光を受ける>
スカイボックスからのAmbientColorとライトプローブなどのベイクしてある光を適用します。ちゃんとStaticにしないと受け付けないようです。
vert内
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.diffuse.rgb = ShadeSH9(half4(UnityObjectToWorldNormal(v.normal), 1));
frag内
fixed4 c = fixed4(環境光を適用したい色やテクスチャ * i.diffuse.rgb , アルファ値);
<ライト+環境光+影を受ける>
↑のライトと環境光と影を受けるのに必要な物を追加した上で最終的な計算を↓にする
frag内
fixed4 c = fixed4 ( max ( i.diffuse.rgb, luminance * _LightColor0) * attenuation, 0 );
<ノーマルマップ>
Properties
_NormalMap (“Normal map”, 2D) = “bump” {}
appdata内
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float2 uv : TEXCOORD0;
v2f内
float4 pos : SV_POSITION;
float4 diffuse : COLOR0;
float2 uv : TEXCOORD0;
float3 worldPos : TEXCOORD1;
half3 tspace0 : TEXCOORD2;
half3 tspace1 : TEXCOORD3;
half3 tspace2 : TEXCOORD4;
Pass内
#include “Lighting.cginc”
sampler2D _NormalMap;
vert内
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _NormalMap); //←メインテクスチャがあるならそっちに
half3 worldNormal = UnityObjectToWorldNormal(v.normal);
//ノーマルマップ用の情報書き込み
half3 wTangent = UnityObjectToWorldDir(v.tangent.xyz);
half tangentSign = v.tangent.w * unity_WorldTransformParams.w;
half3 wBitangent = cross(worldNormal, wTangent) * tangentSign;
o.tspace0 = half3(wTangent.x, wBitangent.x, worldNormal.x);
o.tspace1 = half3(wTangent.y, wBitangent.y, worldNormal.y);
o.tspace2 = half3(wTangent.z, wBitangent.z, worldNormal.z);
frag内
// ノーマルマップを適用した法線方向を計算
half3 tnormal = UnpackNormal(tex2D(_NormalMap, i.uv));
half3 worldNormal;
worldNormal.x = dot(i.tspace0, tnormal);
worldNormal.y = dot(i.tspace1, tnormal);
worldNormal.z = dot(i.tspace2, tnormal);
//光の方向
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
//光具合
float luminance = saturate(dot(worldNormal, lightDir));
fixed4 c = fixed4(ライトを適用したい色やテクスチャ * _LightColor0 * luminance , アルファ値);
<ノーマルマップ+環境光>
↑のノーマルマップと環境光を追加した状態でfrag内の最後の計算を↓のように書き換える。
環境光が当たっている方向をカメラの向きで指定しているので少し不自然ではあるので各自のプロジェクトによって要調整
frag内
//環境光の光具合
float ambientLuminance = saturate(dot(worldNormal,UNITY_MATRIX_V[2].xyz));
fixed4 c = fixed4(ライトを適用したい色やテクスチャ * _LightColor0 * luminance , アルファ値) + i.diffuse * ambientLuminance;