UnityのShaderGraphを利用してSTYLY用のシェーダーを作成する

はじめに

Unity2018のShaderGraphを利用してシェーダーを作成し、これをUnity2017.4用のシェーダーコードに書き直す方法を解説します。

ShaderGraphはSTYLYへアップロードすることができませんが、 Unity2017.4用のシェーダーコードに移植することで、STYLY上へのアップロードが可能となります。  

※2020/04/14現在、STYLYの推奨バージョンはUnity 2019.3.6f1ですがShaderGraphは使用できておらず、対応中です。

STYLYと互換性のあるUnityバージョンはこちらからご確認ください。
https://document.styly.cc/doc/docs/en/creator/creator_plugin_intro/#%E5%AF%BE%E5%BF%9C%E3%81%99%E3%82%8Bunity%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6

ShaderGraphについて

ShaderGraphはノードベースでシェーダーを作成するツールで、視覚的にシェーダーを作成することができます。
 
ShaderGraph

ShaderGraph

 
詳しくはUnity公式サイトをご覧ください。
 
 
似たツールとしてはAmplify Shader EditorやShader Forgeなどがありますが、ここでは詳細は割愛します。
 

ShaderGraphの動作環境

ShaderGraphを使用するためにはUnity2018.3以降のバージョンのUnityが必要となります。  

ShaderGraphのサンプル

https://github.com/UnityTechnologies/ShaderGraph_ExampleLibrary https://github.com/rngtm/ShaderGraphExample  

ShaderGraphの導入

ここでは、Unity2018.3をインストールして実際にShaderGraphを導入するまでの手順を解説します。  

Unity2018.3インストール

今回はUnity Hubを利用して、Unity2018.3をインストールします。 Unity2018.3系をインストール済みの方はこの段落は読み飛ばして構いません。   まずは下記URLからUnity Hubをダウンロードしてインストールしてください。 https://docs.unity3d.com/ja/2018.1/Manual/GettingStartedInstallingHub.html  

Unity HubからUnity2018.3をインストールします。
Unity2018.3以降のバージョンのDownloadをクリック

Unity2018.3以降のバージョンのDownloadをクリック


 
Doneを選択してダウンロード・インストール開始

Doneを選択してダウンロード・インストール開始

 

Unityプロジェクトを作成

Unity2018.3系のUnityをインストールしたらUnityプロジェクトを作成しましょう。 ここで作成するUnityプロジェクトはSTYLY用Unityプロジェクト(Unity2017.4.0f1)とは無関係なものであることに注意してください。 シェーダーグラフのデータを作成する専用のUnityプロジェクトとなります。   UnityHubからUnity2018.3系を指定して、Unityプロジェクトを新規作成します。

 

PackageManager経由でShaderGraphをインストール

Package Managerを起動

Package Managerを起動

  パッケージ一覧が表示されますが、デフォルトではShaderGraphは隠れているため、 AdvancedをクリックしてShow preview packageを選びます。

Advancedをクリック

Advancedをクリック

 

ShaderGraphとRender-Pipeline.Lightweightをインストールします
 
ShaderGraphとRender-Pipeline.Lightweightをインストール

ShaderGraphとRender-Pipeline.Lightweightをインストール

 

Lightweight RPをUnityに登録

最後に、Lightweight Render PipelineをUnityに登録する必要があります。  

Lightweight Render Pipelineアセットを作成

Create > Rendering > Lightweight Render Pipeline Asset を選択し、Lightweight Render Pipelineアセットを作成します。

LWRPアセットを作成

Lightweight Render Pipeline アセットを作成


作成したLightweight Render Pipeline アセット

作成したLightweight Render Pipeline アセット

 

Lightweight Render Pipelineアセットを登録

Edit > Project Settings… を選び、設定ウィンドウを開きます。

Project Settingsウィンドウを開く

Project Settingsウィンドウを開く

  先ほど作成したLightweight Render Pipeline アセットを設定画面に登録します。

Lightweight Render Pipeline アセットを登録

Lightweight Render Pipeline アセットを登録

  長くなりましたが、以上でShaderGraphの導入は完了となります。

 

シェーダーグラフを作る

実際にシェーダーグラフを作ってみましょう。  

シェーダーグラフアセットの作成

