learn GLSL from zero
ToolsCrea con shadersShader MakerCrea shaders gratis en líneaToolkitObras de shaders listas para tu webSketcher LabPinta el hero de tu landing con shaders3D StudioEl editor Three.js en tu navegador
GamesJuega con shadersOnomatoShaderEscribe una palabra y explótalaThe WatcherUn ojo que te sigueAetherVidrio líquido con un ojo adentroBloomcoreUna palabra hace crecer un jardín de luzPyrokineAvienta fuego a la paredVoltaicLa pirámide lanza rayosSurfSurfea un océano de shader

Lección 7 de 10 · Fractales en GLSL

c animado

La constante respira en un círculo. La criatura vive.

Si c define toda la forma del Julia, ¿qué pasa si lo movemos en el tiempo? La criatura respira. El truco es no soltarlo lejos: lo paseamos en un círculo chiquito alrededor de un punto bueno, con wob de radio.

Círculo pequeño = morphing vivo. Círculo grande = se deshace en polvo. Por eso wob se queda discreto: queremos que respire, no que explote.

c = base + wob * vec2(cos(T*0.5), sin(T*0.5))cos y sin del mismo tiempo trazan un círculo perfecto. wob es el radio de ese paseo. Multiplicar por T lo hace girar para siempre: el Julia se reorganiza en bucle, suave, sin saltos.
PruebaSube wob=0.12 a 0.25 y el morphing se vuelve salvaje (cuidado con el polvo). Bájalo a 0.04 para una respiración casi imperceptible. La velocidad vive en T*0.5.

El código

precision highp float;
void main(){
  vec2 uv=(gl_FragCoord.xy*2.0 - R)/R.y;
  float zoom=1.5;
  vec2 z=uv*zoom;
  float wob=0.12;
  vec2 c=vec2(-0.74, 0.12)+wob*vec2(cos(T*0.5), sin(T*0.5));
  float n=0.0; bool esc=false;
  const int IT=150;
  for(int i=0;i<IT;i++){
    z=vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y)+c;
    if(dot(z,z)>256.0){ n=float(i); esc=true; break; }
  }
  float sn=esc ? (n - log2(log2(dot(z,z))) + 4.0) : 0.0;
  float band=sn * 0.5;
  vec3 col=0.5+0.5*cos(0.35*band + vec3(0.0,2.2,4.0) + T*0.1);
  col=esc ? col : vec3(0.02,0.0,0.05);
  gl_FragColor=vec4(col,1.0);
}
close