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 6 de 10 · Animación en shaders

Flow field

Cada triángulo gira a su velocidad. Cada esquina su ley.

Hasta ahora el tiempo avanza igual en todas partes. Pero en un río, hay zonas donde el agua corre rápido y zonas donde se estanca. Eso es un flow field.

El truco: en vez de sumar T directo, lo multiplicas por un valor que cambia con la posición. T * (0.5 + fb(p)). Donde el noise es alto, el tiempo corre rápido. Donde es bajo, casi se detiene.

Cada coordenada tiene su propia velocidad.

Flow fieldUn campo donde cada punto tiene su propia velocidad. Modulas T con una función espacial. El resultado: movimiento que se siente líquido.
PruebaCambia el 0.3 (velocidad base) a 0. y las celdas más lentas se congelan. Cambia el 1.5 (rango entre rápidas y lentas) a 4. y la diferencia entre celdas se vuelve extrema. A 0. y todas giran al mismo ritmo.

El código

void main(){
  vec2 p = (2.*gl_FragCoord.xy - R) / min(R.x, R.y);
  vec3 col = vec3(0.03, 0.02, 0.01);
  for(int j = 0; j < 3; j++){
    for(int i = 0; i < 3; i++){
      float fi=float(i), fj=float(j);
      vec2 c = vec2(-0.6+fi*0.6, -0.6+fj*0.6);
      float vel = 0.3 + n2(c+1.) * 1.5;
      float ang = T * vel;
      float ca=cos(ang), sa=sin(ang);
      vec2 q = p-c; q = vec2(q.x*ca-q.y*sa, q.x*sa+q.y*ca);
      vec2 aq = abs(q);
      float d = max(aq.x*.866+q.y*.5, -q.y) - 0.14;
      vec2 sq=q+vec2(.04,-.06); vec2 asq=abs(sq);
      col *= smoothstep(-.02,.12,max(asq.x*.866+sq.y*.5,-sq.y)-.14);
      float bright = .45+vel*.35;
      col += vec3(.95,.7,.15) * smoothstep(.01,-.01,d) * bright;
      col += vec3(.5,.35,.08) * exp(-max(d,0.)*5.) * vel * .25;
    }
  }
  gl_FragColor = vec4(col, 1.);
}
close