【Unity】テクスチャをシンプルに歪ませるshaderの作成方法

備忘録もかねて、shaderでテクスチャを歪ませる方法を２つまとめました。

方法は２つになります！

ビックリするくらいシンプルです笑

- メインテクスチャをスクロールして歪ませる方法
- ノイズテクスチャをスクロールして歪ませる方法

## 環境
Unity 2018.3.8

## 使用するテクスチャ
### 水面テクスチャ
![CausticsTex.png](https://qiita-image-store.s3.amazonaws.com/0/314351/bc34e5d4-33d9-fffe-32f7-fb6ea13eb94f.png)

### パーリンノイズ
![perlinNoise.png](https://qiita-image-store.s3.amazonaws.com/0/314351/f50ca9d7-1823-ad39-1c58-ce7780df4a7b.png)


## メインテクスチャをスクロールして歪ませる方法
完成図はこちら
![distort1.gif](https://qiita-image-store.s3.amazonaws.com/0/314351/abcda5f8-bccc-9eef-3b16-d61dc23f74cd.gif)

先にソースは添付します。

```DistortMainScrollShader.shader
Shader "Custom/DistortMainScrollShader"
{
    Properties
    {

        _MainTex("Main", 2D) = "white" {}
        _NoiseTex("Noise", 2D) = "white" {}
        _Speed("Speed", Range(0, 1)) = 0.7
        _NoiseAmount("NoiseAmount", Range(0, 0.05)) = 0.025
        _Brightness("Brightness", Range(1, 10)) = 5
        _Color ("Color", Color) = (1, 1, 1, 1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque"}
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

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

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

            fixed4 _Color;
            float _Speed;
            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _NoiseTex;
            float _NoiseAmount;
            float _Brightness;

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

            fixed4 frag (v2f i) : SV_Target
            {
                float4 uvNoise= 2 * tex2D(_NoiseTex, i.uv) - 1;//0 - 1座標を-1 - 1に変換
                //i.uv.x += uvNoise.x * _NoiseAmount;//u座標も歪ませることも可能
                i.uv.y += _Time.x * _Speed + uvNoise.y * _NoiseAmount;
                fixed4 col = tex2D(_MainTex,i.uv) * _Color *  _Brightness;;
                return col;
            }
            ENDCG
        }
    }
}

```

イメージとしては、メインテクスチャがUVスクロール、ノイズテクスチャが固定された仕組みになります。

フェッチしたノイズテクスチャの情報を基に、メインテクスチャが歪むので、メインテクスチャを歪ませながら動かしたときに役立ちます！

## ノイズテクスチャをスクロールして歪ませる方法
一方で、こちらはノイズテクスチャをUVスクロール、そしてメインテクスチャを固定しています。

完成図はこちら
![distort2.gif](https://qiita-image-store.s3.amazonaws.com/0/314351/a85b0522-fcae-dbec-f6b3-9780196bc069.gif)

ソースは以下の通りです。

```DistortNoiseScrollShader.shader
Shader "Custom/DistortNoiseScrollShader"
{
    Properties
    {

        _MainTex("Main", 2D) = "white" {}
        _NoiseTex("Noise", 2D) = "white" {}
        _Speed("Speed", Range(0, 1)) = 0.7
        _NoiseAmount("NoiseAmount", Range(0, 0.05)) = 0.025
        _Brightness("Brightness", Range(1, 10)) = 5
        _Color ("Color", Color) = (1, 1, 1, 1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque"}
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

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

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

            fixed4 _Color;
            float _Speed;
            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _NoiseTex;
            float _NoiseAmount;
            float _Brightness;

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

            fixed4 frag (v2f i) : SV_Target
            {
                float2 nUv = i.uv;
                nUv.y += _Time.x * _Speed;
                float4 uvNoise= 2 * tex2D(_NoiseTex, nUv) -1 ;//0 - 1座標を-1 - 1に変換
                i.uv += uvNoise.xy * _NoiseAmount;
                fixed4 col = tex2D(_MainTex,i.uv);
                return col * _Color * _Brightness;
            }
            ENDCG
        }
    }
}

```

こちらは固定されたUV座標にて、スクロールするノイズテクスチャをフェッチ。その情報で、メインテクスチャを歪ませています。

このやり方はノーマルマップを基に、テクスチャを歪ますなど、様々なテクニックに応用できます！

例えば、こんな感じのことができます(ノーマルマップでの歪み)

![wave3.gif](https://qiita-image-store.s3.amazonaws.com/0/314351/aaeec0ab-583f-54e3-1f7f-5e7d5e20b3af.gif)

## 最後に
いかがだったでしょうか。

ご覧になった方々のお役に立てたら嬉しいです！

一読して下さり、ありがとうございましたm(_ _)m