Projectウィンドウ上で右クリック、Create > Shader > Unlit Graph を選択してシェーダーグラフのアセットを作成します。 今回は色を出したいだけなのでUnlit Graphを選択します。

Unlit シェーダーグラフを作成

Unlit シェーダーグラフを作成


作成されたシェーダーグラフ

作成されたシェーダーグラフ

 

シェーダーグラフを開く

このシェーダーグラフをダブルクリックすると、シェーダーグラフ編集ウィンドウが開きます。 Unlit Masterノードがただ一つ置いてあるシェーダーグラフになっています。

シェーダーグラフ編集画面

シェーダーグラフ編集画面

 

シェーダーグラフを板にくっつけてみる

シェーダーグラフからマテリアルを作成します。

マテリアルを作成

マテリアルを作成

  作成したマテリアルを適当なオブジェクトにくっつけます。 今回は Hierarchyの Create -> 3D Object -> Planeで作成した板にマテリアルをくっつけています。

マテリアルを板に登録

マテリアルを板に登録


マテリアルの登録結果

マテリアルの登録結果

 

色を変えてみる

Unlit Masterノードを見てみるとColorピンがあります。 これは最終的に出力する色の情報になっています。 このColorを緑色にして、ウィンドウ左上にあるSave Assetをクリックして保存してみましょう。

Unlit Masterノードの色を変える

Unlit Masterノードの色を変える

  板の色も緑色になりました。

色の変更結果

色の変更結果

 

テクスチャを表示してみる

次にテクスチャを表示してみましょう。

 

UVノードを追加

シェーダーグラフウィンドウでSpaceキーを入力し、uvと入力してEnterを押します。

UVノードの追加

  UVが追加されます。

UVノード

UVノード

  同様の手順でSample Texture 2Dノードを作成し、UVノードとUnlitノードを以下のように接続します。 Sample Texture 2Dノードにはテクスチャを登録しておきます。

テクスチャを表示するシェーダーグラフ

テクスチャを表示するシェーダーグラフ

シェーダーグラフを保存するとテクスチャの色が板に反映され、以下のような見た目になります。

 
板の見た目

板の見た目

 

シェーダーグラフをShaderLabへ移植

次に、このシェーダーグラフをShaderLabに移植してみましょう。 ShaderLabに移植することで、STYLYへアップロードできるようになります。  

Unlit Shaderの作成

まずはProjectウィンドウでCreate > Shader > Unlit Shaderを選択し、Unlitシェーダーファイルを作成します。

  作成したシェーダーの中身は以下のようになっています。

Shader "Unlit/NewUnlitShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}

 

Unlit Shaderで色を計算している部分

実際に色を出している部分は以下の部分です。

fixed4 frag (v2f i) : SV_Target
{
    // sample the texture
    fixed4 col = tex2D(_MainTex, i.uv);
    // apply fog
    UNITY_APPLY_FOG(i.fogCoord, col);
    return col;
}

テクスチャから色を取り出し、これにフォグをかけて最終的な色として出力するような処理になっています。  

テクスチャ色をそのまま出力するようにする

これを以下のように書き換えます。

fixed4 frag (v2f i) : SV_Target
{
    fixed4 col = tex2D(_MainTex, i.uv);
    return col;
}

テクスチャから色を取り出して出力するような処理になっており、 以下のシェーダーグラフと同じものになっています。

テクスチャを表示するシェーダーグラフ

テクスチャを表示するシェーダーグラフ

 

 

Unlitシェーダーとシェーダーグラフの対応関係

i.uvはUV座標を表しており、シェーダーグラフではUVノードに相当します。
tex2D()関数はテクスチャのuv位置から色を取り出す関数で、シェーダーグラフではSample Texture 2Dノードが相当します。
return命令は、色の値を返す命令で、シェーダーグラフではUnlit MasterノードのColorピンがこれに相当します。
 

ShaderGraphとShaderLabの対応

 

例2 : ノイズを作る

以下のようなノイズを表示してみましょう。

シェーダーグラフ

以下のようなシェーダーグラフを組むことで、ノイズを作ることができます。

ノイズを作るシェーダーグラフ

ノイズを作るシェーダーグラフ

 

ノードを部分的にShaderLabへ移植する

シェーダーグラフのノードはシェーダーコードで実装されており、
そのシェーダーコードをコピー&ペーストすることで全く同じものをShaderLab側で使えるようになります。
 
