如何用一张静态图做出视差效果

把一张平面图片变成会动的视差场景:先拆成不同景深的图层,补全被遮挡的背景,再用 After Effects 或几行 CSS 让它动起来。

Images2Layers 团队约 6 分钟读完

简短回答:把画面拆成不同景深的图层——天空、远景、中景、前景主体——确认被挖走的物体背后已经补好背景,然后让每一层以不同速度移动:越远的层动得越少,越近的层动得越多。在 After Effects 里,就是把图层转成 3D 再加一个缓慢移动的摄像机;在网页上,就是叠放几张图片,让它们的 transform 跟随鼠标或滚动位置变化。最费时的抠图和补背景,交给 AI 图层拆分工具,几分钟就能搞定。

视差之所以有效,是因为人眼会把移动速度理解成距离。走过一道篱笆时,近处的木桩飞快掠过,远处的山几乎不动。用一张静态图的几个图层复现这种速度差,平面画面立刻就有了纵深——纪录片片头、游戏菜单和网站首屏里常见的那种“2.5D”效果,就是这么来的。

难点一直在前期准备:要手动把每个元素抠出来,还要把它们挡住的景物补画出来。这篇指南要加速的正是这一步。下面用的这张插画,是我们用自己的工具生成并拆分的。

扁平风景插画:黄昏天空与飞鸟、远山、长满松树的山丘,前景是石头上的红狐狸AI 生成示例 · Seedream 5.0 Pro Layerize
起点:一张 AI 生成的平面风景插画,景深层次分明——天空、远山、长着松树的山丘,以及前景岩石上的一只狐狸。

什么样的图片适合做视差

不是每张图都适合动起来。拆分之前,先检查这几点:

  • 景深层次清楚。 风景、街景、室内和背景分明的角色插画效果最好;平铺图案或特写纹理没有可以放大的纵深。
  • 主体独立于背景。 狐狸和它脚下的岩石明显位于山丘前方,所以可以单独移动。
  • 边缘留有余地。 每个移动的图层都会露出画框外的一小条区域。主体四周留些空间的图片,比裁得很紧的图更容易做动画。
  • 难处理的材质少。 玻璃、烟雾、复杂背景前的细碎发丝和大量重叠的物体,对任何自动拆分都是难题,一动起来就更明显。

文字比较特殊。标题拆出来后是单独一层的像素,会像其他图层一样移动——要么把它放在几乎不动的层上,要么干脆在动画软件里用真正的文字重新排。

第一步:把图片拆成图层

打开图层拆分工具,上传图片,保持默认的 HD(Seedream 5.0 Pro Layerize)。做视差时选 HD 有两个原因:一是它会自己判断需要几层并给每层命名,下一步整理起来很快;二是它通常会在挖走的物体背后把背景补画出来——如果没有这一步,前景一移动就会露出空洞。

在这张插画上,HD 用 135 秒返回了 12 层,名称分别是 “背景”、“左侧云朵”、“右侧云朵”、“太阳”、“飞鸟”、“左侧远处的小松树”、“右侧远处的小松树”、“中景左侧松树”、“右侧前景大松树”、“左下角前景草丛”、“狐狸坐的岩石”、“坐着的卡通狐狸”。按每层 7 积分计算,这次一共花了 84 积分。

看第一格。背景作为完整的一层返回,里面是天空、远山和山丘,而狐狸、岩石、树木、云朵甚至太阳都被抹掉并补画好了。这正是视差需要的:前面无论什么在动,后面都有景物。

  1. 背景

    1背景

  2. 左侧云朵

    2左侧云朵

  3. 右侧云朵

    3右侧云朵

  4. 太阳

    4太阳

  5. 飞鸟

    5飞鸟

  6. 左侧远处的小松树

    6左侧远处的小松树

  7. 右侧远处的小松树

    7右侧远处的小松树

  8. 中景左侧松树

    8中景左侧松树

  9. 右侧前景大松树

    9右侧前景大松树

  10. 左下角前景草丛

    10左下角前景草丛

  11. 狐狸坐的岩石

    11狐狸坐的岩石

  12. 坐着的卡通狐狸

    12坐着的卡通狐狸

拆分结果,从下到上排列。 12 个图层 · Seedream 5.0 Pro Layerize

下载之前,先预览一下效果。下面的查看器默认是视差模式:把鼠标移到上面,或者倾斜手机,各个图层就会以不同速度漂移。切换到 3D 模式,还能从侧面看到整组图层。

图层:背景
图层:左侧云朵
图层:右侧云朵
图层:太阳
图层:飞鸟
图层:左侧远处的小松树
图层:右侧远处的小松树
图层:中景左侧松树
图层:右侧前景大松树
图层:左下角前景草丛
图层:狐狸坐的岩石
图层:坐着的卡通狐狸
12 个图层

图层12

每个 PNG 都是整幅画布大小,叠在一起就能对齐。

第二步:按景深整理图层

接下来决定每一层离镜头多远。用一个从 0(无限远,完全不动)到 1(最近,动得最多)的简单刻度就够了。以这张狐狸插画为例:

  • 背景(天空、远山和山丘):0 到 0.05——几乎不该动。
  • 云朵和太阳:0.1 左右。
  • 远处的小松树:0.25 左右。
  • 中景松树:0.45 左右。
  • 前景大松树和草丛:0.8 左右。
  • 岩石和狐狸:0.9 到 1——两者设成相同的值,狐狸才会稳稳坐在岩石上。
  • 飞鸟:随你安排,再加一点它们自己的漂移,画面会更生动。

