From 986d37148a4db91fced474fed235b1ddbe697236 Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 6 May 2022 16:53:30 +1000 Subject: [PATCH] theme mandelbrot --- Assets/Audio/ThemeShaderBinder.cs | 2 +- .../GFLPC_Mandelbrot/MandelBrotHybrid.shader | 95 +++++++++++------- .../Scenes/GFLPC_Mandelbrot/Mandelbrot.shader | 10 +- .../GFLPC_Mandelbrot/MandelbrotBW.shader | 98 +++++++++++++++++++ .../GFLPC_Mandelbrot/MandelbrotBW.shader.meta | 10 ++ 5 files changed, 172 insertions(+), 43 deletions(-) create mode 100644 Assets/Scenes/GFLPC_Mandelbrot/MandelbrotBW.shader create mode 100644 Assets/Scenes/GFLPC_Mandelbrot/MandelbrotBW.shader.meta diff --git a/Assets/Audio/ThemeShaderBinder.cs b/Assets/Audio/ThemeShaderBinder.cs index 7f3220c..0ee6099 100644 --- a/Assets/Audio/ThemeShaderBinder.cs +++ b/Assets/Audio/ThemeShaderBinder.cs @@ -37,7 +37,7 @@ public class ThemeShaderBinder : MonoBehaviour Gradient theme = preferences.Theme(); for (int i = 0; i < textureSize; i++) { - _colorCache[i] = theme.Evaluate(1.0f / i); + _colorCache[i] = theme.Evaluate((float)i / (float)textureSize); } _texture.SetPixels(_colorCache); diff --git a/Assets/Scenes/GFLPC_Mandelbrot/MandelBrotHybrid.shader b/Assets/Scenes/GFLPC_Mandelbrot/MandelBrotHybrid.shader index 4582655..f2705d9 100644 --- a/Assets/Scenes/GFLPC_Mandelbrot/MandelBrotHybrid.shader +++ b/Assets/Scenes/GFLPC_Mandelbrot/MandelBrotHybrid.shader @@ -7,10 +7,15 @@ Shader "Explorer/Mandelbrot" _Area("Area", vector) = (0, 0, 4 ,4) _Angle("Angle", range(-3.1415, 3.1415)) = 0 _MaxIter("Max Iterations", range(0, 555)) = 255 - _Color("Color", range(0,1)) = 0.5 - _Repeat("Repeat", float) = 1 _Speed("Speed", range(0, 1)) = 0.1 - _Colors("Colors", vector) = (3.0, 4.0, 5.0, 0.0) + _EscapeRadius("EscapeRadius", range(2, 2000)) = 255 + + _SpectrumTexture("SpectrumTexture", 2D) = "white" {} + _SpectrumSize("SpectrumSize", float) = 16 + + _ThemeTexture("ThemeTexture", 2D) = "white" {} + _ThemeSize("ThemeSize", float) = 16 + } SubShader { @@ -46,54 +51,68 @@ Shader "Explorer/Mandelbrot" } float4 _Area; - float _Angle; - float _Color; - float3 _Colors; - float _Repeat; - float _Speed; int _MaxIter; + float _EscapeRadius; + float _Speed; + + sampler2D _SpectrumTexture; + int _SpectrumSize; + + sampler2D _ThemeTexture; + int _ThemeSize; + sampler2D _MainTex; - float2 rot(float2 p, float2 pivot, float a) { - float s = sin(a); - float c = cos(a); - p -= pivot; - p = float2(p.x*c-p.y*s, p.x*s+p.y*c); - p += pivot; - - return p; - } - fixed4 frag (v2f i) : SV_Target { + // drawing stuff float2 uv = i.uv - 0.5; float2 offset = _Area.xy + uv * _Area.zw; - float2 z; // track pixel jumping across screen - float2 zPrev; - float r = 20; // escape radius + + // cool modulation + float sub = tex2D(_SpectrumTexture, 0.0); + float bass = tex2D(_SpectrumTexture, 0.25); + float mids = tex2D(_SpectrumTexture, 0.50); + float highs = tex2D(_SpectrumTexture, 0.75); + + float r = lerp(2.0, 200, bass); + float maxIterations = lerp(2.0, 500, sub); + + // fractal bits float r2 = r*r; + float2 c = _Area.xy + uv * _Area.zw; + float2 z = 0; + float2 zNext; + int iter; + for (iter = 0; iter < maxIterations; iter ++) + { + // f(z) = z^2 + c + zNext.x = z.x * z.x - z.y * z.y + c.x; + zNext.y = 2 * z.x * z.y + c.y; + z = zNext; - float vxsquare = 0; - float vysquare = 0; + // unbounded + if (length(zNext) > r) + break; + } - float iteration = 0; - float lastIteration = _MaxIter; + // in the set + // make it white + if (iter >= maxIterations) { + return 0; + return 1; + } - do { - vxsquare = uv.x * uv.x; - vysquare = uv.y * uv.y; + float val = iter / float(maxIterations); + float4 col = tex2D(_ThemeTexture, float2(sub, 1.0)); - uv = float2(vxsquare - vysquare, uv.x * uv.y * 2) + offset; + return col * val; - iteration++; - - if ((lastIteration == _MaxIter) && (vxsquare + vysquare) > 4.0) { - lastIteration = iteration + 1; - } - } while (iteration < lastIteration); - - float val = (float(iteration) - (log(log(sqrt(vxsquare + vysquare))) / log(2.0))) / float(_MaxIter); - return float4(sin(val * _Colors.x), sin(val * _Colors.y), sin(val * _Colors.z), 1); + // return float4(val, val, val, 1.0); + // return tex2D(_ThemeTexture, highs); + // float col = tex2D(_ThemeTexture, float2(highs * val, 1.0)); + // return col; + // from spinny curvy brot // float dist = length(z); // distance from origin // float fracIter = (dist - r) / (r2 - r); // linear interpolation // fracIter = log2(log(dist) / log(r) ); // double exponential interpolation diff --git a/Assets/Scenes/GFLPC_Mandelbrot/Mandelbrot.shader b/Assets/Scenes/GFLPC_Mandelbrot/Mandelbrot.shader index 52f5faa..97529ee 100644 --- a/Assets/Scenes/GFLPC_Mandelbrot/Mandelbrot.shader +++ b/Assets/Scenes/GFLPC_Mandelbrot/Mandelbrot.shader @@ -11,7 +11,7 @@ Shader "Explorer/Mandelbrot" _Repeat("Repeat", float) = 1 _Speed("Speed", range(0, 1)) = 0.1 _Symmetry("Symmetry", range(0, 1)) = 0 - _EscapeRadius("EscapeRadius", range(0, 50)) = 20 + _EscapeRadius("EscapeRadius", range(2, 200)) = 50 _SpectrumTexture("SpectrumTexture", 2D) = "white" {} _SpectrumSize("SpectrumSize", float) = 16 @@ -80,17 +80,19 @@ Shader "Explorer/Mandelbrot" c = rot(c, _Area.xy, _Angle); float2 z; // track pixel jumping across screen float2 zPrev; - float r = lerp(2.0f, 20.0f, tex2D(_SpectrumTexture, 0.1f)); + // float r = _EscapeRadius; + float r = lerp(2.0f, 50.0f, tex2D(_SpectrumTexture, 1.0f)); float r2 = r*r; float iter; // track current iteration for (iter = 0; iter < _MaxIter; iter++) { // update z based on previous z value and add original starting position - //zPrev = z; + // zPrev = z; zPrev = rot(z, 0, _Time.y); + // zPrev = rot(z, 0, clamp(tex2D(_SpectrumTexture, 0.1f) * 6.28, 1, 6.28)); + z = float2(z.x*z.x-z.y*z.y, 2*z.x*z.y) + c; if (dot(z, zPrev) > r2) { - //if (length(z) > r) { break; } } diff --git a/Assets/Scenes/GFLPC_Mandelbrot/MandelbrotBW.shader b/Assets/Scenes/GFLPC_Mandelbrot/MandelbrotBW.shader new file mode 100644 index 0000000..a720d2f --- /dev/null +++ b/Assets/Scenes/GFLPC_Mandelbrot/MandelbrotBW.shader @@ -0,0 +1,98 @@ +Shader "Explorer/Mandelbrot" +{ + Properties + { + _MainTex ("Texture", 2D) = "white" {} + // first two numbers are center of area, second two - size of area + _Area("Area", vector) = (0, 0, 4 ,4) + _Angle("Angle", range(-3.1415, 3.1415)) = 0 + _MaxIter("Max Iterations", range(0, 555)) = 255 + // _Speed("Speed", range(0, 1)) = 0.1 + _Colors("Colors", vector) = (0.5, 0.5, 0.5, 0.0) + _EscapeRadius("EscapeRadius", range(2, 2000)) = 255 + } + SubShader + { + // No culling or depth + Cull Off ZWrite Off ZTest Always + + Pass + { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + + #include "UnityCG.cginc" + + struct appdata + { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + }; + + struct v2f + { + float2 uv : TEXCOORD0; + float4 vertex : SV_POSITION; + }; + + v2f vert (appdata v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.uv = v.uv; + return o; + } + + float4 _Area; + float _Angle; + float3 _Colors; + // float _Speed; + int _MaxIter; + float _EscapeRadius; + sampler2D _MainTex; + + fixed4 frag (v2f i) : SV_Target { + float2 uv = i.uv - 0.5; + float2 offset = _Area.xy + uv * _Area.zw; + float r = _EscapeRadius; + float r2 = r*r; + + float2 c = _Area.xy + uv * _Area.zw; + + float2 z = 0; + float2 zNext; + int iter; + for (iter = 0; iter < _MaxIter; iter ++) + { + // f(z) = z^2 + c + zNext.x = z.x * z.x - z.y * z.y + c.x; + zNext.y = 2 * z.x * z.y + c.y; + z = zNext; + + // Bounded? + if (distance(z, float2(0,0)) > r) + break; + } + + float val = iter / float(_MaxIter); + + return float4(val, val, val, 1); + return float4(sin(val), sin(val), sin(val), 1); + + // float dist = length(z); // distance from origin + // float fracIter = (dist - r) / (r2 - r); // linear interpolation + // fracIter = log2(log(dist) / log(r) ); // double exponential interpolation + // iter -= fracIter; + // float m = sqrt(iter / _MaxIter); + // float4 col = sin(float4(.3, .45, .65, 1) * m * 20)*.5 + .5; // procedural colors + // col = tex2D(_MainTex, float2(m * _Repeat + _Time.y*_Speed, _Color)); + // col *= smoothstep(3, 0, fracIter); + // float angle = atan2(z.x, z.y); + // col *= 1 + sin(angle*2 + _Time.y*4)*.2; + // return col; + } + ENDCG + } + } +} diff --git a/Assets/Scenes/GFLPC_Mandelbrot/MandelbrotBW.shader.meta b/Assets/Scenes/GFLPC_Mandelbrot/MandelbrotBW.shader.meta new file mode 100644 index 0000000..20101bf --- /dev/null +++ b/Assets/Scenes/GFLPC_Mandelbrot/MandelbrotBW.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ac37e4ae67210ed48bd3bb15fca8b2b2 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: