260412

const W = 800;
const H = 800;
const EFFECT_RADIUS_PX = 40;
let palette = [];
let currentSeed = 0;
const SIZE = 500;
const STROKE_W = 3;

let sceneFbo;
let liquidShader;

const liquidVert = `
precision mediump float;
attribute vec3 aPosition;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;

void main() {
  vTexCoord = aTexCoord;
  gl_Position = vec4(aPosition, 1.0);
}
`;

const liquidFrag = `
precision mediump float;
varying vec2 vTexCoord;
uniform sampler2D uScene;
uniform float uTime;
uniform vec2 uResolution;
uniform float uRadiusPx;

void main() {
  vec2 uv = vec2(vTexCoord.x, 1.0 - vTexCoord.y);
  vec2 px = (uv - 0.5) * uResolution;
  float dist = length(px);
  float edge = 48.0;
  float mask = 1.0 - smoothstep(uRadiusPx - edge, uRadiusPx + edge, dist);

  vec2 q = uv * 2.0 - 1.0;
  float t = uTime;

  vec2 flow = vec2(
    sin(q.y * 10.0 + t * 1.9) * cos(q.x * 16.5 - t * 1.2),
    cos(q.x * 16.0 - t * 1.6) * sin(q.y * 20.0 + t * 1.4)
  );
  vec2 swirl = 0.06 * mask * flow;

  vec2 mixW = vec2(
    sin(13.0 * (q.x + q.y) + t * 2.8),
    cos(11.0 * (q.x - q.y) - t * 2.3)
  );
  vec2 liquid = swirl + 0.09 * mask * mixW;

  vec2 warped = clamp(uv + liquid, 0.001, 0.999);
  vec4 base = texture2D(uScene, uv);
  vec4 distorted = texture2D(uScene, warped);
  vec3 b = base.rgb / max(base.a, 0.0001);
  vec3 d = distorted.rgb / max(distorted.a, 0.0001);
  float blend = smoothstep(0.0, 0.08, mask);
  vec3 rgb = mix(b, d, blend);
  gl_FragColor = vec4(rgb, 1.0);
}
`;

function setup() {
  setAttributes({ alpha: false });
  createCanvas(W, H, WEBGL);
  strokeWeight(STROKE_W);
  sceneFbo = createFramebuffer({ depth: true, channels: "RGB" });
  liquidShader = createShader(liquidVert, liquidFrag);
  palette = colorArray[1].colors;
  background(palette[3]);
}

function draw() {
  sceneFbo.begin();
  drawScene();
  sceneFbo.end();

  shader(liquidShader);
  liquidShader.setUniform("uScene", sceneFbo.color);
  liquidShader.setUniform("uTime", frameCount * 0.01);
  liquidShader.setUniform("uResolution", [SIZE, SIZE]);
  liquidShader.setUniform("uRadiusPx", EFFECT_RADIUS_PX);
  quad(-1, -1, -1, 1, 1, 1, 1, -1);
  resetShader();
}

function drawScene() {
  background(palette[3]);
  ortho();
  noFill();
  let col = palette[5];
  stroke(col);

  let growNum = 5;
  let startSize = 50;
  let height = 500;
  let speed = 300;
  let phase = (frameCount % speed) / speed;
  let singleArcPhase = (frameCount % (speed / growNum)) / (speed / growNum);

  rotateY(TAU / 4 + TAU / 16);
  translate(0, 0, -height / 2);

  push();
  translate(0, 0, (1 - singleArcPhase) * height);
  fill(col);
  ellipse(0, 0, startSize, startSize, 50);
  pop();

  drawGrowingEllipse(phase, startSize, col);
  push();
  translate(0, 0, height);
  drawGrowingEllipse(1 - phase, startSize, col);
  pop();
}

function drawGrowingEllipse(t, startSize, col) {
  let growNum = 5;
  let endSize = SIZE;
  push();
  for (let i = 0; i < growNum; i++) {
    let tt = (t + i / growNum) % 1;
    let d = lerp(startSize, endSize, tt);
    let alpha = map(1 - tt, 0, 1, 0, 255);
    let c = color(col);
    c.setAlpha(alpha);
    stroke(c);
    noFill();
    ellipse(0, 0, d, d, 50);
  }
  pop();
}
const colorArray = [
  {
    id: 0,
    colors: ["#253276", "#dfdad3", "#ffffff", "#000000"],
  },
  {
    id: 1,
    colors: [
      "#9dbdba",
      "#f8b042",
      "#e47763",
      "#253276",
      "#dfdad3",
      "#FFFFFF",
      "#000000",
    ],
  },
];

円が落ちる間にShaderを入れて波打たせてみる

