You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js关键帧插值问题:缩放设为0时画面异常

Fixing Three.js Animation Glitches When Scaling Objects to 0

Hey there! I totally get why this scaling glitch is frustrating—you’re trying to toggle an object’s visibility by keyframing its scale from 1 to 0, but Three.js’s default interpolation is creating weird in-between frames that mess up your render. Let’s walk through a few solid solutions to fix this:

1. Disable Interpolation for Scale Tracks

The root issue here is that Three.js uses linear interpolation by default between keyframes, so it’s calculating tiny scale values between your 1 and 0 keyframes. To skip those in-between steps, you can switch the interpolation mode to discrete/step interpolation for all scale-related animation tracks:

// After loading your GLTF/FBX model
model.animations.forEach(animation => {
  animation.tracks.forEach(track => {
    // Target any track that controls an object's scale
    if (track.name.includes('.scale')) {
      track.setInterpolation(THREE.InterpolationDiscrete);
    }
  });
});

This tells Three.js to jump directly from the 1 scale value to 0 without any smooth transition—no more glitchy intermediate frames.

2. Use Visibility Instead of Scaling to 0

Scaling an object to 0 isn’t the most reliable way to hide it (it can cause rendering oddities like flipped normals or z-fighting). A better approach is to animate the object’s visible property directly. Here’s how to either set this up in your 3D software or convert existing scale animations to visibility animations in Three.js:

Option A: Set Up Visibility Keyframes in Your 3D Tool

In Blender/Cinema 4D, instead of keyframing scale, keyframe the object’s visibility property (e.g., in Blender, toggle the eye icon in the outliner and set keyframes for that state). Export the animation as GLTF/FBX, and Three.js will pick up the visibility tracks automatically.

Option B: Convert Scale Tracks to Visibility Tracks in Code

If you already have scale animations and don’t want to re-export, you can rewrite the animation tracks:

model.animations.forEach(animation => {
  const updatedTracks = [];
  animation.tracks.forEach(track => {
    if (track.name.includes('.scale')) {
      // Extract the object's name from the track path (e.g., "Cube.scale" → "Cube")
      const objectPath = track.name.split('.')[0];
      // Create a new visibility track that matches your scale keyframes
      const visibilityTrack = new THREE.BooleanKeyframeTrack(
        `${objectPath}.visible`,
        track.times, // Reuse the same keyframe timings
        track.values.map(scaleValue => scaleValue > 0) // Scale > 0 = visible, else hidden
      );
      updatedTracks.push(visibilityTrack);
    } else {
      // Keep non-scale tracks as-is
      updatedTracks.push(track);
    }
  });
  animation.tracks = updatedTracks;
});

This replaces your scale animation with a clean visibility toggle that has no interpolation issues.

3. Override Keyframe Timings to Eliminate Interpolation

If you absolutely need to use scaling instead of visibility, you can force the two keyframes (scale 1 and scale 0) to occur at the exact same time. This removes any window for interpolation:

model.animations.forEach(animation => {
  animation.tracks.forEach(track => {
    if (track.name.includes('.scale')) {
      // Assuming your keyframes are at times [50, 51]
      // Set the second keyframe's time to match the first
      track.times[1] = track.times[0];
      // Optimize the track to remove redundant data
      track.optimize();
    }
  });
});

With both keyframes at the same timestamp, Three.js will jump instantly from scale 1 to 0 without any in-between values.


内容的提问来源于stack exchange,提问作者Christian Tielmann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:21:13