ノードを右クリックしてOpen Documentを選択することで、コードを見ることができます。

  Simple Noiseノードのドキュメントを開いた場合はWebブラウザで以下のドキュメントが開きます。 https://github.com/Unity-Technologies/ShaderGraph/wiki/Simple-Noise-Node   ドキュメントには以下のシェーダーコードが記載されているはずです。 下記コードはSimpleNoiseの中身のシェーダーコードとなっています。

inline float unity_noise_randomValue (float2 uv)
{
    return frac(sin(dot(uv, float2(12.9898, 78.233)))*43758.5453);
}

inline float unity_noise_interpolate (float a, float b, float t)
{
    return (1.0-t)*a + (t*b);
}

inline float unity_valueNoise (float2 uv)
{
    float2 i = floor(uv);
    float2 f = frac(uv);
    f = f * f * (3.0 - 2.0 * f);

    uv = abs(frac(uv) - 0.5);
    float2 c0 = i + float2(0.0, 0.0);
    float2 c1 = i + float2(1.0, 0.0);
    float2 c2 = i + float2(0.0, 1.0);
    float2 c3 = i + float2(1.0, 1.0);
    float r0 = unity_noise_randomValue(c0);
    float r1 = unity_noise_randomValue(c1);
    float r2 = unity_noise_randomValue(c2);
    float r3 = unity_noise_randomValue(c3);

    float bottomOfGrid = unity_noise_interpolate(r0, r1, f.x);
    float topOfGrid = unity_noise_interpolate(r2, r3, f.x);
    float t = unity_noise_interpolate(bottomOfGrid, topOfGrid, f.y);
    return t;
}

float t = 0.0;
for(int i = 0; i < 3; i++)
{
    float freq = pow(2.0, float(i));
    float amp = pow(0.5, float(3-i));
    t += unity_valueNoise(float2(UV.x*Scale/freq, UV.y*Scale/freq))*amp;
}
Out = t;
 

SimpleNoiseのコードをコピー&ペーストする

上記のシェーダーコードを.shaderファイルの中にペーストすることで
.shader内でもノイズが使えるようになりますが、そのままの形では使うことができません。
 
そこで、使える形にするために最後の8行を関数化、未定義の数(UVとScale)を定義します。
#define Scale 500
float unity_simpleNoise_float(float2 UV)
{
    float t = 0.0;
    for(int i = 0; i < 3; i++)
    {
        float freq = pow(2.0, float(i));
        float amp = pow(0.5, float(3-i));
        t += unity_valueNoise(float2(UV.x*Scale/freq, UV.y*Scale/freq))*amp;
    }
    return t;
}

  そしてShaderLabのfrag関数からこの関数を呼び出してノイズが表示されるようにして完成です。

fixed4 frag (v2f i) : SV_Target
{
    fixed4 col = unity_simpleNoise_float(i.uv);
    return col;
}

 

シェーダーコード全体

以下はシェーダーコード全体となります。
Shader "Unlit/NewUnlitShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            /// ここから SimpleNoise //////////////////////////////////////////////
            inline float unity_noise_randomValue (float2 uv)
            {
                return frac(sin(dot(uv, float2(12.9898, 78.233)))*43758.5453);
            }

            inline float unity_noise_interpolate (float a, float b, float t)
            {
                return (1.0-t)*a + (t*b);
            }

            inline float unity_valueNoise (float2 uv)
            {
                float2 i = floor(uv);
                float2 f = frac(uv);
                f = f * f * (3.0 - 2.0 * f);

                uv = abs(frac(uv) - 0.5);
                float2 c0 = i + float2(0.0, 0.0);
                float2 c1 = i + float2(1.0, 0.0);
                float2 c2 = i + float2(0.0, 1.0);
                float2 c3 = i + float2(1.0, 1.0);
                float r0 = unity_noise_randomValue(c0);
                float r1 = unity_noise_randomValue(c1);
                float r2 = unity_noise_randomValue(c2);
                float r3 = unity_noise_randomValue(c3);

                float bottomOfGrid = unity_noise_interpolate(r0, r1, f.x);
                float topOfGrid = unity_noise_interpolate(r2, r3, f.x);
                float t = unity_noise_interpolate(bottomOfGrid, topOfGrid, f.y);
                return t;
            }

            #define Scale 500
            float unity_simpleNoise_float(float2 UV)
            {
                float t = 0.0;
                for(int i = 0; i < 3; i++)
                {
                    float freq = pow(2.0, float(i));
                    float amp = pow(0.5, float(3-i));
                    t += unity_valueNoise(float2(UV.x*Scale/freq, UV.y*Scale/freq))*amp;
                }
                return t;
            }
            /// ここまで SimpleNoise //////////////////////////////////////////////

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = unity_simpleNoise_float(i.uv);
                return col;
            }
            ENDCG
        }
    }
}

 

