イラスト、モデリング、Unity、VR関連

unityとかblenderとかvr関連の作業メモ

shader マンデルブロ集合

 

Shader "Custom/Mnd4" {
	Properties{
		_MainTex("MainTex",2D) = "white"{}
		_Limit("Limit",Int) = 360
		_StartZ("StartZ",Vector) = (0,0,0,0)
		_PowX("PowX",Int) = 2
		_PowY("PowY",Int) = 2
		_Multi("Multi",Float) = 2
		_P1("P1",Range(0,1)) = 1
	}
	SubShader{
		Tags{"RenderType"="Opaque" "Queue" = "Geometry"}
		//透明部分のあるテクスチャを使う場合
		//Tags{"Queue" = "Transparent" "RenderType" = "Transparent"}
		//Blend SrcAlpha OneMinusSrcAlpha

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

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

			struct v2f {
				float4 pos:SV_POSITION;
				float4 uv:TEXCOORD0;
			};
			#define PI 3.14159265358979323846264338327950288
			#define NAPIER 2.718281828459045235360287471352
			float _P1;
			float4 _StartZ;
			int _Limit;
			int _PowX;
			int _PowY;
			float _Multi;

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

			sampler2D _MainTex;

			float3 hsv(float h, float s, float v){
			    float4 t = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
			    float3 p = abs(frac(float3(h,h,h) + t.xyz) * 6.0 - float3(t.w,t.w,t.w));
			    return v * lerp(float3(t.x,t.x,t.x), clamp(p - float3(t.x,t.x,t.x), 0.0, 1.0), s);
			}

			float mod(float x, float y){
		  	return x - y * floor(x / y);
		  }

			float2 PowZ(float a,float b,float n,float2 c){
				float zz = sqrt(pow(a,2)+pow(b,2));
				float angle = atan(b/a);
				return float2(pow(zz,n)*cos(n*angle) + c.x,
				              pow(zz,n)*sin(n*angle) + c.y);
			}

			//z(n+1) = z(n)^2 + c
			//z = a + bi;
			//z(t) = z(n)^t を実数部と虚数部に分けて返す
			float2 ConvertMnd(float t,float2 z,float2 c){
				return PowZ(z.x,z.y,_Multi,c);
			}

			float4 frag(v2f i) :SV_Target {
				//return float4(Ganma(_Multi)/100,0,0,1);
		    // マンデルブロ集合
				//http://yomotsu.net/blog/2014/03/31/fractal.html
				//http://azisava.sakura.ne.jp/mandelbrot/definition.html
		    int cnt = 0;                    // カウンタ
		    float2 z = float2(_StartZ.xy);  // 漸化式 Z の初期値
				float2 zNext = float2(0,0);		//zNext = z^2 + c
				float2 c = 2.0 * i.uv - 1.0;  //複素平面上の座標

		   
			//[unroll]
		    for(int i = 0; i < _Limit; i++){
					/*マンデルブロ集合を複素数を使わずに書き直す*/
					zNext = ConvertMnd(3.5,z,c);
					z = zNext;
		      if(length(z) > 2.0){break;}
					cnt++;
		    }
				float m = float(cnt)/360.0;
				float3 rgb = float3(m,m*3,m*5);
		    return float4(rgb, 1.0);
			}
			ENDCG
		}//Pass
	}//SubShader
	FallBack "Diffuse"
}