Search:

Blog of Forest Johnson

This has officially deteriorated into the incoherent ramblings of a personal blog.

Wednesday, August 20, 2008

M-set in a shader






Shader "Mandelbrot" {
    Properties {
        _X ("X", Range(-2,2)) = 0
        _Y ("Y", Range(-2,2)) = 0
    }
    SubShader {
        Pass {
        Fog { Mode Off }
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag

float _X;
float _Y;

struct appdata {
    float4 vertex;
    float4 texcoord;
};

struct v2f {
    float4 pos : POSITION;
    float2 uv : TEXCOORD0;
};
v2f vert (appdata v) {
    v2f o;
    o.pos = mul( glstate.matrix.mvp, v.vertex );
    o.uv = v.texcoord.xy;
    return o;
}
half4 frag( v2f f ) : COLOR {
    float2 z = (f.uv - half2(0.62,0.5)) * 4;
    float2 offset = z + half2(_X,_Y);
    float threshold = 2*2;
    int itr = 40;
    float isOut = 0;
    
    for(int i = 0; i < itr && isOut == 0; i++) {
        z = half2(z.x*z.x - z.y*z.y, z.x*z.y*2) + offset;    
        isOut = z.x*z.x+z.y*z.y > threshold ? i : 0;
    }
    
   if(isOut == 0) isOut = itr;
    return isOut / itr;
       //float4((z*0.1)+0.5,1,0)
}
ENDCG    
        }
    } 
    FallBack off
}

2 comments:

Proton said...

Would be really cool if you could zoom in and out of it.

Haven't seen it done in real-time before.

Forest Johnson said...

Well if you apply it to a plane in Unity and then zoom in using the camera you can go in a bit. But to get it to go in far before getting blurry you would need to do several passes, and that would require floating point render textures to store the intermediate states. I'm not sure if that would even work anyway.

I'm happy with this result, it was just a quick experiment.