例3 : 流れるシマシマ模様を作る

流れるシマシマ模様

流れるシマシマ模様


  以下のようなシェーダーグラフを組むと流れるシマシマ模様になります。

 

シマシマシェーダーグラフをShaderLabに移植する

このシマシマシェーダーグラフをShaderLabへ移植してみましょう。

 

シェーダーグラフが生成するShaderLabコードを表示

まず、Unlitマスターノードを右クリックして、Show Generated Codeを選択します。 Show Generated Codeを選択すると、シェーダーグラフをシェーダーコードとして表示することができます。

  実際には以下のようなシェーダーコードが表示されます。

  このシェーダーコードはUnity2018以降で提供されるScriptable Render Pipelineという仕組みの上で動いております。

そのため、残念ながらUnity2017上で動かすことができずSTYLYへのアップロードもできません。

  今回はこのシェーダーコードをUnity2017.4.0f1上で動くように移植し、STYLYへアップロードが可能な状態にする手順を解説します。  

生成されたコード内のfrag関数に相当する部分を探す

Show Generated Codeで生成されたシェーダーコードの中身を読んでいくとPopulateSurfaceData関数が見つかるはずです。

SurfaceDescription PopulateSurfaceData(SurfaceDescriptionInputs IN)
{
    SurfaceDescription surface = (SurfaceDescription)0;
    float4 _UV_5352AF33_Out = IN.uv0;
    float _Split_ADBF75FC_R = _UV_5352AF33_Out[0];
    float _Split_ADBF75FC_G = _UV_5352AF33_Out[1];
    float _Split_ADBF75FC_B = _UV_5352AF33_Out[2];
    float _Split_ADBF75FC_A = _UV_5352AF33_Out[3];
    float _Multiply_318DDBE1_Out;
    Unity_Multiply_float(_Split_ADBF75FC_R, 3, _Multiply_318DDBE1_Out);

    float _Add_45F8AE1E_Out;
    Unity_Add_float(_Multiply_318DDBE1_Out, _Time.y, _Add_45F8AE1E_Out);
    float _Fraction_BBF94AC3_Out;
    Unity_Fraction_float(_Add_45F8AE1E_Out, _Fraction_BBF94AC3_Out);
    float _Step_AA2EEF1D_Out;
    Unity_Step_float(_Fraction_BBF94AC3_Out, 0.5, _Step_AA2EEF1D_Out);
    surface.Color = (_Step_AA2EEF1D_Out.xxx);
    surface.Alpha = 1;
    surface.AlphaClipThreshold = 0;
    return surface;
}

  このPopulateSurfaceData関数の中身をfrag関数の中に張り付けます。

fixed4 frag (v2f i) : SV_Target
{
    SurfaceDescription surface = (SurfaceDescription)0;
    float4 _UV_5352AF33_Out = IN.uv0;
    float _Split_ADBF75FC_R = _UV_5352AF33_Out[0];
    float _Split_ADBF75FC_G = _UV_5352AF33_Out[1];
    float _Split_ADBF75FC_B = _UV_5352AF33_Out[2];
    float _Split_ADBF75FC_A = _UV_5352AF33_Out[3];
    float _Multiply_318DDBE1_Out;
    Unity_Multiply_float(_Split_ADBF75FC_R, 3, _Multiply_318DDBE1_Out);

    float _Add_45F8AE1E_Out;
    Unity_Add_float(_Multiply_318DDBE1_Out, _Time.y, _Add_45F8AE1E_Out);
    float _Fraction_BBF94AC3_Out;
    Unity_Fraction_float(_Add_45F8AE1E_Out, _Fraction_BBF94AC3_Out);
    float _Step_AA2EEF1D_Out;
    Unity_Step_float(_Fraction_BBF94AC3_Out, 0.5, _Step_AA2EEF1D_Out);
    surface.Color = (_Step_AA2EEF1D_Out.xxx);
    surface.Alpha = 1;
    surface.AlphaClipThreshold = 0;
    return surface;
}

 

