ホーム 記事一覧 ブック DH週間トピックス 検索 このサイトについて
English
Three.js + Puppeteer で VRM キャラクターを動かして動画を自動生成する

Three.js + Puppeteer で VRM キャラクターを動かして動画を自動生成する

はじめに 技術ブログの記事を VTuber 風の解説動画に自動変換できたら面白いのでは――そんな思いつきから、Three.js + Puppeteer で VRM キャラクターをフレーム単位でレンダリングし、VOICEVOX の音声とリップシンクさせて動画を生成するパイプラインを作りました。 この記事では、実装で得られた知見とハマりどころを共有します。 全体のパイプライン 処理の流れは以下の通りです。 Markdown 記事を読み込み → LLM(OpenRouter API)でセクション分割された台本を生成 VOICEVOX でセクションごとに音声(WAV)と音素タイミングを生成 Three.js + @pixiv/three-vrm でヘッドレス Chrome 上に VRM モデルを描画し、音素データに基づくリップシンクアニメーションをフレーム連番 PNG として出力 スライド画像を自動生成(HTML → Chrome ヘッドレス → PNG) FFmpeg でスライド背景 + VRM アニメーション + 音声を合成し、MP4 動画を出力 Python スクリプトがオーケストレーション役を担い、VRM レンダリングは Node.js スクリプトを子プロセスとして呼び出す構成です。 使用技術 役割 技術 3D レンダリング Three.js v0.172 VRM 読み込み @pixiv/three-vrm v3.3.3 ヘッドレスブラウザ puppeteer-core (SwiftShader) 音声合成 VOICEVOX Engine (Docker) 動画合成 FFmpeg パイプライン制御 Python VRM モデル AvatarSample_C (VRoid Hub / 無料ライセンス) ヘッドレス Chrome で VRM を読み込む 課題: file:// の CORS 制限 最初の壁は、ヘッドレス Chrome 上で VRM ファイルを読み込む方法でした。ローカルの .vrm ファイルを file:// プロトコルで読もうとすると CORS エラーで弾かれます。 ...

Three.js + React Three Fiber で GLTF モデルのテクスチャが荒く表示される問題と解決策

Three.js + React Three Fiber で GLTF モデルのテクスチャが荒く表示される問題と解決策

概要 React Three Fiber を使用して GLTF モデルを表示した際、テクスチャがぼやけて見える、または荒く表示される問題に遭遇しました。本記事では、その原因と解決策を解説します。 症状 GLTF モデルのテクスチャがぼやけて表示される 他の 3D ビューアでは正常に表示される同じモデルが、自作のビューアでは荒く見える dpr(デバイスピクセル比)や antialias を設定しても改善しない 原因 Three.js r152 以降、デフォルトの出力カラースペースが変更されました。 GLTF モデルのテクスチャは通常 sRGB 色空間 で保存されています。しかし、Three.js のデフォルト設定では出力が Linear 色空間 になっているため、以下の問題が発生します: テクスチャの補間処理が Linear 空間で行われる ミップマップの生成が正しい色空間で行われない 結果として、テクスチャがぼやけたり、色がおかしくなる 解決策 Canvas の onCreated コールバックで outputColorSpace を設定します。 Before(問題のあるコード) import { Canvas } from '@react-three/fiber'; <Canvas camera={{ position: [5, 5, 5], fov: 50 }} dpr={[1, 2]} gl={{ antialias: true }} > <Scene /> </Canvas> After(修正後のコード) import { Canvas } from '@react-three/fiber'; import * as THREE from 'three'; <Canvas camera={{ position: [5, 5, 5], fov: 50 }} dpr={Math.min(window.devicePixelRatio, 2)} gl={{ antialias: true, preserveDrawingBuffer: true, powerPreference: 'high-performance', toneMapping: THREE.ACESFilmicToneMapping, toneMappingExposure: 1, }} onCreated={({ gl }) => { gl.outputColorSpace = THREE.SRGBColorSpace; }} > <Scene /> </Canvas> 各設定の説明 outputColorSpace: THREE.SRGBColorSpace 最も重要な設定 。出力カラースペースを sRGB に設定することで、テクスチャが正しく表示されます。 ...

Sketchfab APIでGLBファイルをダウンロード・表示するWebアプリを作る

