【uGUI】_TextureSampleAdd
UnityのUI用のデフォルトシェーダー(UI-Default.shader)の frag関数の中に下記のような処理があります。
half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
この _TextureSampleAdd って何だろうと思って調べてみました。
ちょうど Unity Forum に同じ質問をしている人がいました。
https://forum.unity.com/threads/what-does-_texturesampleadd-do.531422/
Alpha8フォーマットのテクスチャをUIで使用しているかどうかによって、エンジンが自動的に設定するものです。使用している場合は (1, 1, 1, 0) が設定され、使用していない場合は (0, 0, 0, 0) が設定されます。
だそうです。
Unityのリファレンスにも説明ありました。
その他欄に載ってます。
UI 専用に Unity によって自動的に設定されます。使用するテククチャが Alpha8 型 (値は (1,1,1,0) に設定) か、そうでないか (値は (0,0,0,0) に設定) に基づきます。
ところで、Alpha8って何だっけ?(昔調べたけど忘れた)となったので再度調べ直しました。リファレンスにはアルファのみのテクスチャとしか書いてませんね。
あとは、この記事がわかりやすいです。
調査したところ、Alpha8ではシェーダではRGBは0とみなされる為、_TextureSampleAddを(1,1,1,0)として加算し、白色にしているという状態でした。
Alpha8を使わなければ_TextureSampleAddは削除しても〜と思われるかもですが、Textは内部でAlpha8テクスチャを参照している様なので、同じシェーダを利用するとTextも暗くなってしまいます!
よって_TextureSampleAddをどうにかしたい時は「Alpha8の利用の有無」「Textでは更に別シェーダを用意する」などの考慮が必要そうです。
他のコードは何となく読み取れるけど一応調べてみました。
tex2D
uv座標(IN.texcoord)からテクスチャ(_MainTex)上のピクセルカラーを取得して返す関数
_MainTex
sampler2D _MainTex;
コード内で sampler2D型の_MainTex変数を定義しており、中身はInspectorで設定したテクスチャです。
IN.texcoord
フラグメントシェーダーへの入力を下記のように定義していて、texcoordはTEXCOORD0というセマンティクスであり、1番目のuv座標らしい。
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
Unityのリファレンスにも少し説明がありました。
-
POSITION
は頂点位置、一般的にはfloat3
かfloat4
です。 -
NORMAL
は通常の頂点で、一般的にはfloat3
です。 -
TEXCOORD0
は、第 1 の UV 座標で、一般的に、float2
,float3
,float4
です。 -
TEXCOORD1
,TEXCOORD2
,TEXCOORD3
は、それぞれ第 2、第 3、第 4 の UV 座標です。 -
TANGENT
は、(ノーマルマッピングで使用される)接線ベクトルで、一般的には、float4
です。 -
COLOR
は、頂点ごとの色で、一般的には、float4
です。
わからないことを調べ始めたら、別のわからないことが出てきて、それを調べてたら別のわからないことが出てきて... の繰り返しですね。
【uGUI】Imageに色を加算合成する
uGUIの画像に色を加算合成してみます。
参考記事はこちらです。
ビルトインシェーダーを複製してCustomUI-Add.shaderを作成します。
シェーダー名を変更します。
Shader "CustomUI/Add"
色を決定している箇所を変更します。
// half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd);
color.rgb += IN.color.rgb;
color.a *= IN.color.a;
Imageに変更したシェーダーを適用してカラーを変更します。
今回は赤に設定しました。
結果はこうなりました。
Unityのデフォルトでは、ImageのColorを変更した場合には乗算合成が行われますが、変更後のシェーダーでは加算処理が行われるようになっています。乗算の場合は黒にどんな色を乗算しても黒(0に何を掛け算しても0)になるため画像が暗く見えますが、加算の場合は白(1)に近づくため明るく見えます。
ただこの方法の場合、通常のUI-Defaultマテリアルとは別のマテリアルを作成する必要があるためドローコールが増えることになり、実際に適用するとなると問題になりそうな気もします。
【uGUI】Imageの色を反転する
UnityのuGUIのシェーダーのカスタマイズをしてみます。
以下の記事を参考にしました。
ビルドインシェーダーのダウンロード
まずは、組み込みシェーダーをダウンロードします。
過去のアーカイブをダウンロードできるページから、
使用しているUnityのバージョンのビルドインシェーダーを選択します。今回はUnity 2019.1.1f1、OSはMacで試しました。
ダウンロードした builtin_shaders-2019.1.1f1.zip を解凍して、DefaultResourcesExtra/UI/UI-Default.shaderをUnityプロジェクトの適当な箇所にドラッグ&ドロップしてインポートします。
カスタマイズの準備は完了しました。
シェーダーの変更
uGUIのImageの色を反転させます。インポートしたUI-Defaultシェーダーを複製して任意の名前にします(ここではCustomUI-Negaとしました)
まずはUI-Negaシェーダーを開いて3行目のシェーダー名を変更します
Shader "UI/Default"
を
Shader "CustomUI/Nega"
に変更します。
次に101行目の色を決定している箇所の下に
half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
この行を追加します。
color.rgb = 1 - color.rgb;
これでソースコードの変更は終了です。
シェーダーの適用
CustomUI-Negaを右クリックし、Create > Material とするとシェーダーが適用済のマテリアルが作成されます(知らなかった)。作成したマテリアルを適当なImageのMaterial欄にセットすれば完了です。
結果はこうなりました。