NinaShader

Unity Shader 学習メモ

【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/

f:id:ninagreen:20190602150724p:plain

Alpha8フォーマットのテクスチャをUIで使用しているかどうかによって、エンジンが自動的に設定するものです。使用している場合は (1, 1, 1, 0) が設定され、使用していない場合は (0, 0, 0, 0) が設定されます。

だそうです。

 

Unityのリファレンスにも説明ありました。

docs.unity3d.com

その他欄に載ってます。

UI 専用に Unity によって自動的に設定されます。使用するテククチャが Alpha8 型 (値は (1,1,1,0) に設定) か、そうでないか (値は (0,0,0,0) に設定) に基づきます。

 

ところで、Alpha8って何だっけ?(昔調べたけど忘れた)となったので再度調べ直しました。リファレンスにはアルファのみのテクスチャとしか書いてませんね。

docs.unity3d.com

 

あとは、この記事がわかりやすいです。

logicalbeat.jp

 

調査したところ、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のリファレンスにも少し説明がありました。

docs.unity3d.com

 

  • POSITION は頂点位置、一般的には float3 か float4 です。
  • NORMAL は通常の頂点で、一般的には float3 です。
  • TEXCOORD0 は、第 1 の UV 座標で、一般的に、float2float3float4 です。
  • TEXCOORD1TEXCOORD2TEXCOORD3 は、それぞれ第 2、第 3、第 4 の UV 座標です。
  • TANGENT は、(ノーマルマッピングで使用される)接線ベクトルで、一般的には、 float4 です。
  • COLOR は、頂点ごとの色で、一般的には、 float4 です。

わからないことを調べ始めたら、別のわからないことが出てきて、それを調べてたら別のわからないことが出てきて... の繰り返しですね。 

【uGUI】Imageに色を加算合成する

uGUIの画像に色を加算合成してみます。

参考記事はこちらです。

www.shibuya24.info

 

ビルトインシェーダーを複製して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に変更したシェーダーを適用してカラーを変更します。

今回は赤に設定しました。

f:id:ninagreen:20190602045651p:plain

 

結果はこうなりました。

f:id:ninagreen:20190602045709p:plain

 

Unityのデフォルトでは、ImageのColorを変更した場合には乗算合成が行われますが、変更後のシェーダーでは加算処理が行われるようになっています。乗算の場合は黒にどんな色を乗算しても黒(0に何を掛け算しても0)になるため画像が暗く見えますが、加算の場合は白(1)に近づくため明るく見えます。

 

ただこの方法の場合、通常のUI-Defaultマテリアルとは別のマテリアルを作成する必要があるためドローコールが増えることになり、実際に適用するとなると問題になりそうな気もします。

 

 

【uGUI】Imageの色を反転する

UnityのuGUIのシェーダーのカスタマイズをしてみます。

以下の記事を参考にしました。

tsubakit1.hateblo.jp

 

ビルドインシェーダーのダウンロード

まずは、組み込みシェーダーをダウンロードします。

過去のアーカイブをダウンロードできるページから、

unity3d.com

 

使用しているUnityのバージョンのビルドインシェーダーを選択します。今回はUnity 2019.1.1f1、OSはMacで試しました。

f:id:ninagreen:20190602033646p:plain

 

ダウンロードした builtin_shaders-2019.1.1f1.zip を解凍して、DefaultResourcesExtra/UI/UI-Default.shaderをUnityプロジェクトの適当な箇所にドラッグ&ドロップしてインポートします。

f:id:ninagreen:20190602034057p:plain

 

カスタマイズの準備は完了しました。

 

シェーダーの変更

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欄にセットすれば完了です。

結果はこうなりました。

f:id:ninagreen:20190602041849p:plain