Sketchfab APIでGLBファイルをダウンロード・表示するWebアプリを作る

Sketchfab APIを使って3DモデルをGLBファイルとしてダウンロードし、ブラウザ上でThree.jsで表示するWebアプリを作成しました。本記事では、セキュリティを考慮したアーキテクチャ設計から実装まで解説します。 やりたかったこと Sketchfab上の3DモデルをGLB形式でダウンロードしたい ダウンロードしたGLBをブラウザ上で3D表示したい APIトークンを安全に管理したい 技術スタック Next.js 16(App Router) React Three Fiber / @react-three/drei TypeScript 最初に試したこと:クライアントサイドのみで実装 最初はシンプルにHTML + JavaScriptだけで実装しようとしました。 // Sketchfab APIからダウンロードURLを取得 const response = await fetch( `https://api.sketchfab.com/v3/models/${modelUid}/download`, { headers: { 'Authorization': `Token ${apiToken}` } } ); const data = await response.json(); console.log(data.glb.url); // 署名付きS3 URL これ自体は動作しましたが、2つの問題がありました。 問題1: APIトークンの露出 クライアントサイドでAPIトークンを使用すると、ブラウザの開発者ツールから簡単に確認できてしまいます。APIトークンが漏洩すると、他人があなたのアカウントでAPIを利用できてしまうため、これは避けるべきです。 問題2: CORSエラー(場合による) ブラウザのセキュリティ制限により、異なるオリジンへのリクエストが制限されることがあります。今回のケースでは、Sketchfab APIへのリクエスト自体はCORSが許可されていましたが、環境によっては問題になる可能性があります。 解決策:サーバーサイドAPIを経由する設計 Next.jsのAPI Routesを使って、サーバーサイドでSketchfab APIと通信する設計にしました。 ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │ │ │ │ │ │ Client │────▶│ Next.js API │────▶│ Sketchfab API │ │ (Browser) │ │ (Server) │ │ │ │ │◀────│ │◀────│ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ ┌─────────────────┐ │ │ │ └──────────▶│ S3 (GLB) │ │ 署名付きURL │ └─────────────────┘ ポイント:署名付きURLの活用 Sketchfab APIは、GLBファイルの実体ではなく「署名付きS3 URL」を返します。 ...

Next 15(React 19 を使用)で、@react-three/fiberとdreiを使う

Next 15(React 19 を使用)で、@react-three/fiberとdreiを使う

概要 Next 15(React 19 を使用)で、@react-three/fiberを使う際、以下のように説明されています。 R3F v8 is not compatible with React 19 or Next 15, which uses React 19. Use the R3F v9 RC instead which can be installed with @react-three/fiber@rc. (日本語訳)R3F v8 は React 19 や Next 15(React 19 を使用)と互換性がありません。代わりに R3F v9 RC を使用してください。インストールするには @react-three/fiber@rc を使用してください。 一方、マウス操作を行うために以下を追加しましたが、@react-three/fiber@rcとは相性が悪いようでした。 https://www.npmjs.com/package/@react-three/drei この問題に対する対処法の備忘録です。 方法 本記事執筆時点(2025-02-06)の情報です。 まず、@react-three/fiber@rcではなく、@react-three/fiber@alphaをインストールする必要がありました。(@betaでもよいかもしれません。) そして、dreiについては、@react-three/drei@10.0.0-rc.1をインストールしました。結果、以下のような組み合わせでは、無事にインストールすることができました。 "@react-three/drei": "^10.0.0-rc.1", "@react-three/fiber": "^9.0.0-alpha.8", まとめ 考慮が不十分な点があるかもしれませんが、参考になりましたら幸いです。

virtual-museum-tour-threejsを試す

virtual-museum-tour-threejsを試す

概要 以下のリポジトリを試す機会がありましたので、備忘録です。 https://github.com/theringsofsaturn/virtual-museum-tour-threejs 以下でチュートリアル動画も公開されていました。 https://www.youtube.com/watch?v=8oQC0ICNtL0 フォーク リポジトリをフォークして、一部修正を加え、GitHub Pagesでビルド結果を確認できるようにしました。 https://nakamura196.github.io/virtual-museum-tour-threejs/ まとめ Three.jsを使ったアプリ開発にあたり、参考になるかと思います。