結果
結果はこちら(gfycat)
Unityのshaderを初めて書いたのでメモ。
参考資料
参考:Moving vertices in shaders - Unity Answers
というかほとんど上のShaderコピーしたんですがこれをきっかけにもっとshader書けるようになりたいなって感じです。
コード
Shader "Custom/BekoBekoShader" {
Properties{
_MainTex("Texture", 2D) = "white" {}
_Amount("Height Adjustment", Float) = 1.0
}
SubShader{
Tags{ "RenderType" = "Opaque" }
CGPROGRAM
#pragma surface surf Lambert vertex:vert
struct Input {
float2 uv_MainTex;
float3 worldPos;
};
// Access the shaderlab properties
float _Amount;
sampler2D _MainTex;
float rand(float3 co)
{
return frac(sin(dot(co.xyz, float3(12.9898, 78.233, 45.5432))) * 43758.5453);
}
// Vertex modifier function
void vert( inout appdata_full v) {
// Do whatever you want with the "vertex" property of v here
//コメント部分を適用すると中心から円状に波が広がる
/*float mag = (v.vertex.x * v.vertex.x) + (v.vertex.z * v.vertex.z);
mag = sqrt(mag);*/
float mag = v.vertex.x + v.vertex.z;
v.vertex.y = sin(_Time * _Amount + mag) / 3;
}
// Surface shader function
void surf(Input IN, inout SurfaceOutput o) {
o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
}
ENDCG
}
FallBack "Diffuse"
}
解説をしようとするけど失敗するところ
UnityのShaderは大きく2つの部分に分けることができて、
Properties と SubShaderに分けられます。
Shader "名前"{
Properties{}
SubShader{
CGPROGRAM
ENDCG
}
}
ってことですね。
PropertiesはUnityのInspectorに出てくる変数ですね。
SubShaderの中から型指定して同じ変数名使えばPropertiesの変数にアクセスできます。(_Amount, _MainTexとか)
SubShaderは何個でも記述できて、ハードウェアに応じて上から順番にトライされて最終的にダメなら Fallbackで指定された名前のShaderをトライしていくって感じらしいです。
#pragma surface surf Lambert vertex:vert
ではVertex Shaderの関数がvertであると示すプリコンパイル命令的なものだと思います(雑)
この辺はまだちょっと理解できてません・・・
で vert 関数には特殊なシグネチャがあるのか、パラメータ増やそうとしたりすると怒られました。
見てのとおりググって適当に書いただけなのでコメントで指南いただけたらとてもうれしいです。
PS
Lambertってちょいちょい見るけどなんぞやと思ったのでググってみました。
Wikipedia: Lambertian Reflecance
要するにSpecularの逆で光がキレイに反射するよりDiffuse的に曇る、というか見る角度は関係なく光の影響を受けることを指すらしいです。
数式も簡単で素晴らしい
I_{D}=\mathbf{L}\cdot\mathbf{N} C I_{L}
I(D)が出てくる光、Lが光の単位ベクトル、Nが面の法線、Cが色、I(L)が光の大きさの場合のLambertian Reflectanceだそうです。
詳しくはWikipediaを読んでもらうといいんですが、簡潔に「光の向きと法線が近い角度であるほど明るく見える」ってだけの話です。
これから覚えること多そうですがとりあえずEarl Sweatshirtが風になびいたのでOKです。