diff options
author | Andreas Grois <andi@grois.info> | 2018-03-23 09:20:21 +0100 |
---|---|---|
committer | Andreas Grois <andi@grois.info> | 2018-03-23 09:20:21 +0100 |
commit | b8082e3ef23758ce0f3a541aecf5a87efe3c1d53 (patch) | |
tree | b6b3cdd993bb8b6b8865ea903172e44646652e86 | |
parent | bf8b1e63686bfa6f6cd982fd801d7799c7706f51 (diff) | |
parent | f60384e1306cb66b0460ed46a38fe010ff6c427a (diff) |
Merge branch 'master' into feature/04-zoomability
-rw-r--r-- | BuddhaTest/Shaders/BuddhaCompute.glsl | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/BuddhaTest/Shaders/BuddhaCompute.glsl b/BuddhaTest/Shaders/BuddhaCompute.glsl index b1c87cb..91c1195 100644 --- a/BuddhaTest/Shaders/BuddhaCompute.glsl +++ b/BuddhaTest/Shaders/BuddhaCompute.glsl @@ -159,8 +159,10 @@ bool isInMainCardioid(vec2 v) return rhsSqrt*rhsSqrt<zNormSqr; } -bool isInMainBulb(vec2 v) +bool isInKnownCircle(vec2 v) { + //this checks if the point is in some known circle that's part of the Mandelbrot set. + //The first cirlce is at -1 with radius of 1/4. That one can be derived analytically: //The condition for this is that f(f(z)) = z //where f(z) = z*z+v //This is an equation of fourth order, but two solutions are the same as @@ -168,9 +170,38 @@ bool isInMainBulb(vec2 v) //Factoring those out, you end up with a second order equation. //Again, the solutions need to be attractive (|d/dz f(f(z))| < 1) //Well, after a bit of magic one finds out it's a circle around -1, radius 1/4. - vec2 shifted = v + vec2(1,0); - float sqrRadius = dot(shifted,shifted); - return sqrRadius<0.062499999; + + //the other circles are taken from http://linas.org/art-gallery/bud/bud.html + //with a bit of tolerance. Those number are experimental, and I just don't want to risk missing points. + //Also, here perfect circles are used, they used ellipses. The difference between circle and ellipse orbit was + //always smaller than 0.6% for them though, so taking a 2% margin will more than do. + struct circle + { + vec2 center; + float radius; + }; + const circle[] circles = + { + circle(vec2(-1.0,0.0),0.24999), + circle(vec2(-0.124866818, 0.74396884), 0.09452088*0.98), + circle(vec2(0.281058181, 0.531069896), 0.043999991*0.98), + circle(vec2(0.37926948, 0.33593786), 0.0237270*0.98), + circle(vec2(0.38912506, 0.216548077), 0.01415882*0.98), + circle(vec2(0.376222674, 0.145200726), 0.00909100*0.98), + circle(vec2(0.35924728, 0.101225755), 0.00616879*0.98), + circle(vec2(0.34339510, 0.073032700), 0.00437060*0.98), + circle(vec2(0.32985010, 0.054264593), 0.00320580*0.98), + circle(vec2(0.31860462, 0.0413441289), 0.002419144*0.98), + circle(vec2(0.30933816, 0.032184347), 0.001869337*0.98) + }; + for(int i=0;i < circles.length();++i) + { + vec2 shifted = vec2(v.x,abs(v.y)) - circles[i].center; + float sqrRadius = dot(shifted,shifted); + if(sqrRadius < circles[i].radius*circles[i].radius) + return true; + } + return false; } bool isGoingToBeDrawn(in vec2 offset, in uint totalIterations, inout vec2 lastVal, inout uint iterationsLeftThisFrame, inout uint doneIterations, out bool result) @@ -248,7 +279,7 @@ void main() { //we know that iterationsLeftToDo is at least 1 by the while condition. --iterationsLeftToDo; //count this as 1 iteration. offset = getCurrentOrbitOffset(state.orbitNumber, totalWorkers, uniqueWorkerID); - if(isInMainBulb(offset) || isInMainCardioid(offset)) + if(isInMainCardioid(offset) || isInKnownCircle(offset)) { // do not waste time drawing this orbit ++state.orbitNumber; |