Remotion LabRemotion Lab
視覺設計隨機效果

隨機效果

在 Remotion 中正確使用隨機數,確保每次渲染結果一致。

為什麼不能用 Math.random()?

Remotion 是逐幀渲染的。每一幀都是獨立的 React render。如果你用 Math.random(),每次 render 都會得到不同的值,導致:

  • 預覽時畫面閃爍
  • 每一幀的「隨機」位置都不同,看起來像抖動

你需要的是確定性隨機——同一個 seed 永遠產生相同的結果。

random() 函數

Remotion 提供 random() 函數,接受一個 seed 參數:

import { random } from "remotion";
 
// 相同的 seed 永遠回傳相同的值
random("my-seed");    // 0.7635...(每次都一樣)
random("my-seed");    // 0.7635...(完全相同)
random("other-seed"); // 0.1234...(不同的 seed,不同的值)

實際範例:隨機粒子

import { AbsoluteFill, random, useCurrentFrame, interpolate } from "remotion";
 
const PARTICLE_COUNT = 50;
 
const Particle: React.FC<{ index: number }> = ({ index }) => {
  const frame = useCurrentFrame();
 
  // 用 index 當 seed,每個粒子的位置固定
  const x = random(`x-${index}`) * 1920;
  const startY = random(`y-${index}`) * 1080;
  const size = 4 + random(`size-${index}`) * 8;
  const speed = 1 + random(`speed-${index}`) * 3;
 
  const y = startY - frame * speed;
 
  const opacity = interpolate(
    y,
    [-50, 0, 1080],
    [0, 1, 0.3],
    { extrapolateLeft: "clamp", extrapolateRight: "clamp" }
  );
 
  return (
    <div
      style={{
        position: "absolute",
        left: x,
        top: y,
        width: size,
        height: size,
        borderRadius: "50%",
        backgroundColor: "white",
        opacity,
      }}
    />
  );
};
 
export const ParticleEffect: React.FC = () => {
  return (
    <AbsoluteFill style={{ backgroundColor: "#0f0f1a" }}>
      {new Array(PARTICLE_COUNT).fill(null).map((_, i) => (
        <Particle key={i} index={i} />
      ))}
    </AbsoluteFill>
  );
};

每個粒子用 index 作為 seed 的一部分,確保位置、大小、速度在每一幀都一致。

結合 noise(雜訊)

Remotion 也提供 noise2D()noise3D() 函數,用於產生平滑的隨機變化:

import { noise2D } from "@remotion/noise";
 
const value = noise2D("seed", x * 0.01, frame * 0.02);
// 回傳 -1 到 1 之間的值,變化平滑

安裝:

npm install @remotion/noise

noise 特別適合製作有機的、流動的視覺效果。

小結

  • 不要用 Math.random(),會導致每幀結果不同
  • 用 Remotion 的 random(seed) 確保確定性
  • 用不同的 seed 產生不同的隨機值
  • @remotion/noisenoise2D / noise3D 做平滑的隨機變化