如果两层应该一起动——比如岩石和狐狸——就把它们合并,或者设成相同的景深。如果一层里有距离不同的东西,就在编辑软件里用蒙版拆开。这次拆分把远山和山丘都留在了背景层里,做轻微的移动没有问题;想要更强的纵深,可以沿山脊线把山丘从远山上切下来单独设景深——再把远山往山脊下方稍微补画一些,这样山丘移动时就不会露出缝隙。

然后检查空洞。逐个隐藏前景图层,看看背后露出了什么。HD 通常会把背景补好,但如果发现缺口,现在就处理:从附近仿制、用编辑软件的内容识别填充,或者把后面那层稍微拉宽一点。小缺口只会在移动到最大幅度时露出来,所以很少需要做到完美。

最后,根据下一步选择下载格式:

  • 分层 PSD——保留每一层的名称和位置,最适合 After Effects、Photoshop 时间轴等动态软件。
  • PNG ZIP——每层都是完整画布尺寸的 PNG,已经对齐,最适合网页,因为直接把文件叠在一起就行,无需定位。

第三步(A):在 After Effects 里做动画

  1. 选择“文件 → 导入 → 文件”,选中 PSD,把导入为设为“合成 - 保持图层大小”。每一层都会带着名称出现在原位。
  2. 打开新建的合成,给每个图层打开 3D 开关。
  3. 沿 Z 轴把远处的图层往后推。以狐狸场景为例,可以从背景 2000、云朵和太阳 1600、远处松树 1000、中景松树 600、前景大松树和草丛 250、岩石和狐狸 100 开始尝试。
  4. 往后推的图层看起来会变小,所以要放大补偿:缩放 = 100 × (缩放值 + z) ÷ 缩放值,其中“缩放值”是摄像机的 Zoom 参数,z 是该图层的距离。这样图层看起来和原来一样大,移动起来却像远处的物体。
  5. 通过“图层 → 新建 → 摄像机”添加摄像机,在四到八秒内为它的位置做动画——缓慢推近,或者轻微横移。移动幅度要小:大约画面宽度的 5%–10% 就足够了。
  6. 给关键帧加缓动,打开运动模糊,然后渲染。

如果移动过程中画面侧边露出了边缘,就把那一层再放大一点,或者减小摄像机的移动幅度。

第三步(B):用 CSS 在网页上实现

网站上不需要视频。把 ZIP 里的 PNG 叠放在一个容器里,鼠标移动时按景深移动每一张:

<div class="scene">
  <img src="layer-01.png" data-depth="0" alt="">
  <img src="layer-02.png" data-depth="0.15" alt="">
  <img src="layer-03.png" data-depth="0.4" alt="">
  <img src="layer-04.png" data-depth="0.9" alt="">
</div>
.scene {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
}
.scene img {
  position: absolute;
  inset: -4%;              /* 留一点出血,边缘永远不会露出来 */
  width: 108%;
  height: 108%;
  object-fit: cover;
  transition: transform 0.2s ease-out;
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
  .scene img { transition: none; transform: none !important; }
}
const scene = document.querySelector('.scene');
const layers = [...scene.querySelectorAll('img')];

scene.addEventListener('pointermove', (event) => {
  const box = scene.getBoundingClientRect();
  const x = (event.clientX - box.left) / box.width - 0.5;
  const y = (event.clientY - box.top) / box.height - 0.5;
  for (const img of layers) {
    const depth = Number(img.dataset.depth);
    img.style.transform = `translate3d(${x * depth * -40}px, ${y * depth * -40}px, 0)`;
  }
});

因为 ZIP 里每张 PNG 的画布尺寸都一样,所有图层无需额外定位就能对齐。想做随滚动变化的视差,就把鼠标位置换成滚动位置,或者在浏览器支持的情况下使用 CSS 滚动驱动动画。把 PNG 转成 WebP 能让页面更轻,在手机上也要控制同时移动的图层数量。

常见问题与解决办法

  • 移动的物体背后出现空洞或残影。 这块背景没有补全。在编辑软件里修补,或者减小这一层的移动幅度。
  • 抠出的物体周围有一圈白边。 把该图层的边缘收缩一个像素,或者使用编辑软件的去边功能。
  • 所有东西一起动。 各层的景深值太接近了。把它们拉开——天空应该几乎不动。
  • 看着头晕。 减少运动幅度。轻微的移动让人感到纵深,幅度太大就成了晃动。始终尊重系统的“减少动态效果”设置。
  • 画面边缘露出来了。 给图层更多出血(放大一些),或者缩短移动距离。

要为动画准备角色插画?动漫 PSD页面介绍了如何把角色拆成身体、头发、道具和背景,作为绑定的起点。如果还在纠结用哪个模型,可以看看我们的 Qwen Image Layered 与 Seedream Layerize 实测对比。没有 Photoshop 也想检查分层文件,可以用免费的 PSD 在线查看工具打开。

用你自己的图片试试

上传 JPG、PNG 或 WebP,把拆好的图层下载为分层 PSD 或 PNG ZIP。没有水印,任务失败自动退还积分。

更多文章