learn GLSL from zero
ToolsCreate with shadersShader MakerFree online shader builderToolkitShader works ready for your siteSketcher LabPaint your landing’s hero with shaders3D StudioThe Three.js editor in your browser
GamesPlay with shadersOnomatoShaderType a word, blow it upThe WatcherAn eye that follows youAetherLiquid glass with an eye insideBloomcoreA word grows a garden of lightPyrokineThrow fire at the wallVoltaicThe pyramid throws lightningSurfSurf a shader ocean

Lesson 9 of 10 · Domain warping

Liquid Metal

Shapes that melt and merge. T-1000.

A lava lamp does not scroll, its blobs float, deform, split apart. The trick: two warps with T at different speeds. One pushes vertical, the other pushes diagonal. Blobs move in different directions and deform each other.

T * 0.12 is slow, gelatinous. Blobs are in no rush.

Molten mercury under zero gravity.

Two warps with TOne warp with T only in Y = rises. Another warp with T in X and Y at different speeds = twists. Combined = blobs floating fluidly.
TryChange 0.15 (the slow speed) to 0.04 for ultra slow motion. To 0.4 and blobs go nervous. Change 0.1 (base blob radius) to 0.18 and blobs grow until they merge into one mass.

The code

void main(){
  vec2 p = (2.*gl_FragCoord.xy - R) / min(R.x, R.y);
  float slow = T * 0.15;
  float field = 0.0;
  for(int i = 0; i < 5; i++){
    float fi = float(i);
    vec2 c = vec2(sin(slow*(.4+fi*.1)+fi*2.1)*.6, cos(slow*(.3+fi*.08)+fi*1.7)*.5);
    float r = 0.1+sin(fi*3.3)*.03;
    vec2 d = p-c;
    float shape = mix(length(d), max(abs(d.x),abs(d.y)), sin(fi*2.7)*.5+.5);
    field += r*r/(shape*shape+0.0001);
  }
  float edge = smoothstep(0.6,1.0,field);
  float body = smoothstep(1.0,2.0,field);
  float core = smoothstep(3.0,5.0,field);
  float spec = smoothstep(6.0,10.0,field);
  vec3 col = vec3(0.02,0.02,0.04);
  col += vec3(.15,.15,.2)*edge*(1.-body);
  col = mix(col, vec3(.55,.58,.65), body);
  col = mix(col, vec3(.8,.82,.88), core);
  col = mix(col, vec3(1.,.98,.95), spec);
  col += vec3(.1,.1,.15)*pow(edge,2.)*(1.-body);
  col = hueShift(col, 0.0);
  gl_FragColor = vec4(col, 1.0);
}
close