知識0からのUnityShader勉強

知識0からのUnityShader勉強

UnityのShaderをメインとして、0から学んでいくブログです。

【UnityShader】ノイズシェーダー拡張【2.5】#46

前回の成果

パーリンノイズについて理解した。

soramamenatan.hatenablog.com


今回やること

前回勉強したパーリンノイズを活かして、ノイズで着色をします。

sasanon.hatenablog.jp


事前準備

Scene上にPlaneを配置します。
そして、今回制作するmaterialをPlaneにアタッチしてください。

f:id:soramamenatan:20200329114152p:plain


ソースコード

Shader "Unlit/GradationNoise" {
    Properties {
        _NoiseTilingOffset("NoiseTex Tiling(x, y) / Offset(z, w)", Vector) = (0.1, 0.1, 0.0)
        _NoiseSizeScroll("NoiseTex Size(x, y) / Scroll(z, w)", Vector) = (16, 16, 0, 0)
        _BaseColor("Base Color", Color) = (1, 1, 1, 1)
        _GradationClolor("Gradation Color", Color) = (1, 1, 1, 1)
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "extensionNoiseUtil.cginc"

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

            struct v2f {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            fixed4 _NoiseTilingOffset;
            fixed4 _NoiseSizeScroll;
            fixed4 _BaseColor;
            fixed4 _GradationClolor;

            v2f vert (appdata v) {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_NOISE_TEX(v.uv, _NoiseTilingOffset, _NoiseSizeScroll);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target {
                fixed p = perlinNoise(i.uv, _NoiseSizeScroll.xy);
                return lerp(_GradationClolor, _BaseColor, p);
            }
            ENDCG
        }
    }
}

extensionNoiseUtil.cgincについてはこちらを参照してください。

soramamenatan.hatenablog.com


パーリンノイズで空模様を表現

プロパティを以下のように設定します。

f:id:soramamenatan:20200329114731p:plain

パーリンノイズは元々雲模様に近いので、グラデーションと組み合わせることにより、より雲のような表現に近づけることができます。

f:id:soramamenatan:20200329114712g:plain


タイリングの調整

タイリングが1未満の範囲で拡大、縮小ができます。


事前準備

Scene上にCubeを配置し、materialをアタッチします。

f:id:soramamenatan:20200329121057p:plain


結果

タイリングの値を(0.1, 0.02)にする(UV比5 : 1)と木目のようなテクスチャになります。

プロパティ

f:id:soramamenatan:20200329120053p:plain

見た目

f:id:soramamenatan:20200329120043p:plain

このタイリングを(1.0, 0.02)にする(UV比50 : 1)と木目が細かくなります。

プロパティ

f:id:soramamenatan:20200329120055p:plain

見た目

f:id:soramamenatan:20200329120047p:plain


風を表現する

最後に風のようなエフェクトを表現します。
まず、Shaderに下記ソースコードのように変更します。

// 上部省略
SubShader {
    // 変更点
    Tags { "RenderType"="Transparent" "Queue" = "Transparent"}
    LOD 100
    ZWrite Off
    Blend SrcAlpha OneMinusSrcAlpha
    // ここまで
    Pass {
// 下部省略

備忘録

ZWrite Off

オブジェクトのピクセルをデプスバッファに書き込むかを判断します。

On/Off 用途
On 不透明なオブジェクトを描画する場合
Off 部分的に透過のエフェクトを描く場合
Blend

ブレンディングのことです。
SrcAlpha OneMinusSrcAlphaは一般的な透過に使用します。
詳しくはこちらを参照してください。
【UnityShader】テクスチャのカリング #19 - 知識0からのUnityShader勉強

これで透過したノイズを表現できるようになったので、プロパティを変更していきます。


事前準備

Scene上にPlaneを用意し、materialをアタッチします。

f:id:soramamenatan:20200329114152p:plain


結果

グラデーションが透過できれば成功です。

プロパティ

f:id:soramamenatan:20200329131603p:plain

見た目

f:id:soramamenatan:20200329131544g:plain


MainTexと合成

マスク画像を使用することにより、風っぽさを向上させることができます。

ソースコード

Shader "Unlit/GradationNoiseWind" {
    Properties {
        // 追加
        _MainTex ("Texture", 2D) = "white" {}
        _NoiseTilingOffset("NoiseTex Tiling(x, y) / Offset(z, w)", Vector) = (0.1, 0.1, 0.0)
        _NoiseSizeScroll("NoiseTex Size(x, y) / Scroll(z, w)", Vector) = (16, 16, 0, 0)
        _BaseColor("Base Color", Color) = (1, 1, 1, 1)
        _GradationClolor("Gradation Color", Color) = (1, 1, 1, 1)
    }
    SubShader {
        Tags { "RenderType"="Transparent" "Queue" = "Transparent"}
        LOD 100
        ZWrite Off
        Blend SrcAlpha OneMinusSrcAlpha

        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "extensionNoiseUtil.cginc"

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

            struct v2f {
                float2 uv : TEXCOORD0;
                // 追加
                float2 texuv : TEXCOORD1;
                float4 vertex : SV_POSITION;
            };
            // 追加
            sampler2D _MainTex;
            // 追加
            float4 _MainTex_ST;
            fixed4 _NoiseTilingOffset;
            fixed4 _NoiseSizeScroll;
            fixed4 _BaseColor;
            fixed4 _GradationClolor;

            v2f vert (appdata v) {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_NOISE_TEX(v.uv, _NoiseTilingOffset, _NoiseSizeScroll);
                // 追加
                o.texuv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target {
                fixed p = perlinNoise(i.uv, _NoiseSizeScroll.xy);
                // 変更
                return lerp(_GradationClolor, _BaseColor, p) * tex2D(_MainTex, i.texuv);
            }
            ENDCG
        }
    }
}

MainTexの処理を追加して、最後に乗算してあげます。


結果

MainTexと合成できれば成功です。
今回は、Unityのデフォルトで存在するDefault-ParticleをMainTexにしています。
風というよりは、月夜のようになりました。

プロパティ

f:id:soramamenatan:20200329133707p:plain

見た目

f:id:soramamenatan:20200329133711g:plain

今回は以上となります。
ここまでご視聴ありがとうございました。