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 9 de 10 · Fractales en GLSL

Orbit trap

No cuentes el escape: mide qué tan cerca pasó la órbita.

Hasta ahora coloreábamos por cuándo escapa z. El orbit trap colorea por por dónde pasó. En cada iteración, z salta por el plano dibujando una órbita; medimos la distancia mínima de esa órbita a una trampa, aquí un anillo.

Donde la órbita roza el anillo, el frag se enciende. Salen vetas de luz que serpentean por dentro y por fuera del conjunto, una geometría completamente distinta de los anillos de escape.

trap = min(trap, abs(length(z) - 0.8))En cada paso comparamos la distancia de z a un anillo de radio 0.8 y guardamos la más chica de toda la órbita. Esa distancia mínima es el color: cerca de la trampa = brillante; lejos = apagado.
PruebaMueve el radio en length(z)-0.8 a 0.3 y las vetas se reorganizan. Sube la nitidez en 1.0-trap*1.5 a 3.0 para filamentos más finos.

El código

precision highp float;
void main(){
  vec2 uv=(gl_FragCoord.xy*2.0 - R)/R.y;
  float zoom=1.4;
  vec2 c=uv*zoom+vec2(-0.6,0.0);
  vec2 z=vec2(0.0);
  float trap=1000.0;
  bool esc=false;
  const int IT=120;
  for(int i=0;i<IT;i++){
    z=vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y)+c;
    trap=min(trap, abs(length(z)-0.8));
    if(dot(z,z)>256.0){ esc=true; break; }
  }
  float vein=pow(clamp(1.0-trap*1.5,0.0,1.0),2.0);
  vec3 col=0.5+0.5*cos(6.2831*(trap*0.7+vec3(0.0,0.33,0.66)));
  col=col*0.35 + vec3(1.0,0.9,0.7)*vein*0.95;
  gl_FragColor=vec4(col,1.0);
}
close