はじめに

Three.jsで3D空間上で動画を再生して見たので実装方法をまとめてみます。

表示するだけだと簡単ですが、シェーダーを使うとより細かくカスタムする事が出来ます。

以下は、VR上で再生テストしたキャプチャ動画。

Three.js で 動画を再生

WebGL 上で動画を表示する場合、VideoTexture を MeshBasicMaterial に貼るだけなら簡単だが、映像の見た目を変えたり、加工したり、エフェクトをかけたりするには追加のテクニックが必要になる。ここでは Three.js で動画表示をカスタムする代表的な手法を整理する。

基本:VideoTexture をそのまま貼る

const video = document.createElement('video');
video.src = 'sample.mp4';
video.loop = true;
video.muted = true;
video.play();

const texture = new THREE.VideoTexture(video);
texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.LinearFilter;

const material = new THREE.MeshBasicMaterial({ map: texture });
const mesh = new THREE.Mesh(new THREE.PlaneGeometry(2, 1), material);
scene.add(mesh);

カスタム方法①:サイズ・比率調整

PlaneGeometry のサイズ変更や mesh.scale で引き伸ばし可能。

const geo = new THREE.PlaneGeometry(16, 9); // 比率維持
mesh.scale.set(3, 3, 1);

カスタム方法②:動画の一部だけを使う(UV 操作)

VideoTexture をトリミングしたい場合は UV を編集する。

texture.offset.set(0, 0.5);
texture.repeat.set(1, 0.5); // 下半分だけ表示

カスタム方法③:透明度・色調整

material.transparent = true;
material.opacity = 0.7;
material.color.set(0x88ccff); // 色補正

カスタム方法④:3D 形状に貼り付ける

平面以外にも貼れる。

半円スクリーン例:

const geo = new THREE.CylinderGeometry(5, 5, 3, 32, 1, true);
const mat = new THREE.MeshBasicMaterial({ map: texture, side: THREE.DoubleSide });
scene.add(new THREE.Mesh(geo, mat));

カスタム方法⑤:フィルター処理(ShaderMaterial)

より高度な加工を行いたい場合は ShaderMaterial を使う。 動画を「ピクセル単位で加工」できるため、白黒化・モザイク・グリッチ・色補正など、ほとんど何でも作れる。

ベースとなる最小シェーダー

const material = new THREE.ShaderMaterial({
  uniforms: {
    tex: { value: texture },
  },
  vertexShader: `
    varying vec2 vUv;
    void main() {
      vUv = uv;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
    }
  `,
  fragmentShader: `
    uniform sampler2D tex;
    varying vec2 vUv;
    void main() {
      vec4 c = texture2D(tex, vUv);
      gl_FragColor = vec4(c.rgb, 1.0);
    }
  `
});

この fragmentShader 内にフィルター処理を書く。


よく使うシェーダー加工例

白黒化

vec4 c = texture2D(tex, vUv);
float g = dot(c.rgb, vec3(0.299, 0.587, 0.114));
gl_FragColor = vec4(vec3(g), 1.0);

モザイク

vec2 uv = floor(vUv * 40.0) / 40.0;
vec4 c = texture2D(tex, uv);
gl_FragColor = vec4(c.rgb, 1.0);

波揺れ(VHS 風)

vec2 uv = vUv + 0.02 * sin(vUv.y * 50.0 + time);
vec4 c = texture2D(tex, uv);
gl_FragColor = vec4(c.rgb, 1.0);

カスタム方法⑥:再生制御

Web 上の video 要素なので、操作性は高い。

video.playbackRate = 0.5;   // スロー
video.currentTime = 10;     // シーク

まとめ用途

  • UI として動画を使う
  • WebXR の背景・スクリーン
  • 動画をエフェクト素材にする
  • アニメーション背景
  • インタラクティブ映像

Three.js は動画表示を“貼るだけ”で終わらせず、加工素材として扱える。