シェーダでテクスチャを回転させてみます。
回転させる
まずは普通に回転させます。
Shader "Example" { Properties { [NoScaleOffset] _MainTex ("Texture", 2D) = "white" {} _RotateSpeed ("Rotate Speed", float) = 1.0 _Tiling ("Tiling", float) = 1.0 } SubShader { Tags { "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #define PI 3.141592 struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; float _RotateSpeed; float _Tiling; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target { // Timeを入力として現在の回転角度を作る half angle = frac(_Time.x) * PI * 2; // 回転行列を作る half angleCos = cos(angle * _RotateSpeed); half angleSin = sin(angle * _RotateSpeed); half2x2 rotateMatrix = half2x2(angleCos, -angleSin, angleSin, angleCos); // タイリング処理 i.uv = frac(i.uv * _Tiling); // 中心を起点にUVを回転させる i.uv = mul(i.uv - 0.5, rotateMatrix) + 0.5; fixed4 col = tex2D(_MainTex, i.uv); return col; } ENDCG } } }
コメントに書いた通りですが、まず回転行列を掛けてUVを回転させています。
結果は次のようになります。
タイリングを設定するとこんな感じになります。
タイリングしたセルごとに回転をずらす
次にタイリングしたセルごとに回転をずらしてみます。
Shader "Example" { Properties { [NoScaleOffset] _MainTex ("Texture", 2D) = "white" {} _RotateSpeed ("Rotate Speed", float) = 1.0 _Tiling ("Tiling", float) = 1.0 } SubShader { Tags { "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #define PI 3.141592 struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; float _RotateSpeed; float _Tiling; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target { // セルを計算する int2 cell = i.uv * _Tiling; // セルを回転角度の計算に依存させる half angle = frac(_Time.x + (cell.x + cell.y) * 0.01) * PI * 2; half angleCos = cos(angle * _RotateSpeed); half angleSin = sin(angle * _RotateSpeed); half2x2 rotateMatrix = half2x2(angleCos, -angleSin, angleSin, angleCos); i.uv = frac(i.uv * _Tiling); i.uv = mul(i.uv - 0.5, rotateMatrix) + 0.5; fixed4 col = tex2D(_MainTex, i.uv); return col; } ENDCG } } }
結果は次のようになります。
角度にディストーションを適用する
さらに、回転角度にディストーションテクスチャを設定できるようにします。
Shader "Example" { Properties { [NoScaleOffset] _MainTex ("Texture", 2D) = "white" {} [NoScaleOffset] _DistTex ("Distortion Texture", 2D) = "white" {} _RotateSpeed ("Rotate Speed", float) = 1.0 _Tiling ("Tiling", float) = 1.0 } SubShader { Tags { "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #define PI 3.141592 struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float2 uv2 : TEXCOORD1; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; sampler2D _DistTex; float4 _DistTex_ST; float _RotateSpeed; float _Tiling; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; o.uv2 = TRANSFORM_TEX(v.uv, _DistTex); return o; } fixed4 frag (v2f i) : SV_Target { // Distortionの値をangleに反映する half dist = tex2D(_DistTex, i.uv2).r; half angle = (frac(_Time.x) + dist) * PI * 2; half angleCos = cos(angle * _RotateSpeed); half angleSin = sin(angle * _RotateSpeed); half2x2 rotateMatrix = half2x2(angleCos, -angleSin, angleSin, angleCos); i.uv = frac(i.uv * _Tiling); i.uv = mul(i.uv - 0.5, rotateMatrix) + 0.5; fixed4 col = tex2D(_MainTex, i.uv); return col; } ENDCG } } }
試しにパーリンノイズテクスチャを適用すると結果はこんな感じになりました。