##Shaderなんもわからん
本当に何もわかりません。
なので結果的にいい感じになりましたというメモです。
##デモ
左手が今回いい感じになったShaderです。
透過しつつ、いい感じに立体感もあり、指が重なって二重に見えることはありません。
ちなみに右手はOculus Integration
の中に入っているHands_Transparent
です。
左手はそれをちょっと変えただけです。
##Shader
Shader "Custom/SemiTransparent" {
Properties {
_MainColor("_Color",Color) = (0,0,0,0)
_RimColor ("Rim Color", Color) = (0.26,0.19,0.16,0.0)
_RimPower ("Rim Power", Range(0.5,8.0)) = 3.0
}
SubShader {
Tags { "Queue" = "Transparent" }
LOD 200
Pass{
ZWrite On
ColorMask A
}
CGPROGRAM
#pragma surface surf Standard alpha:fade
#pragma target 3.0
struct Input {
float3 viewDir;
};
fixed4 _MainColor;
float4 _RimColor;
float _RimPower;
void surf (Input IN, inout SurfaceOutputStandard o) {
o.Albedo = _MainColor;
o.Alpha = _MainColor.a;
half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
o.Emission = _RimColor.rgb * pow (rim, _RimPower);
}
ENDCG
}
FallBack "Diffuse"
}
##float? half? fixed?
まず変数に見たことがないものがあって混乱しました。
Scriptリファレンスには下記のようにありました。
できるかぎり低い精度を使用します。これは iOS や Android などモバイルプラットフォームでは特に重要です。経験則から以下のようにします。
・ワールド空間の位置とテクスチャ座標には、float 型を使用してください。
・上記以外 (ベクトル、HDR カラーなど) には、half で始めます。必要なときだけ、増加します。
・テクスチャデータのとても簡易な操作には、fixed を使用します。
実際には、正確にはどの数の型を使用すべきかは、プラットフォームや GPU に依存します。
深く調べるとさらに難しいことが書いてありそうだったので、
現段階では返す数値の精度が違うとだけ覚えておきます。
##Pass
Passは簡単に言うとこんな感じに描画しますよってことらしいです。
複数回に分けて書くことができる(複数回に分けて描画することができる)みたいです。
Surface shader
はデフォルトではPassと書かれていないですが、
内部でPassとして展開されるそうです。
今回のshaderに当てはめると下記のようなイメージです。
SubShader {
Tags { "Queue" = "Transparent" }
LOD 200
Pass{
ZWrite On
ColorMask 0
}
/*本来は内部ではPassとして展開される処理*/
Pass{
CGPROGRAM
/*~省略~*/
ENDCG
}
}
つまり、今回書いたシェーダーにはPassが2つあるということになります。
主に追加したのは1パス目だけです。
なので、その説明をしていこうと思います。
##ZWrite1
ZWriteはDepth Bufferを書き込むかどうかOn,Offできます。
最初は意味不明でしたが、
Depth Buffer = 深度情報 = どっちが前にあるか(後ろにあるか)判別するための情報
という理解で着地しました。
Depth Buffer(深度情報)が与えられていない手のShaderを見るとよくわかります。
どの指が手前にあるのかを判別するZWriteをShader上でOnにしていないので、
人差し指より前側に他の指が描画されてしまっているということです。
##ColorMask
ColorMaskは使用するカラーチャンネル(RGBA)を指定することができます。
0
を指定するとすべてのチャンネルを無視することができるので何も書き込まれません。
つまり、1パス目はDepth Buffer(深度情報)を書き込むためだけのコードということです。
Pass{
ZWrite On
ColorMask 0
}
2パス目にZWrite On書いとけばいいんじゃないか?
と思って試しましたが、ダメでした。先にDepth Buffer(深度情報)を書き込んであげる必要があるようです。
##Shaderなんもわからん
本当に何もわからないので間違い、アドバイス等ありましたらよろしくお願いします。