const W = 800;
const H = 800;
const EFFECT_RADIUS_PX = 40;
let palette = [];
let currentSeed = 0;
const SIZE = 500;
const STROKE_W = 3;

let sceneFbo;
let liquidShader;

const liquidVert = `
precision mediump float;
attribute vec3 aPosition;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;

void main() {
  vTexCoord = aTexCoord;
  gl_Position = vec4(aPosition, 1.0);
}
`;

const liquidFrag = `
precision mediump float;
varying vec2 vTexCoord;
uniform sampler2D uScene;
uniform float uTime;
uniform vec2 uResolution;
uniform float uRadiusPx;

void main() {
  vec2 uv = vec2(vTexCoord.x, 1.0 - vTexCoord.y);
  vec2 px = (uv - 0.5) * uResolution;
  float dist = length(px);
  float edge = 48.0;
  float mask = 1.0 - smoothstep(uRadiusPx - edge, uRadiusPx + edge, dist);

  vec2 q = uv * 2.0 - 1.0;
  float t = uTime;

  vec2 flow = vec2(
    sin(q.y * 10.0 + t * 1.9) * cos(q.x * 16.5 - t * 1.2),
    cos(q.x * 16.0 - t * 1.6) * sin(q.y * 20.0 + t * 1.4)
  );
  vec2 swirl = 0.06 * mask * flow;

  vec2 mixW = vec2(
    sin(13.0 * (q.x + q.y) + t * 2.8),
    cos(11.0 * (q.x - q.y) - t * 2.3)
  );
  vec2 liquid = swirl + 0.09 * mask * mixW;

  vec2 warped = clamp(uv + liquid, 0.001, 0.999);
  vec4 base = texture2D(uScene, uv);
  vec4 distorted = texture2D(uScene, warped);
  vec3 b = base.rgb / max(base.a, 0.0001);
  vec3 d = distorted.rgb / max(distorted.a, 0.0001);
  float blend = smoothstep(0.0, 0.08, mask);
  vec3 rgb = mix(b, d, blend);
  gl_FragColor = vec4(rgb, 1.0);
}
`;

function setup() {
  setAttributes({ alpha: false });
  createCanvas(W, H, WEBGL);
  strokeWeight(STROKE_W);
  sceneFbo = createFramebuffer({ depth: true, channels: "RGB" });
  liquidShader = createShader(liquidVert, liquidFrag);
  palette = colorArray[1].colors;
  background(palette[3]);
}

function draw() {
  sceneFbo.begin();
  drawScene();
  sceneFbo.end();

  shader(liquidShader);
  liquidShader.setUniform("uScene", sceneFbo.color);
  liquidShader.setUniform("uTime", frameCount * 0.01);
  liquidShader.setUniform("uResolution", [SIZE, SIZE]);
  liquidShader.setUniform("uRadiusPx", EFFECT_RADIUS_PX);
  quad(-1, -1, -1, 1, 1, 1, 1, -1);
  resetShader();
}

function drawScene() {
  background(palette[3]);
  ortho();
  noFill();
  let col = palette[5];
  stroke(col);

  let growNum = 5;
  let startSize = 50;
  let height = 500;
  let speed = 300;
  let phase = (frameCount % speed) / speed;
  let singleArcPhase = (frameCount % (speed / growNum)) / (speed / growNum);

  rotateY(TAU / 4 + TAU / 16);
  translate(0, 0, -height / 2);

  push();
  translate(0, 0, (1 - singleArcPhase) * height);
  fill(col);
  ellipse(0, 0, startSize, startSize, 50);
  pop();

  drawGrowingEllipse(phase, startSize, col);
  push();
  translate(0, 0, height);
  drawGrowingEllipse(1 - phase, startSize, col);
  pop();
}

function drawGrowingEllipse(t, startSize, col) {
  let growNum = 5;
  let endSize = SIZE;
  push();
  for (let i = 0; i < growNum; i++) {
    let tt = (t + i / growNum) % 1;
    let d = lerp(startSize, endSize, tt);
    let alpha = map(1 - tt, 0, 1, 0, 255);
    let c = color(col);
    c.setAlpha(alpha);
    stroke(c);
    noFill();
    ellipse(0, 0, d, d, 50);
  }
  pop();
}
const colorArray = [
  {
    id: 0,
    colors: ["#253276", "#dfdad3", "#ffffff", "#000000"],
  },
  {
    id: 1,
    colors: [
      "#9dbdba",
      "#f8b042",
      "#e47763",
      "#253276",
      "#dfdad3",
      "#FFFFFF",
      "#000000",
    ],
  },
];

Last Updated:

260412