Unity_Add_*** 系の関数をコピペ

生成コード中で以下の4つの関数が使用されているのでこれもコピペしてきます。

void Unity_Multiply_float (float A, float B, out float Out)
{
    Out = A * B;
}
void Unity_Add_float(float A, float B, out float Out)
{
    Out = A + B;
}
void Unity_Fraction_float(float In, out float Out)
{
    Out = frac(In);
}
void Unity_Step_float(float Edge, float In, out float Out)
{
    Out = step(Edge, In);
}

 

SurfaceDescriptionの削除

SurfaceDescription surface = (SurfaceDescription)0; の部分は削除します。
 

引数名の修正

frag関数の引数の変数名がiになっているのでこれをINへ変更します。 変更前

fixed4 frag (v2f i) : SV_Target

変更後

fixed4 frag (v2f IN): SV_Target

 

uvの参照名の修正

v2fの中ではuvという名前で定義されているため、以下の行のuv0をuvに修正します。 修正前

float4 _UV_5352AF33_Out = IN.uv0;

修正後

float4 _UV_5352AF33_Out = IN.uv;

 

uvの変数型の修正

INのuvはfloat2として定義されているため、左辺の変数型もfloat4からfloat2へ変更します。 修正前

float4 _UV_5352AF33_Out = IN.uv;

修正後

float2 _UV_5352AF33_Out = IN.uv;

 

uv要素参照の修正

float2やfloat4の各要素には以下のような構文でアクセスすることができます

float4 value = float4(1.0);
float x = value[0]; // x = value.xとおなじ
float y = value[1]; // y = value.yとおなじ
float z = value[2]; // z = value.zとおなじ
float w = value[3]; // w = value.wとおなじ

  今回、uv値はfloat2のためz成分とw成分が存在しません。 なので下記のコードを削除します。

float _Split_ADBF75FC_B = _UV_5352AF33_Out[2];
float _Split_ADBF75FC_A = _UV_5352AF33_Out[3];

 

returnの修正

surfaceデータに色やアルファ値を格納してreturnしていますが、今回は色情報(fixed4)を返すため、 下記のコードを削除します。

surface.Color = (_Step_AA2EEF1D_Out.xxx);
surface.Alpha = 1;
surface.AlphaClipThreshold = 0;
return surface;
 
代わりに、surface.Colorに代入している値を返すようにしてやります。
return _Step_AA2EEF1D_Out;

 

frag関数の修正結果

最終的にはfrag関数は以下のようになります。

fixed4 frag (v2f IN) : SV_Target
{
    float2 _UV_5352AF33_Out = IN.uv;
    float _Split_ADBF75FC_R = _UV_5352AF33_Out[0];
    float _Split_ADBF75FC_G = _UV_5352AF33_Out[1];

    float _Multiply_318DDBE1_Out;
    Unity_Multiply_float(_Split_ADBF75FC_R, 3, _Multiply_318DDBE1_Out
    float _Add_45F8AE1E_Out;
    Unity_Add_float(_Multiply_318DDBE1_Out, _Time.y, _Add_45F8AE1E_Out);
    float _Fraction_BBF94AC3_Out;
    Unity_Fraction_float(_Add_45F8AE1E_Out, _Fraction_BBF94AC3_Out);
    float _Step_AA2EEF1D_Out;
    Unity_Step_float(_Fraction_BBF94AC3_Out, 0.5, _Step_AA2EEF1D_Out

    return _Step_AA2EEF1D_Out;
}

 

Shaderコード全体

移植した後のシェーダーコード全体は以下になります。

Shader "Unlit/NewUnlitShader"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			// make fog work
			#pragma multi_compile_fog
			
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				float4 vertex : SV_POSITION;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				UNITY_TRANSFER_FOG(o,o.vertex);
				return o;
			}
			

            void Unity_Multiply_float (float A, float B, out float Out)
            {
                Out = A * B;
            }

            void Unity_Add_float(float A, float B, out float Out)
            {
                Out = A + B;
            }

            void Unity_Fraction_float(float In, out float Out)
            {
                Out = frac(In);
            }

            void Unity_Step_float(float Edge, float In, out float Out)
            {
                Out = step(Edge, In);
            }
			
			fixed4 frag (v2f IN) : SV_Target
			{
				float2 _UV_5352AF33_Out = IN.uv;
				float _Split_ADBF75FC_R = _UV_5352AF33_Out[0];
				float _Split_ADBF75FC_G = _UV_5352AF33_Out[1];

				float _Multiply_318DDBE1_Out;
				Unity_Multiply_float(_Split_ADBF75FC_R, 3, _Multiply_318DDBE1_Out);
				float _Add_45F8AE1E_Out;
				Unity_Add_float(_Multiply_318DDBE1_Out, _Time.y, _Add_45F8AE1E_Out);
				float _Fraction_BBF94AC3_Out;
				Unity_Fraction_float(_Add_45F8AE1E_Out, _Fraction_BBF94AC3_Out);
				float _Step_AA2EEF1D_Out;
				Unity_Step_float(_Fraction_BBF94AC3_Out, 0.5, _Step_AA2EEF1D_Out);

				return _Step_AA2EEF1D_Out;
			}
			ENDCG
		}
	}
}

 

