ParinNoise
#include "UnityCG.cginc" float4 permute(float4 x){ return fmod(34.0 * pow(x, 2) + x, 289.0); } float2 fade(float2 t){ return 6.0 * pow(t, 5.0) - 15.0 * pow(t, 4.0) + 10.0 * pow(t, 3.0); } float4 taylorInvSqrt(float4 r) { return 1.79284291400159 - 0.85373472095314 * r; } #define DIV_289 0.0034602076124567474048442906 float mod289(float x) { return x - floor(x * DIV_289) * 289.0; } float PerlinNoise2D(float2 P){ float4 Pi = floor(P.xyxy) + float4(0.0, 0.0, 1.0, 1.0); float4 Pf = frac (P.xyxy) - float4(0.0, 0.0, 1.0,1.0); float4 ix = Pi.xzxz; float4 iy = Pi.yyww; float4 fx = Pf.xzxz; float4 fy = Pf.yyww; float4 i = permute(permute(ix) + iy); float4 gx = frac(i / 41.0) * 2.0 - 1.0 ; float4 gy = abs(gx) - 0.5 ; float4 tx = floor(gx + 0.5); gx = gx - tx; float2 g00 = float2(gx.x,gy.x); float2 g10 = float2(gx.y,gy.y); float2 g01 = float2(gx.z,gy.z); float2 g11 = float2(gx.w,gy.w); float4 norm = taylorInvSqrt(float4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); g00 *= norm.x; g01 *= norm.y; g10 *= norm.z; float n00 = dot(g00, float2(fx.x, fy.x)); float n10 = dot(g10, float2(fx.y, fy.y)); float n01 = dot(g01, float2(fx.z, fy.z)); float n11 = dot(g11, float2(fx.w, fy.w)); float2 fade_xy = fade(Pf.xy); float2 n_x = lerp(float2(n00, n01), float2(n10, n11), fade_xy.x); float n_xy = lerp(n_x.x, n_x.y, fade_xy.y); return 2.3 * n_xy; } float GetNoise(float2 xy,float scroll,float size){ xy *= size; xy += float2(scroll,1); float ns = PerlinNoise2D(xy) / 2 + 0.5f; return ns; }
Shader "Custom/TexBug" { Properties{ _MainTex("MainTex",2D) = "white"{} _Height("Height",float) = 1.8//アバターの足裏をゼロとした場合の頭頂部の位置、つまり身長 _Width("Width",float) = 0.3//アバターの中心からの横幅 _Digit("Digit",Range(1,10)) = 1 _ChangeFrec("ChangeFrec",Range(1,500)) = 1 //バグ発生個所の変更頻度 _MaxBoxSize("MaxBoxSize",Range(0,0.1)) = 0.1 _MaxNoiseLen("MaxNoiseLen",Range(0,0.5)) = 0.5 _BugLoop("BugLoop",Range(1,50)) = 30 _BugLineColor("BugLineColor",Color) = (1,0,0,1) _BugLineWidth("BugLineWidth",Range(0,0.01)) = 0.01 _BugSpd("BugSpd",Range(1,10)) = 3 _BugNum("BugNum",Range(1,20)) = 2 } SubShader{ Tags{"RenderType"="Opaque" "DisableBatching"="true"} //透明部分のあるテクスチャを使う場合 //Tags{"Queue" = "Transparent" "RenderType" = "Transparent"} //Blend SrcAlpha OneMinusSrcAlpha Lighting Off Pass{ CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "ParinNoise.cginc" struct appdata { float4 vertex:POSITION; float4 uv:TEXCOORD0; }; struct v2f { float4 pos:SV_POSITION; float4 uv:TEXCOORD0; float type:TEXCOORD1; }; float _PI = 3.141592; sampler2D _MainTex; float _Height; float _Width; float _Digit; float _ChangeFrec; float _MaxBoxSize; float _MaxNoiseLen; float _BugLoop; float4 _BugLineColor; float _BugLineWidth; float _BugSpd; float _BugNum; //0~1を返す float rand(float2 co){ return frac(sin(dot(co.xy ,float2(12.9898,78.233))) * 43758.5453); } float noise(float2 xy){ return frac(sin(dot(xy, float2(1000, 1000))) * 2000); } float NormalizeX(float x){ return x/_Width; } //-1~1に float NormalizeY(float y){ return y/_Height; } float Pow(float val,int times){ float res = 1; for(int k=0;k<times;k++){ res *= val; } return res; } float GetNumByTime(float digit,float change_frec){ int d = trunc(digit); float tm = _Time.y/change_frec*Pow(10,d); float mx = trunc(tm);//小数部3桁を整数部に移動 return frac(mx/10000);//整数部5桁を小数部に移動しそれのみxに代入 } //-1~1の値を取る float2 BugCenterPos(float av){ float x = rand(GetNumByTime(_Digit,_ChangeFrec)+av); float y = rand(float2(x,x)); x = (x - 0.5)*2; y = (y - 0.5)*2; //return float2(0,0); return float2(x,y); } //箱の距離関数 float rectangle(float2 p, float2 size){ return max(abs(p.x) - size.x/_Width, abs(p.y) - size.y/_Height); } float4 BugBoxFrame(float4 c,float2 p,float ActBoxSizeX,float ActBoxSizeY){ float leng = rectangle(p,float2(ActBoxSizeX+_BugLineWidth,ActBoxSizeY+_BugLineWidth)); return lerp(c,_BugLineColor,step(leng,0.001)); } float4 BugBoxCont(float4 c,float2 p,float ActBoxSizeX,float ActBoxSizeY){ float leng = rectangle(p,float2(ActBoxSizeX,ActBoxSizeY)); return lerp(c,float4(0,0,0,0),step(leng,0.001)); } v2f vert(appdata v){ v2f o = (v2f)0; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.uv; float nx = NormalizeX(v.vertex.x); float ny = NormalizeY(v.vertex.y); for(int j=0;j<_BugNum;j++){ float2 o_cpos = BugCenterPos(rand(j)); float time = GetNumByTime(_Digit,_ChangeFrec/_BugSpd); //unroll内の数値は_BugLoopに合わせて置き換える //ループ展開するだけのはずだが結果が変わる場合がある //[unroll(10)] for(int k=0;k<_BugLoop;k++){ float2 cpos = o_cpos; uint f = k - k % 2; //中心となる位置から少しずらしたランダムなBoxの位置 cpos.x = o_cpos.x + (noise(float2(rand(f+0.1+time),rand(f+0.2+time)))-0.5)*2*_MaxNoiseLen/_Width; cpos.y = o_cpos.y + (noise(float2(rand(f+0.3+time),rand(f+0.4+time)))-0.5)*2*_MaxNoiseLen/_Height; //_MaxBoxSizeを最大値としたランダムな数 float mx = rand(f+0.5+time)*_MaxBoxSize; float ActBoxSizeX = _MaxBoxSize - mx; //_MaxBoxSizeを最大値としたランダムな数 float my = rand(f+0.7+time)*_MaxBoxSize; float ActBoxSizeY = _MaxBoxSize - my; float2 p = float2(cpos.x-nx,cpos.y-ny); if(rectangle(p,float2(ActBoxSizeX,ActBoxSizeY))<0.00001){ o.type = 1;//clip(-1) return o; } if(rectangle(p,float2(ActBoxSizeX+_BugLineWidth,ActBoxSizeY+_BugLineWidth))<0.00001){ o.type = 2;//BugLineColor return o; } } } o.type = 0;//DefaultTex return o; } float4 frag(v2f i) :SV_Target { if(i.type >=0 && i.type < 0.66) return tex2D(_MainTex,i.uv); if(i.type >=0.66 && i.type < 1.32) clip(-1); if(i.type >=1.32 && i.type <=2 ) _BugLineColor; return float4(0,0,1,1); } ENDCG }//Pass }//SubShader //FallBack "Diffuse" }