Three.js|GLBの色を壊さず「たれ感アニメーション」を追加する方法(Shader最小実装)

記事
IT・テクノロジー
はじめに

Three.jsでGLBモデルを使った演出を作っていると、

「元の色・テクスチャが消えた」

「Shaderを使ったら全部真っ白になった」

「動かしたいのは形だけなのに見た目が壊れる」

という壁に必ずぶつかります。

今回は、
GLBの見た目を一切壊さずに「たれ感のある動き」だけを追加する方法を
実際にハマった失敗も含めて解説します。

やりたかったこと

parfaitの sauce.glb だけ に

垂れているような「ゆらゆら動く演出」を入れたい

元の色・テクスチャ・ライティングはそのまま

よくある失敗

最初にやりがちなのがこれ👇

obj.material = new THREE.ShaderMaterial(...)


これをやると…

GLBに設定された

ベースカラー

テクスチャ

ライティング情報
👉 すべて消える

結果、
「動くけど真っ白なモデル」 になります。

3dstrawberrypafet および他 9 ページ - 個人 - Microsoft​ Edge 2026_01_04 14_51_37.png


正解アプローチ
ShaderMaterialに置き換えない

Three.jsには便利な仕組みがあります。

onBeforeCompile

これを使うと
「元のマテリアルに、少しだけShaderを足す」 ことができます。

実装コード(最小構成)
① たれ演出を追加する関数
function enableSauceDrip(material) {
  material.onBeforeCompile = (shader) => {
    shader.uniforms.uTime = { value: 0 };

    shader.vertexShader = shader.vertexShader.replace(
      '#include <begin_vertex>',
      `
      #include <begin_vertex>

      // 下に行くほど少し揺れる
      float drip = smoothstep(0.1, -0.6, transformed.y);
      transformed.y += sin(uTime) * drip * 0.01;
      `
    );

    material.userData.shader = shader;
  };

  material.needsUpdate = true;
}

② sauce.glb だけに適用
model.traverse(obj => {
  if (!obj.isMesh) return;

  obj.castShadow = true;
  obj.receiveShadow = true;

  if (item.file === "sauce.glb") {
    enableSauceDrip(obj.material);
  }
});

③ アニメーションループ
parfaitGroup.traverse(obj => {
  if (obj.isMesh && obj.material.userData.shader) {
    obj.material.userData.shader.uniforms.uTime.value += 0.05;
  }
});

結果

GLBの色・質感 → そのまま

ライティング → 崩れない

sauce だけ → 自然にたれる動き

他の具材 → 影響なし

Shader初心者でも
「これだけでいい」 という実装です。

まとめ

見た目を壊したくない場合
👉 ShaderMaterial は使わない

動きだけ足したい場合
👉 onBeforeCompile を使う

GLB演出は「置き換え」より「拡張」

Three.jsで
「ちょっとリッチな表現を入れたい」
そんなときに使えるテクニックです。

おわりに(ココナラ誘導用)

Three.js・GLB・Shaderを使った
Web向け演出・アニメーション実装の相談も受け付けています。

「こういう動きできる?」
「このモデルを動かしたい」など
お気軽にご相談ください。
サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す ココナラコンテンツマーケット ノウハウ記事・テンプレート・デザイン素材はこちら