例4 : ノイズ表現

縦のノイズと横のノイズを交互に表示

縦のノイズと横のノイズを交互に表示


縦のノイズと横のノイズを交互に表示するシェーダーグラフ

縦のノイズと横のノイズを交互に表示するシェーダーグラフ

 

ShaderLabへ移植

上記のノイズシェーダーを移植したものが以下になります。

Shader "Unlit/TwoNoiseShader"
{
    Properties
    {
		_MainTex ("Texture", 2D) = "white" {}
        Vector1_A6C402D7("TimePower", Float) = 8
		Vector1_E7DE3A15("Speed", Float) = 1.2
		Vector1_CFAA147C("NoiseScale", Float) = 500
    }
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			// make fog work
			#pragma multi_compile_fog
			
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				float4 vertex : SV_POSITION;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			
            float Vector1_A6C402D7;
            float Vector1_E7DE3A15;
            float Vector1_CFAA147C;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				UNITY_TRANSFER_FOG(o,o.vertex);
				return o;
			}

			/////////////////////////////////////////////////////
			inline float unity_noise_randomValue (float2 uv)
			{
				return frac(sin(dot(uv, float2(12.9898, 78.233)))*43758.5453);
			}

			inline float unity_noise_interpolate (float a, float b, float t)
			{
				return (1.0-t)*a + (t*b);
			}
			inline float unity_valueNoise (float2 uv)
			{
				float2 i = floor(uv);
				float2 f = frac(uv);
				f = f * f * (3.0 - 2.0 * f);

				uv = abs(frac(uv) - 0.5);
				float2 c0 = i + float2(0.0, 0.0);
				float2 c1 = i + float2(1.0, 0.0);
				float2 c2 = i + float2(0.0, 1.0);
				float2 c3 = i + float2(1.0, 1.0);
				float r0 = unity_noise_randomValue(c0);
				float r1 = unity_noise_randomValue(c1);
				float r2 = unity_noise_randomValue(c2);
				float r3 = unity_noise_randomValue(c3);

				float bottomOfGrid = unity_noise_interpolate(r0, r1, f.x);
				float topOfGrid = unity_noise_interpolate(r2, r3, f.x);
				float t = unity_noise_interpolate(bottomOfGrid, topOfGrid, f.y);
				return t;
			}

            void Unity_SimpleNoise_float(float2 UV, float Scale, out float Out)
            {
                float t = 0.0;

                float freq = pow(2.0, float(0));
                float amp = pow(0.5, float(3-0));
                t += unity_valueNoise(float2(UV.x*Scale/freq, UV.y*Scale/freq))*amp;

                freq = pow(2.0, float(1));
                amp = pow(0.5, float(3-1));
                t += unity_valueNoise(float2(UV.x*Scale/freq, UV.y*Scale/freq))*amp;

                freq = pow(2.0, float(2));
                amp = pow(0.5, float(3-2));
                t += unity_valueNoise(float2(UV.x*Scale/freq, UV.y*Scale/freq))*amp;

                Out = t;
            }

            void Unity_Multiply_float (float A, float B, out float Out)
            {
                Out = A * B;
            }

            void Unity_Add_float(float A, float B, out float Out)
            {
                Out = A + B;
            }

            void Unity_Fraction_float(float In, out float Out)
            {
                Out = frac(In);
            }

            void Unity_OneMinus_float(float In, out float Out)
            {
                Out = 1 - In;
            }

            void Unity_Power_float(float A, float B, out float Out)
            {
                Out = pow(A, B);
            }

            void Unity_Step_float(float Edge, float In, out float Out)
            {
                Out = step(Edge, In);
            }

            void Unity_Maximum_float(float A, float B, out float Out)
            {
                Out = max(A, B);
            }
			/////////////////////////////////////////////////////
			
			fixed4 frag (v2f IN) : SV_Target
			{
                float2 _UV_41543244_Out = IN.uv;
                float _Split_791929F1_R = _UV_41543244_Out[0];
                float _Split_791929F1_G = _UV_41543244_Out[1];
                // float _Split_791929F1_B = _UV_41543244_Out[2];
                // float _Split_791929F1_A = _UV_41543244_Out[3];
                float _Property_A34CC187_Out = Vector1_CFAA147C;
                float _SimpleNoise_7780AF9D_Out;
                Unity_SimpleNoise_float((_Split_791929F1_G.xx), _Property_A34CC187_Out, _SimpleNoise_7780AF9D_Out);
                float _Property_BB3AE4B0_Out = Vector1_E7DE3A15;
                float _Multiply_C7983931_Out;
                Unity_Multiply_float(_Property_BB3AE4B0_Out, _Time.y, _Multiply_C7983931_Out);

                float _Add_F4937AD1_Out;
                Unity_Add_float(_Multiply_C7983931_Out, 0.5, _Add_F4937AD1_Out);
                float _Fraction_DC83F623_Out;
                Unity_Fraction_float(_Add_F4937AD1_Out, _Fraction_DC83F623_Out);
                float _OneMinus_3CCE1B16_Out;
                Unity_OneMinus_float(_Fraction_DC83F623_Out, _OneMinus_3CCE1B16_Out);
                float _Property_652E266A_Out = Vector1_A6C402D7;
                float _Power_B837429A_Out;
                Unity_Power_float(_OneMinus_3CCE1B16_Out, _Property_652E266A_Out, _Power_B837429A_Out);
                float _Step_52333ACB_Out;
                Unity_Step_float(_SimpleNoise_7780AF9D_Out, _Power_B837429A_Out, _Step_52333ACB_Out);
                float2 _UV_DAF98106_Out = IN.uv;
                float _Split_22E8C67A_R = _UV_DAF98106_Out[0];
                float _Split_22E8C67A_G = _UV_DAF98106_Out[1];
                float _Property_9D173142_Out = Vector1_CFAA147C;
                float _SimpleNoise_BFF5A899_Out;
                Unity_SimpleNoise_float((_Split_22E8C67A_R.xx), _Property_9D173142_Out, _SimpleNoise_BFF5A899_Out);
                float _Fraction_8C0CEF59_Out;
                Unity_Fraction_float(_Multiply_C7983931_Out, _Fraction_8C0CEF59_Out);
                float _OneMinus_AEBC704A_Out;
                Unity_OneMinus_float(_Fraction_8C0CEF59_Out, _OneMinus_AEBC704A_Out);
                float _Property_78DB6EAB_Out = Vector1_A6C402D7;
                float _Power_8970AF46_Out;
                Unity_Power_float(_OneMinus_AEBC704A_Out, _Property_78DB6EAB_Out, _Power_8970AF46_Out);
                float _Step_83B2C153_Out;
                Unity_Step_float(_SimpleNoise_BFF5A899_Out, _Power_8970AF46_Out, _Step_83B2C153_Out);
                float _Maximum_A494F6AC_Out;
                Unity_Maximum_float(_Step_52333ACB_Out, _Step_83B2C153_Out, _Maximum_A494F6AC_Out);

				return _Maximum_A494F6AC_Out;
            }
			ENDCG
		}
	}
}

 

UnityからSTYLYにアセットをアップロードする方法

UnityからSTYLYへアセットをアップロードする方法については下記URLをご覧ください。 https://styly.cc/ja/manual/unity-asset-uploader/