Apollonian

Shader ported from shadertoy.com to use as card illustration in Fragment Forge.

 

License is under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License as is standard in Shadertoy.

Shader code
shader_type canvas_item;
// Using code from

// mla for the  Colourful Apollonia shader
// https://www.shadertoy.com/view/tsScDt
// Ported to Godot and customized for Fragment Forge by Db0

// Licence: Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// https://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US

uniform bool is_card = true;
uniform float iTime;
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
uniform vec2 iChannelResolution0;

//vec2 iResolution =  1.0 / SCREEN_PIXEL_SIZE; // for copy-paste

const int AA = 2;
uniform float N = 3.0;
const int max_iterations = 100;
const float pi = 3.14159265;

bool checkinverse(inout vec2 pos, vec3 c, float s, inout float mindist2) {
  vec2 p = pos-c.xy;
  float p2 = dot(p,p);
  float d2 = s*p2 - s*c.z;
  if (d2 > 0.0) {
    mindist2 = min(d2,mindist2);
    return false;
  }
  pos = p*c.z/p2 + c.xy;
  return true;
}
  
bool checkinverse2(inout vec2 pos, vec3 c, float s) {
  float mindist2;
  return checkinverse(pos,c,s,mindist2);
}

vec2 invert(vec2 pos, vec3 c) {
  vec2 p = pos-c.xy;
  float p2 = dot(p,p);
  return p*c.z/p2 + c.xy;
}
  
vec4 gasket(vec2 pos){
  float theta = pi/N;
  float r = 1.0/cos(theta);
  float s = tan(theta);
  float r2min = 0.0;
  for(int n = 0; n < max_iterations; n++){
    float mindist2 = 1e8;
    vec3 c1 = vec3(0,0,pow(r-s,2.0));
    vec3 c2 = vec3(0,0,pow(r+s,2.0));
    if (checkinverse(pos,c1,1.0,mindist2)) {
    } else if (checkinverse(pos,c2,-1.0,mindist2)) {
    } else {
      bool found = false;
      for (float i = 0.0; i < N; i++) {
        float t = 0.2*iTime/2.;
        vec3 c = vec3(r*sin(2.0*i*theta+t), r*cos(2.0*i*theta+t), s*s);
        if (checkinverse(pos,c,1.0,mindist2)) {
          found = true;
          break;
        }
      }
      if (!found) return vec4(pos,float(n),mindist2);
    }
  }
  return vec4(pos,float(max_iterations),r2min);
}

// Smooth HSV to RGB conversion 
// Function by iq, from https://www.shadertoy.com/view/MsS3Wc
vec3 hsv2rgb( in vec3 c ) {
  vec3 rgb = clamp( abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0 );
  rgb = rgb*rgb*(3.0-2.0*rgb); // cubic smoothing	
  return c.z * mix( vec3(1.0), rgb, c.y);
}

vec3 getCol(vec4 n){
  float t = iTime/2.;
  return hsv2rgb(vec3(mod((t+n.z)/50.0,1.0),0.8,0.8));
}

void fragment(){
  vec2 m = vec2(0,0.8);
  vec2 iResolution =  1.0 / SCREEN_PIXEL_SIZE; // for copy-paste
//  if (iMouse.x != 0.0) {
//    m = 2.0 * iMouse.xy / iResolution.y - vec2(iResolution.x / iResolution.y, 1.0);
//  }
  vec2 c = m*(1.0/dot(m,m));
  vec3 col = vec3(0);
  for (int i = 0; i < AA; i++) {
    for (int j = 0; j < AA; j++) {
      vec2 z = UV * 2. +vec2(float(i),float(j))/float(AA)-UV.xy;
      z -= 0.5 * 2. +vec2(float(i),float(j))/float(AA)-UV.xy;
//      vec2 z = (2.0*FRAGCOORD.xy+vec2(float(i),float(j))/float(AA)-iResolution.xy)/iResolution.y;
	if(!is_card){
		z.x *= iResolution.x/iResolution.y;
	} 
      if (false) {
        z.y += 1.0;
        z = invert(z,vec3(0,-1,2)); // Map half plane to unit disk.
      }
      z = invert(z,vec3(c,dot(c,c)-1.0));
      vec4 data = gasket(z);
      float d = 1.0/(sqrt(data.w)+1.0);
      col += 0.8*d*getCol(data);
    }
  }
  col /= float(AA*AA);
  COLOR = vec4(pow(col,vec3(0.4545)),1);
}
Tags
fractal
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from db0

Planet

guest
0 Comments
Inline Feedbacks
View all comments