[{"data":1,"prerenderedAt":13171},["ShallowReactive",2],{"author-count-basile-ja":3,"author-basile-ja":4,"posts-author-basile-ja-1":19,"tags-header-ja":13092,"tags-footer-ja":13149},23,{"id":5,"title":6,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":10,"meta":11,"navigation":13,"pageType":14,"path":15,"seo":16,"slug":10,"stem":17,"__hash__":18},"jsonPages/ja/authors/basile.json","Basile Samel",null,"json","ja","basile",{"name":6,"profile_image":12},"",true,"authors","/ja/authors/basile",{},"ja/authors/basile","k9eJIKPeix111lGaPtpaYiT9Bwm41UjZh4zfo9DcKVg",[20,575,992,1849,2588,3201,3903,4395,5255,5997,6473,7237,7809,8185,8870,9372,9893,10487,10981,11361,11752,12066,12580],{"id":21,"title":22,"authors":23,"body":27,"description":12,"extension":557,"feature_image":558,"html":7,"meta":559,"navigation":13,"path":563,"published_at":564,"seo":565,"slug":566,"stem":567,"tags":568,"__hash__":574,"updated_at":560,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/automated-kitsu-pdf-reports/index.md","PythonとGazuでKitsuレポートを自動化する（2026）",[24],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},"630632b2ca5910003d4a70af","https://blog.cg-wire.com/author/basile/",{"type":28,"value":29,"toc":547},"minimark",[30,47,51,54,57,60,63,68,71,87,90,99,102,105,139,141,145,148,151,160,167,170,194,196,200,203,211,253,256,300,315,317,321,324,327,330,333,339,349,368,377,388,391,393,397,408,429,436,439,446,449,457,463,465,469,472,475,481,493,503,505,509,512,515,518,536],[31,32,37,42],"div",{"className":33},[34,35,36],"kg-card","kg-callout-card","kg-callout-card-yellow",[31,38,41],{"className":39},[40],"kg-callout-emoji","📊",[31,43,46],{"className":44},[45],"kg-callout-text","手作業のステータス報告を何時間分も、数秒で完全に自動化されたKitsuのPDFに変えます。",[48,49,50],"p",{},"毎週、データを集めてレポートを作るのに、何時間くらい費やしていますか？",[48,52,53],{},"アニメ制作スタジオではKitsuで進捗を追跡していますが、それでもスーパーバイザーがそのデータをPDFにまとめる作業を何時間も手作業で行っているのをよく見かけます。プロデューサーやディレクターに状況を共有するためとはいえ、これは創造のエネルギーを大きく奪い、かつ、上級チームが対処しなくてはいけない“手作業ならではの致命点”になりがちです。データがすでに追跡ソフトウェア内に存在しているのであれば、共有することは格闘である必要はありません。",[48,55,56],{},"テクニカルリードとしての仕事は、アーティストがアートに集中できるように、退屈な作業を自動化することです。そしてGazuのPythonクライアントを使えば、Kitsuのデータベースと最終的な関係者向けレポートの間をつなぐことができます。",[48,58,59],{},"今日は、プロジェクトの指標をプログラムで取得して、独自のPDFを生成するスクリプトを作ります。2時間の手作業を5秒の自動化タスクへと変えるわけです。",[61,62],"hr",{},[64,65,67],"h2",{"id":66},"why-custom-reports","なぜカスタムレポートなのか？",[48,69,70],{},"Kitsuは、制作の混乱を整理しておくための命綱です。標準搭載のダッシュボードは、マルチ制作の分析を含むあらゆるユースケースをカバーしています。ですが、時には「標準」だけでは足りません。",[72,73,76],"figure",{"className":74},[34,75],"kg-image-card",[77,78],"img",{"src":79,"className":80,"alt":12,"loading":82,"width":83,"height":84,"srcSet":85,"sizes":86},"https://blog.cg-wire.com/content/images/2026/02/data-src-image-4807effb-72e4-4fe8-9684-7f8a44579c42.png",[81],"kg-image","lazy",1600,900,"https://blog.cg-wire.com/content/images/size/w600/2026/02/data-src-image-4807effb-72e4-4fe8-9684-7f8a44579c42.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/02/data-src-image-4807effb-72e4-4fe8-9684-7f8a44579c42.png 1000w, https://blog.cg-wire.com/content/images/2026/02/data-src-image-4807effb-72e4-4fe8-9684-7f8a44579c42.png 1600w","(min-width: 720px) 720px",[48,88,89],{},"たとえばクライアントは、プレミアムなサービスに対価を払っていると感じたいことがあります。生のソフトウェア画面のスクリーンショットや、ただの汎用リンクを送ると、少し素人っぽく見えてしまいます。カスタムレポートを使えば、スタジオのブランディングで包んだ進捗更新を届けられ、提供するフレームと同じくらい洗練された見栄えにできます。",[48,91,92,93,98],{},"さらに悩ましいのが、プロデューサーにとって扱いやすい形式を探すことです。プロデューサーは、非常に特定のExcelのピボットテーブルや、社内の奇妙なロジック（本人しか理解していない）に従った過去資料用のレガシーPDFを要求してきます。「Sequence 02の“進行中（In Progress）”になっているすべてのショット」をフィルタして、そのうえで「延期（Overdue）になっているリテイク」と絡めたリストが必要だ」といった場合でも、カスタムレポートならそのデータを即座に得られます。",[94,95,97],"a",{"href":96},"https://blog.cg-wire.com/reduce-rework-animation/","手作業のコピペによる地獄から救われ","、またアニメーションに戻れます。",[48,100,101],{},"また、先進的な追跡のために、カスタムビューが必要なスタジオもあります。たとえば、FXキャッシュの遅延によって照明チームが常に停滞しているようなとき、カスタムデータは部門のボトルネックを見つけるのに役立ちます。問題が“金曜夜の追い込み”へ変わる前に、摩擦を解消できます。",[48,103,104],{},"幸い、Kitsuは非常に拡張しやすいです。",[31,106,109,113],{"className":107},[34,35,108],"kg-callout-card-blue",[31,110,112],{"className":111},[40],"💡",[31,114,116,124,127,129,130,132,134,135],{"className":115},[45],[117,118,119],"b",{},[120,121,123],"strong",{"style":122},"white-space: pre-wrap;","動作例を探していますか？",[125,126],"br",{},[125,128],{},"このガイドで紹介している例の統合に関する完全なソースコードは、GitHubで確認できます：",[125,131],{},[125,133],{},"🔗 ",[94,136,138],{"href":137},"https://github.com/cgwire/blog-tutorials/tree/main/custom-kitsu-reports?ref=blog.cg-wire.com","https://github.com/cgwire/blog-tutorials/tree/main/custom-kitsu-reports",[61,140],{},[64,142,144],{"id":143},"_1-kitsu-setup-authentication","1. Kitsuのセットアップと認証",[48,146,147],{},"まず、Kitsuのインスタンスに接続する必要があります。",[48,149,150],{},"まだスタジオURLがない場合、そして自分のマシンでKitsuを動かしたい場合、Dockerが制作向けの実行環境を最速で立ち上げる方法です：",[152,153,154],"pre",{},[155,156,159],"code",{"className":157},[158],"language-bash","docker run --init -ti --rm -p 80:80 -p 1080:1080 --name cgwire cgwire/cgwire\n",[48,161,162,163,166],{},"スクリプト作成では、公式のKitsu Python SDKである",[155,164,165],{},"gazu","を使います。",[48,168,169],{},"ユーザーの認証情報で認証できます（ローカルでのテストならこれで十分です）：",[152,171,172,177],{},[155,173,176],{"className":174},[175],"language-python","import gazu\n",[48,178,179],{},[155,180,182,183,188,189,193],{"className":181},[175],"gazu.set_host(\"",[94,184,185],{"href":185,"rel":186},"http://localhost/api",[187],"nofollow","\")\nuser = gazu.log_in(\"",[94,190,192],{"href":191},"mailto:admin@example.com","admin@example.com","\", \"mysecretpassword\")\n",[61,195],{},[64,197,199],{"id":198},"_2-fetch-production-data","2. 制作データの取得",[48,201,202],{},"コードを1行も書く前に、Kitsuが公開しているデータについて説明する必要があります。UI上で見えるなら、Gazuで取得できる可能性が高いです。",[48,204,205,206,210],{},"APIは意外なほど奥が深いです。",[94,207,209],{"href":208},"https://blog.cg-wire.com/how-to-track-properly-the-cg-artist-progress/","しっかりした制作レポート","を作るなら、通常は次のようなデータを取得することになります：",[212,213,214,221,227,233,239,245],"ul",{},[215,216,217,220],"li",{},[120,218,219],{},"進捗指標（Progress Metrics）："," ステータスの変更（例：イベントを使って「WIP」から「Internal Review」に移るなど）。",[215,222,223,226],{},[120,224,225],{},"時間管理（Time Tracking）："," あるショットが「In Progress」になっている期間と、元の見積もりの差。",[215,228,229,232],{},[120,230,231],{},"キャストリスト（Cast Lists）："," 特定のエピソードまたはシーケンスに紐づく、登場人物、環境、プロップのすべて。",[215,234,235,238],{},[120,236,237],{},"作業量（Workload）："," ある特定のアーティストに現在割り当てられているフレーム数またはアセット数の正確な値。",[215,240,241,244],{},[120,242,243],{},"予算（Budget）："," チームの割当（クォータ）が時間とともにどのように変化するか。",[215,246,247,248,252],{},"その他にも、",[94,249,251],{"href":250},"https://gazu.cg-wire.com/data?ref=blog.cg-wire.com","詳細な開発者ドキュメント","で読めるリソースがたくさんあります。",[48,254,255],{},"よくあるシナリオを見てみましょう。特定のプロジェクトにおいて、チームメンバーに現在割り当てられているすべてのタスクを素早く把握したい、というケースです。これは「誰が何をしている？」系のレポートの土台になります。",[152,257,258,295],{},[155,259,261,262,266,269,274,287],{"className":260},[175],"projects = gazu.project.all_projects()\nproject = projects",[263,264,265],"span",{},"0",[48,267,268],{},"tasks = gazu.task.all_tasks_for_project(project)",[48,270,271,272],{},"report = ",[263,273],{},[48,275,276,277],{},"for task in tasks:\nassignees = ",[263,278,279,280,283,284],{},"gazu.person.get_person(p_id)",[263,281,282],{},"\"full_name\""," for p_id in task",[263,285,286],{},"\"assignees\"",[152,288,293],{"className":289,"code":291,"language":292},[290],"language-text","task_info = {\n    \"date\": task[\"updated_at\"],\n    \"entity\": gazu.entity.get_entity(task[\"entity_id\"])[\"name\"],\n    \"type\": gazu.task.get_task_type(task[\"task_type_id\"])[\"name\"],\n    \"status\": gazu.task.get_task_status(task[\"task_status_id\"])[\"name\"]\n}\n\nfor artist in assignees:\n    report.append({**task_info, \"artist\": artist})\n","text",[155,294,291],{"__ignoreMap":12},[48,296,297],{},[155,298],{"className":299},[175],[48,301,302,303,306,307,310,311,314],{},"Gazuは辞書（dictionaries）を返します。",[155,304,305],{},"all_tasks_for_project"," を取得しているときは、長編制作ではこれが膨大な量のデータになり得る点を覚えておいてください。必ずデータを絞り込むようにしましょう。たとえば",[155,308,309],{},"task_status"," や ",[155,312,313],{},"entity_type","でフィルタし、必要なのがアクティブなAnimationショットだけなら、そのように絞り込むべきです。",[61,316],{},[64,318,320],{"id":319},"_3-creating-a-reusable-template","3. 再利用できるテンプレートの作成",[48,322,323],{},"次に、PDFをどのように描画（レンダリング）するかを決めます。主な選択肢は2つあります。",[48,325,326],{},"ReportLabを使う方法です。これは最小限の手法です。高速で、Python以外の外部依存を必要としません。社内向けのテックレポート、単純な明細テーブル、高速なバッチ自動化に最適です。",[48,328,329],{},"または、Jinja2（テンプレート）とWeasyPrintを使って、HTMLからPDFへ変換するレンダリングパイプラインを作ることもできます。この方法がよく好まれるのは、CSSでレポートの見た目を調整できるからです。Webページを作れるならレポートも作れます。クライアント向けの納品物、重めのブランディング、複雑なレイアウトに最適です。",[48,331,332],{},"設定とテンプレートを定義しましょう：",[152,334,335],{},[155,336,338],{"className":337},[175],"STUDIO_NAME = \"My Animation Studio\"\nSTUDIO_LOGO = \"studio_logo.png\"  # ローカルのファイルパス\nPROJECT_NAME = \"My Project\"\nOUTPUT_PDF = \"activity_report.pdf\"\n",[48,340,341,342,348],{},"Jinja2の構文（",[155,343,344],{},[345,346],"binding",{"value":347},"variable","）を使って、Pythonのデータを標準的なHTMLへ差し込みます。",[152,350,351,362],{},[155,352,355,356],{"className":353},[354],"language-html","\u003C!doctype html>\n\u003Chtml>\n\u003Chead>\n\u003Cmeta charset=\"utf-8\" />\n\u003Cstyle>\nbody {\nfont-family: Arial, sans-serif;\nmargin: 40px;\n}\nheader {\ndisplay: flex;\nalign-items: center;\nmargin-bottom: 30px;\n}\nheader img {\nheight: 50px;\nmargin-right: 20px;\n}\nh1 {\ncolor: #2a2a2a;\n}\ntable {\nwidth: 100%;\nborder-collapse: collapse;\nmargin-top: 20px;\n}\nth {\nbackground: #222;\ncolor: white;\npadding: 8px;\ntext-align: left;\n}\ntd {\npadding: 8px;\nborder-bottom: 1px solid #ccc;\n}\n.footer {\nmargin-top: 40px;\nfont-size: 10px;\ncolor: #777;\ntext-align: center;\n}\n\u003C/style>\n\u003C/head>",[152,357,360],{"className":358,"code":359,"language":292},[290],"&lt;body&gt;\n    &lt;header&gt;\n        &lt;img src=\"{{ studio_logo }}\" /&gt;\n        &lt;h1&gt;{{ studio_name }} – Activity Report&lt;/h1&gt;\n    &lt;/header&gt;\n\n    &lt;p&gt;\n        &lt;strong&gt;Project:&lt;/strong&gt; {{ project_name }}&lt;br /&gt;\n        &lt;strong&gt;Report Date:&lt;/strong&gt; {{ report_date }}\n    &lt;/p&gt;\n\n    &lt;table&gt;\n        &lt;tr&gt;\n            &lt;th&gt;Date&lt;/th&gt;\n            &lt;th&gt;Artist&lt;/th&gt;\n            &lt;th&gt;Task&lt;/th&gt;\n            &lt;th&gt;Entity&lt;/th&gt;\n            &lt;th&gt;Status&lt;/th&gt;\n        &lt;/tr&gt;\n        {% for row in rows %}\n        &lt;tr&gt;\n            &lt;td&gt;{{ row.date }}&lt;/td&gt;\n            &lt;td&gt;{{ row.artist }}&lt;/td&gt;\n            &lt;td&gt;{{ row.entity }}&lt;/td&gt;\n            &lt;td&gt;{{ row.type }}&lt;/td&gt;\n            &lt;td&gt;{{ row.status }}&lt;/td&gt;\n        &lt;/tr&gt;\n        {% endfor %}\n    &lt;/table&gt;\n\n    &lt;div class=\"footer\"&gt;Generated automatically by {{ studio_name }}&lt;/div&gt;\n&lt;/body&gt;\n",[155,361,359],{"__ignoreMap":12},[48,363,364],{},[155,365,367],{"className":366},[354],"\u003C/html>\n",[48,369,370,371,376],{},"このHTMLファイルは、レポートの視覚構造とスタイルを定義するJinja2テンプレートとして機能し、ページレイアウト、フォント、色、そしてアクティビティデータを表示するためのテーブルを含みます。",[155,372,373],{},[345,374],{"value":375},"..."," の式は、スタジオ名、ロゴURL、プロジェクト名、レポート日付などの値のプレースホルダーを示し、埋め込まれたCSSにより、レンダリングまたはPDFへの変換時に文書がきちんと整った印刷用の見た目になります。",[48,378,379,380,383,384,387],{},"Pythonコードがこのテンプレートをレンダリングすると、Jinja2がスクリプトから渡された実際の値で、すべてのプレースホルダーを置き換えます。そして",[155,381,382],{},"{% for row in rows %}","のループを実行し、アクティビティ記録ごとに1行のテーブルを生成します。",[155,385,386],{},"row","の辞書は、日付、アーティスト、タスク、エンティティ、ステータス、そして時間（hours）の値を提供し、hoursフィールドは小数点以下2桁で明示的にフォーマットされるため、テーブルが完全に埋められた完全なHTMLドキュメントが得られます。",[48,389,390],{},"レンダリングされたHTMLはWeasyPrintに渡されます。WeasyPrintは、HTML構造とインラインCSSの両方を解釈して、内容を印刷可能な文書としてレイアウトします。スタジオのロゴは、URLまたは相対パスを通じて読み込まれ、テーブルとテキストはテンプレートで定義された通りのスタイルになります。そしてすべてがPDFファイルにレンダリングされ、最後に「レポートは自動生成された」ことを示すフッターで締まります。",[61,392],{},[64,394,396],{"id":395},"_4-rendering","4. レンダリング",[48,398,399,400,403,404,407],{},"最後に、全部をつなぎ合わせます。",[155,401,402],{},"jinja2","を使ってHTML内のプレースホルダーにデータを流し込み、次に",[155,405,406],{},"WeasyPrint","でそのHTML文字列をPDFファイルに変換します：",[152,409,410,423],{},[155,411,413,414,417,420],{"className":412},[175],"from jinja2 import Environment, FileSystemLoader\nfrom weasyprint import HTML\nfrom datetime import date",[48,415,416],{},"env = Environment(loader=FileSystemLoader(\".\"))\ntemplate = env.get_template(\"report.html\")",[48,418,419],{},"html = template.render(\nstudio_name=STUDIO_NAME,\nstudio_logo=STUDIO_LOGO,\nproject_name=PROJECT_NAME,\nreport_date=date.today().isoformat(),\nrows=report,\n)",[48,421,422],{},"HTML(string=html, base_url=\".\").write_pdf(OUTPUT_PDF)",[48,424,425],{},[155,426,428],{"className":427},[175],"print(f\"PDF generated: {OUTPUT_PDF}\")\n",[48,430,431,432,435],{},"コードの最初の部分は、Jinja2に対して、現在のディレクトリからHTMLテンプレートを読み込むよう設定し、そのうえで前述の",[155,433,434],{},"report.html","を取得します。",[48,437,438],{},"次に、テンプレートは、実行時のデータをそれらのプレースホルダーに注入して、完全なHTMLドキュメントとしてレンダリングされます。スタジオとプロジェクトのメタデータが渡され、現在の日付はISO形式で生成されます。このステップの結果は、動的な値がすべて解決されたプレーンなHTML文字列です。",[48,440,441,442,445],{},"最後に、レンダリングされたHTMLはWeasyPrintに渡されます。WeasyPrintはHTMLと、関連するCSSやアセットを解析し、PDFファイルへ変換します。",[155,443,444],{},"base_url","パラメータにより、画像やスタイルシートへの相対パスが正しく動作するようになります。完成したPDFは出力先パスへ書き込まれ、その後、確認メッセージが出力されます。",[48,447,448],{},"この最終結果は次の通りです：",[72,450,452],{"className":451},[34,75],[77,453],{"src":454,"className":455,"alt":12,"loading":82,"width":83,"height":84,"srcSet":456,"sizes":86},"https://blog.cg-wire.com/content/images/2026/02/data-src-image-13e6f8e7-6700-4219-a7ed-6bbdb4850aab.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/02/data-src-image-13e6f8e7-6700-4219-a7ed-6bbdb4850aab.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/02/data-src-image-13e6f8e7-6700-4219-a7ed-6bbdb4850aab.png 1000w, https://blog.cg-wire.com/content/images/2026/02/data-src-image-13e6f8e7-6700-4219-a7ed-6bbdb4850aab.png 1600w",[48,458,459,462],{},[94,460,461],{"href":137},"対応するGithubリポジトリをクローン","すれば、1分でこのスクリプトを自分で実行してみることができます。",[61,464],{},[64,466,468],{"id":467},"_5-automation-tips","5. 自動化のヒント",[48,470,471],{},"自動化こそが、このワークフローの本当の“最大のリターン”です。レポートスクリプトがローカルで動くようになったら、次は人の介入なしに確実に動き、そして出力が、人々がすでに見に行く場所に届くようにします。",[48,473,474],{},"スクリプトを手作業で実行するのではなく、サーバーにcronジョブを設定して、予測可能な時間に実行しましょう。たとえば、毎営業日18:00に実行すれば、PDFは夜のうちに生成され、プロデューサーが仕事を始めるタイミングで準備が整います。日次のバーンダウンやショットのステータス要約にも特に役立ちます。",[48,476,477,478,480],{},"PDFが生成されたら、",[155,479,165],{},"を使ってKitsu内の適切なエンティティ（Production、Episode、繰り返しタスクなど）に直接添付します。これにより、レポートは“正真正銘の制作成果物”になり、永続的な履歴として残ります。たとえば、毎日のレポートを「Daily Production Report（毎日の制作レポート）」というタスクにアップロードすれば、時間の経過による変更の監査や、過去の判断を参照するのが簡単になります。実用的なコツとして、日付をファイル名と添付コメントの両方に含めると、KitsuのUI上で各レポートをダウンロードせずにすばやくスキャンできます。",[48,482,483,484,487,488,492],{},"レポートを関係者へ直接プッシュするには、Pythonの標準機能である",[155,485,486],{},"smtplib","（またはトランザクションメールサービス）を使って、PDFを添付して送信します。これは",[94,489,491],{"href":490},"https://blog.cg-wire.com/collaborative-animation-production/","一日中Kitsuの中にいないプロデューサーやクライアント","に最適です。具体的には、本文に短い要約（例：「Shots blocked: 12, shots finaled: 3」）を送り、詳細は完全なPDFを添付するという形が現実的です。",[48,494,495,496,310,499,502],{},"単一のHTMLレイアウトに固定せず、同じKitsuデータから異なるレポートスタイルを生成できるように、複数のJinja2テンプレート（",[155,497,498],{},"client_report.html",[155,500,501],{},"internal_audit.html","など）を保存しておくとよいでしょう。たとえば、クライアント向けにはクリーンでハイレベルなサマリー、社内の追跡にはより詳細なテーブル、といった使い分けができます。役立つ考え方として、ベースのテンプレートやマクロ（ヘッダー、テーブル、ステータスバッジ）を共有し、ブランディングやレイアウトの変更が、すべてのレポート種別へ波及するようにします。必要なら古いレポートを正確に再現できるように、これらのテンプレートもコードと一緒にバージョン管理しておきましょう。",[61,504],{},[64,506,508],{"id":507},"conclusion","結論",[48,510,511],{},"ここでのより大きなテーマは、PDFの話だけではありません。制作を前に進める“実際の作業”に向けて、時間と注意力を取り戻すことです！",[48,513,514],{},"GazuでKitsuから構造化されたデータを引き出し、Pythonで整形し、洗練された自動化レポートとしてレンダリングすることで、壊れやすい手作業の儀式を、静かにバックグラウンドで動く再現可能な仕組みに置き換えられます。これまで数時間かけて行っていたコピペ、整形、二重チェックは、正確なデータを、間に合うタイミングで、プロデューサーやクライアントが本当に読みたくなる形式で届ける、信頼できるパイプラインへと変わります。カスタムレポートによって、自信を持って進捗を伝えられ、危機（クランチ）になる前に問題を浮上させられ、そしてスタジオを“創造面で鋭いだけでなく技術的にも規律がある”存在として見せられます。",[48,516,517],{},"パイプラインが複雑になればなるほど、カスタムレポートを作る重要性は増します。インスピレーションとして、ぜひ私たちのスクリプトガイドももっと読んでみてください！",[31,519,521,525],{"className":520},[34,35,36],[31,522,524],{"className":523},[40],"📽️",[31,526,528,529,535],{"className":527},[45],"アニメーション制作プロセスについてさらに学ぶには ",[94,530,534],{"href":531,"rel":532},"https://www.cg-wire.com/community?ref=blog.cg-wire.com",[533],"noreferrer","私たちのDiscordコミュニティに参加することをご検討ください","！ベストプラクティスを共有する1,000人以上の専門家とつながり、時にはオフラインのイベントも企画しています。ぜひあなたをお迎えできるとうれしいです！ 😊",[31,537,541],{"className":538},[34,539,540],"kg-button-card","kg-align-center",[94,542,546],{"href":531,"className":543},[544,545],"kg-btn","kg-btn-accent","Discordコミュニティに参加する",{"title":12,"searchDepth":548,"depth":548,"links":549},2,[550,551,552,553,554,555,556],{"id":66,"depth":548,"text":67},{"id":143,"depth":548,"text":144},{"id":198,"depth":548,"text":199},{"id":319,"depth":548,"text":320},{"id":395,"depth":548,"text":396},{"id":467,"depth":548,"text":468},{"id":507,"depth":548,"text":508},"md","https://images.unsplash.com/photo-1666875753105-c63a6f3bdc86?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDR8fGRhc2hib2FyZHxlbnwwfHx8fDE3NzAwMjAyODZ8MA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":560,"featured_at":561,"visibility":562},"2026-02-20T06:03:57.000+01:00","false","public","/blog-i18n/ja/automated-kitsu-pdf-reports","2026-02-02T10:00:12.000+01:00",{"title":22,"description":12},"automated-kitsu-pdf-reports","blog-i18n/ja/automated-kitsu-pdf-reports/index",[569],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"5fff0e54653a0c003924f7f2","Pipeline Automation","pipeline","https://blog.cg-wire.com/tag/pipeline/","A1jHJcpx8texdbTYQ1gtp0HqhMaofvRtplW__o8urP8",{"id":576,"title":577,"authors":578,"body":580,"description":12,"extension":557,"feature_image":977,"html":7,"meta":978,"navigation":13,"path":980,"published_at":981,"seo":982,"slug":983,"stem":984,"tags":985,"__hash__":991,"updated_at":979,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/automating-kitsu-production-onboarding/index.md","CSVインポートでKitsuの制作環境をスケールさせる（2026）",[579],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":581,"toc":969},[582,593,601,604,607,610,637,639,643,646,688,695,698,701,711,713,717,720,723,740,746,752,755,757,761,764,774,781,793,795,799,802,826,829,832,835,838,841,843,847,850,881,884,894,901,904,907,915,921,923,925,928,931,945,948,963],[31,583,585,589],{"className":584},[34,35,36],[31,586,588],{"className":587},[40],"🚀",[31,590,592],{"className":591},[45],"クリーンなスタジオデータを自動で取り込むことで、数分で新しいKitsuの制作を立ち上げます。",[48,594,595,596,600],{},"Kitsuで新しいショーやシーンを作るのにフォームをクリックして回り、アセットリストを作り直し、アーティストを1人ずつ割り当てる必要があるなら、",[94,597,599],{"href":598},"https://blog.cg-wire.com/client-communication-animation/","オンボーディングは不足しています","。",[48,602,603],{},"こうした手作業のオーバーヘッドは、すぐに積み上がります。制作が変わるたびに同じセットアップ儀式が繰り返され、クルーのオンボーディングはコピペ合戦になり、各ステップごとに何かが壊れる別のチャンスが増えていきます。スタジオ規模では、この摩擦が本当の時間・本当の金銭・本当の正気をコストとして奪います。",[48,605,606],{},"最も速いスタジオは、Kitsuを単に使うだけではありません。パイプラインに組み込みます。制作データベースのように扱い、新しいショー、ショット、または部署が“日”ではなく“分”でオンラインになれるよう、クリーンで構造化されたスタジオデータを投入します。パイプラインは複製され、チームは自動的に紐づけられ、Kitsuはボトルネックではなくエンジンになります。",[48,608,609],{},"この記事では、CSVファイルとKitsuのPython API（Gazu）を使って、まさにそれを実現するための実務的で制作実証済みのワークフローを分解していきます。制作オンボーディングのセットアップ作業を“消す”ために、どのように自動化するかを説明します。",[31,611,613,616],{"className":612},[34,35,108],[31,614,112],{"className":615},[40],[31,617,619,624,626,628,629,631,134,633],{"className":618},[45],[117,620,621],{},[120,622,623],{"style":122},"動く例を探していますか？",[125,625],{},[125,627],{},"このガイドで紹介している例の統合の完全なソースコードは、GitHubで確認できます：",[125,630],{},[125,632],{},[94,634,636],{"href":635},"https://github.com/cgwire/blog-tutorials/tree/main/import-spreadsheet-to-kitsu?ref=blog.cg-wire.com","https://github.com/cgwire/blog-tutorials/tree/main/import-spreadsheet-to-kitsu",[61,638],{},[64,640,642],{"id":641},"what-you-can-import","インポートできるもの",[48,644,645],{},"実際の制作では、データの大部分がいくつかの繰り返しパターンに分類され、どれも自動化に向いています：",[212,647,648,666,682],{},[215,649,650,653,654,658,659,658,662,665],{},[120,651,652],{},"アーティスト"," - あなたのクルーはどこか別の場所にすでに存在しています。HRシート、給与計算のエクスポート、Notionのテーブルなどです。そこには通常、",[655,656,657],"em",{},"Animator","、",[655,660,661],{},"TD",[655,663,664],{},"Supervisor","のような役割とともに、名前やメールアドレスが含まれています。Kitsuでユーザーを手作業で再作成する代わりに、そのリストを1回のパスでインポートすれば、1日目の前にチームを準備できます。",[215,667,668,671,672,658,675,658,678,681],{},[120,669,670],{},"アセット"," - キャラクター、プロップ、環境……命名規則に従うものなら、簡単に自動化できます。",[155,673,674],{},"CHAR_RobotA",[155,676,677],{},"PROP_Sword_01",[155,679,680],{},"ENV_CityBlock","のようなエントリが入ったCSVは、数秒でKitsu内の完全にセットされたアセットリストへと変換でき、パイプラインが期待するのとまったく同じ形に整理されます。",[215,683,684,687],{},[120,685,686],{},"タスク"," - タスクもまた、手作業のセットアップが特に痛む領域です。モデリング、リギング、サーフェシング、アニメーション……こうしたタスクタイプは、ショーごとに頻繁に変わることはありません。タスクを一括でインポートすれば、すべてのアセットに適切なタスクリスト（スタック）を自動的に紐づけたり、UIで何百行もクリックする代わりに、アーティストや部署を事前に割り当てたりできます。",[48,689,690,691,694],{},"基本を超えて、Kitsuが理解する",[94,692,693],{"href":250},"あらゆる制作向けデータ","をインポートできます。シーケンス、ショット、エピソード、さらには“制作全体”までも可能です。これにより、過去のショーの構造をそのまま複製したり、同じレイアウトと命名規則で新しいシーズンを立ち上げたりするのが簡単になります。",[48,696,697],{},"ほとんどのスタジオは、すでにこれらをスプレッドシートに保存しています。そのスプレッドシートをデータソースとして扱い、Kitsuへ直接投入し、自動化にセットアップ作業を任せましょう。",[48,699,700],{},"KitsuのUIは基本的なスプレッドシートのインポートに対応していますが、スクリプトはそれをはるかに超えます。KitsuのPython API（Gazu）なら、Notionからタスクを同期する、アセットトラッカーをミラーする、スケジュールが変わったらタスクリストを再生成する、といった一連の自動化をつなげられます。",[72,702,704],{"className":703},[34,75],[77,705],{"src":706,"className":707,"alt":12,"loading":82,"width":708,"height":709,"srcSet":710},"https://blog.cg-wire.com/content/images/2026/02/data-src-image-82a7e584-d2c0-4457-9ea4-4e97c794b6ff.png",[81],600,611,"https://blog.cg-wire.com/content/images/2026/02/data-src-image-82a7e584-d2c0-4457-9ea4-4e97c794b6ff.png 600w",[61,712],{},[64,714,716],{"id":715},"_1-csv-parser","1. CSVパーサー",[48,718,719],{},"最初のステップは、スタジオデータの読み取り方を標準化することです。CSVは理想的です。制作側が編集しやすく、スクリプト側が解析しやすいからです。",[48,721,722],{},"このチュートリアルではシンプルさのためにアーティストのデータモデルに焦点を当てますが、Googleドライブに保存したアセットや、Trelloのタスクでも同様のことができます。",[152,724,725,730],{},[155,726,729],{"className":727},[728],"language-py","def load_csv(file_path: Path) -> pd.DataFrame:\n    \"\"\"Load a CSV file into a pandas DataFrame.\"\"\"\n    return pd.read_csv(file_path)\n",[48,731,732],{},[155,733,735,736,739],{"className":734},[728],"def parse_artists(df: pd.DataFrame) -> List",[263,737,738],{},"Dict",":\n\"\"\"\nExpected columns:\n- email\n- first_name\n- last_name\n- role\n\"\"\"\nreturn df.to_dict(orient=\"records\")\n",[48,741,742,745],{},[155,743,744],{},"load_csv","は、生のCSVファイルをPythonが扱える形に変える入口です。pandasを使ってディスクからファイルを読み取り、DataFrameを返します。これにより、Kitsuへ送信する前にフィルタリング、検証、変換が可能な、構造化された“表のような表現”になります。",[48,747,748,751],{},[155,749,750],{},"parse_artists","は、アーティストデータを表すDataFrameを受け取り、各行をアーティストのメール、名前、役割を含む辞書へと変換します。これらの辞書のリストを返すことで、KitsuまたはGazuに直接渡してユーザーを一括で作成できる、API向けのデータが生成されます。アーティストを1人ずつ追加する必要はありません。",[48,753,754],{},"たとえば、Google SheetsからクルーリストをエクスポートするTVアニメ制作スタジオなら、それを単にCSVとして保存すれば済みます。制作はデータの管理を保持しつつ、TDは各ショーごとにフォーマット変更を依頼されることなく取り込みを自動化できます。",[61,756],{},[64,758,760],{"id":759},"_2-kitsu-auth","2. Kitsu認証",[48,762,763],{},"何かをアップロードする前に、Kitsuインスタンスに対して認証する必要があります：",[152,765,766],{},[155,767,182,769,188,772,193],{"className":768},[728],[94,770,185],{"href":185,"rel":771},[187],[94,773,192],{"href":191},[48,775,776,777,780],{},"実際には、スタジオは自動化のために専用の",[120,778,779],{},"パイプラインアカウントまたは管理者アカウント","を使うことがよくあります。これにより権限の問題を避けられ、スクリプトがデータを作成・変更するときも監査ログをきれいに保てます。",[48,782,783,784,792],{},"ローカルでのテスト用には、",[94,785,787,788,791],{"href":786},"https://blog.cg-wire.com/dcc-integration-blender-kitsu/","「",[155,789,790],{},"kitsu-docker","」のインストールを使う","のがおすすめです。",[61,794],{},[64,796,798],{"id":797},"_3-loading-data","3. データの読み込み",[48,800,801],{},"オンボーディング時に、アーティストは通常最初のボトルネックになります。メールを集めて招待を送り、タスクへ割り当てる必要があります……それらの作成を自動化すれば、制作コーディネーターが手作業で費やす何時間もの作業を削減できます。",[152,803,804,821],{},[155,805,807,808,810,811,814,815],{"className":806},[728],"def upload_artists(artists: List",[263,809,738],{},"):\n\"\"\"\nCreate artists if they do not already exist.\n\"\"\"\nexisting_users = {\nuser",[263,812,813],{},"\"email\"",": user\nfor user in gazu.person.all_persons()\n}",[152,816,819],{"className":817,"code":818,"language":292},[290],"for artist in artists:\n    if artist[\"email\"] in existing_users:\n        print(f\"Artist exists: {artist['email']}\")\n        continue\n\n    gazu.person.new_person(\n        artist[\"first_name\"],\n        artist[\"last_name\"],\n        artist[\"email\"],\n    )\n    print(f\"Created artist: {artist['email']}\")\n",[155,820,818],{"__ignoreMap":12},[48,822,823],{},[155,824],{"className":825},[728],[48,827,828],{},"この関数は、アーティストの辞書リストを受け取り、重複を避けながらKitsuへ同期します。",[48,830,831],{},"まずKitsuに対して既存ユーザーをすべて問い合わせ、メールをキーにしたルックアップテーブルを作成します。これにより、アーティストがすでに存在するかを高速に確認できます。",[48,833,834],{},"次に、入力されたアーティストデータを順に処理し、各エントリについてメールをルックアップと照合します。マッチが見つかればスクリプトは作成をスキップし、そのアーティストがすでに存在することをログに記録します。マッチが見つからなければ、Gazu APIを使ってアーティストの名前とメールからKitsuに新しいユーザーを作成し、確認メッセージを出力します。",[48,836,837],{},"この結果、再実行しても安全な“冪等（べきとう）”なインポートステップになります。新しいアーティストは追加され、既存のアーティストはそのまま変更されません。",[48,839,840],{},"長尺映画の立ち上げ段階では、制作側がHRデータから数百人のアーティストを1分もかからずにインポートできるでしょう。遅れて参加するスタッフは、CSVを更新してスクリプトを再実行するだけで追加でき、ユーザーの重複や手作業の確認は不要になります。",[61,842],{},[64,844,846],{"id":845},"_4-tying-it-all-together","4. すべてをつなぐ",[48,848,849],{},"メインの入口では、すべてをひとまとめにします：",[152,851,852,876],{},[155,853,855,856,859,860,863,864,188,867,869,870],{"className":854},[728],"if ",[120,857,858],{},"name"," == \"",[120,861,862],{},"main","\":\ngazu.set_host(\"",[94,865,185],{"href":185,"rel":866},[187],[94,868,192],{"href":191},"\", \"mysecretpassword\")",[152,871,874],{"className":872,"code":873,"language":292},[290],"artists_df = load_csv(Path(\"artists.csv\"))\n\nartists = parse_artists(artists_df)\n\nupload_artists(artists)\n",[155,875,873],{"__ignoreMap":12},[48,877,878],{},[155,879],{"className":880},[728],[48,882,883],{},"このブロックは、ファイルが直接実行されたときにのみ動作します。別のモジュールにインポートされた場合は動きません。",[48,885,886,887,890,891,893],{},"認証後、",[155,888,889],{},"artists.csv","をpandasのDataFrameに読み込み、",[155,892,750],{},"でそれらの行をアーティスト辞書のリストへ変換し、名前によってKitsu内の既存の制作を取得します。",[48,895,896,897,900],{},"最後に、準備されたデータを反復してKitsuでアーティストアカウントを作成する役割を担う",[155,898,899],{},"upload_artists","を呼び出します。UIの手作業なしで、制作オンボーディングの自動化ステップが完了します。",[48,902,903],{},"実際には、スタジオはこれらのスクリプトをパイプラインのツールと一緒にバージョン管理します。新しいショーはチェックリストではなく、再現可能なコマンドになります。",[48,905,906],{},"これで、Kitsuのダッシュボードにログインし、最終結果を確認できます：",[72,908,910],{"className":909},[34,75],[77,911],{"src":912,"className":913,"alt":12,"loading":82,"width":83,"height":84,"srcSet":914,"sizes":86},"https://blog.cg-wire.com/content/images/2026/02/data-src-image-9f641c9c-07b5-4154-9c42-45279f6a9d20.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/02/data-src-image-9f641c9c-07b5-4154-9c42-45279f6a9d20.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/02/data-src-image-9f641c9c-07b5-4154-9c42-45279f6a9d20.png 1000w, https://blog.cg-wire.com/content/images/2026/02/data-src-image-9f641c9c-07b5-4154-9c42-45279f6a9d20.png 1600w",[48,916,917,920],{},[94,918,919],{"href":635},"対応するGithubリポジトリをご覧ください","。ニーズに合わせて簡単にフォークして使える、動く例があります！",[61,922],{},[64,924,508],{"id":507},[48,926,927],{},"最良の形では、Kitsuの自動化によってテクニカルディレクターが、制作が生まれるプロセスの主導権を取り戻せます。パイプラインがクリーンなデータから自分自身を生成できるなら、オンボーディングは“面倒な作業”でなくなります。アーティスト、アセット、タスクをKitsuに直接インポートすることで、冗長な作業を排除し、人為的なミスを減らし、制作オンボーディングを予測可能にします。このアプローチは、小規模チームから複数ショーを抱えるスタジオまでスケールします。",[48,929,930],{},"インポートパイプラインをさらに面白くするために、追加できる機能は次のとおりです：",[212,932,933,936,939,942],{},[215,934,935],{},"役割に基づいてタスクをアーティストへ自動割り当てする",[215,937,938],{},"制作管理のために部署を入力する",[215,940,941],{},"予算の制約にもとづいて、初期見積と各部署のカレンダーを生成する",[215,943,944],{},"スクリプトを各ショットのブレイクダウンリストに変換し、それを使ってアセットを事前生成する",[48,946,947],{},"このリストはまだ続けられますが、とにかく小さく始めてみてください！",[31,949,951,954],{"className":950},[34,35,36],[31,952,524],{"className":953},[40],[31,955,957,958,962],{"className":956},[45],"アニメーションのプロセスについてもっと知りたい方は ",[94,959,961],{"href":531,"rel":960},[533],"私たちのDiscordコミュニティに参加することを検討してください","！ ベストプラクティスを共有する1,000人以上の専門家とつながり、時には現地イベントも企画しています。ぜひ歓迎します！ 😊",[31,964,966],{"className":965},[34,539,540],[94,967,546],{"href":531,"className":968},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":970},[971,972,973,974,975,976],{"id":641,"depth":548,"text":642},{"id":715,"depth":548,"text":716},{"id":759,"depth":548,"text":760},{"id":797,"depth":548,"text":798},{"id":845,"depth":548,"text":846},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1504868584819-f8e8b4b6d7e3?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDN8fHNwcmVhZHNoZWV0fGVufDB8fHx8MTc3MDA0NDU0MXww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":979,"featured_at":561,"visibility":562},"2026-02-20T06:03:58.000+01:00","/blog-i18n/ja/automating-kitsu-production-onboarding","2026-02-16T10:00:37.000+01:00",{"title":577,"description":12},"automating-kitsu-production-onboarding","blog-i18n/ja/automating-kitsu-production-onboarding/index",[986],{"id":987,"name":988,"slug":989,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":990},"5fff0e4b653a0c003924f7f0","Production Management","production-management","https://blog.cg-wire.com/tag/production-management/","C69B6mCcB0VkTI8upL9CC7VUJLkC8_oHpEuIgReKt3s",{"id":993,"title":994,"authors":995,"body":997,"description":12,"extension":557,"feature_image":1833,"html":7,"meta":1834,"navigation":13,"path":1836,"published_at":1837,"seo":1838,"slug":1839,"stem":1840,"tags":1841,"__hash__":1848,"updated_at":1835,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/blender-addon-ui-scripting-guide/index.md","BlenderアドオンUI開発のための2026年ガイド",[996],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":998,"toc":1815},[999,1010,1018,1021,1047,1049,1055,1058,1078,1087,1094,1097,1104,1124,1130,1141,1155,1193,1199,1202,1205,1210,1216,1221,1227,1232,1238,1246,1248,1254,1257,1271,1274,1284,1289,1295,1300,1306,1311,1317,1322,1328,1331,1369,1372,1374,1380,1383,1393,1396,1402,1453,1462,1468,1471,1483,1536,1542,1545,1557,1618,1624,1627,1639,1665,1672,1698,1700,1706,1709,1732,1742,1748,1757,1760,1778,1780,1784,1787,1792,1795,1809],[31,1000,1002,1006],{"className":1001},[34,35,36],[31,1003,1005],{"className":1004},[40],"📄",[31,1007,1009],{"className":1008},[45],"Blenderスクリプトを、アーティストが実際に使いたくなる本物のツールに変えよう。アドオン用のクリーンで直感的なUIパネルの作り方はこちらです。",[48,1011,1012,1013,1017],{},"これまでに ",[94,1014,1016],{"href":1015},"https://blog.cg-wire.com/blender-scripting-animation/","Blenderスクリプトを書いた","ことがあるなら、正しく機能させるのは戦いの半分にすぎず、もう半分は「誰かにそれを使ってもらうこと」だと気づいたはずです。Blenderアドオンを共有し、販売するには、クリーンなユーザーインターフェースが必須です。",[48,1019,1020],{},"このガイドでは、内蔵のレイアウトシステムを使ってBlenderアドオンのユーザーインターフェースを作る方法を学びます。よく使うUIコンポーネントの種類、パネルが表示され得る場所、そして最小限の動作例を順を追って解説します。最後には、アドオンにBlenderネイティブなグラフィカルインターフェースを与える方法が分かるようになります。",[31,1022,1024,1027],{"className":1023},[34,35,108],[31,1025,112],{"className":1026},[40],[31,1028,1030,1034,1036,1038,1039,1041,134,1043],{"className":1029},[45],[117,1031,1032],{},[120,1033,123],{"style":122},[125,1035],{},[125,1037],{},"このガイドで紹介している例の統合についての完全なソースコードは、私たちのGitHubで確認できます：",[125,1040],{},[125,1042],{},[94,1044,1046],{"href":1045},"https://github.com/cgwire/blender-ui-addon-script?ref=blog.cg-wire.com","https://github.com/cgwire/blender-ui-addon-script",[61,1048],{},[64,1050,1052],{"id":1051},"_1-common-ui-components",[120,1053,1054],{},"1. よくあるUIコンポーネント",[48,1056,1057],{},"Blenderでは、ユーザーインターフェースのあらゆる要素に、Pythonライブラリ上の対応物があります。UIは、次のいずれかの型を継承するクラスを作成することで構築します：",[212,1059,1060,1066,1072],{},[215,1061,1062,1065],{},[155,1063,1064],{},"bpy.types.Panel"," - カスタムパネル（最も一般的）",[215,1067,1068,1071],{},[155,1069,1070],{},"bpy.types.Menu"," - メニューおよびサブメニュー",[215,1073,1074,1077],{},[155,1075,1076],{},"bpy.types.Operator"," - ボタンから実行できるアクションやツール",[72,1079,1081],{"className":1080},[34,75],[77,1082],{"src":1083,"className":1084,"alt":12,"loading":82,"width":1085,"height":1086},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-daa22afa-ac20-4e3e-8543-c694588146bf.png",[81],334,542,[48,1088,1089,1090,1093],{},"これらのクラスは、それぞれ ",[155,1091,1092],{},"draw(self, context)"," メソッドを実装できます。レイアウトコマンドを使って、どのようなインターフェースにするべきかを説明します。Blenderのレイアウトシステムは、スペース、整列、位置などを自動的に処理します。これは宣言的なUIシステムで、何が表示され、どの順番にすべきかを説明するだけです。",[48,1095,1096],{},"ここでは、よく使うレイアウト要素を紹介します：",[1098,1099,1101],"h3",{"id":1100},"basic-display-elements",[120,1102,1103],{},"基本的な表示要素",[212,1105,1106,1115],{},[215,1107,1108,1111,1112],{},[120,1109,1110],{},"Label"," - 対話なしのテキストをそのまま表示します。形式： ",[155,1113,1114],{},"layout.label(text=\"こんにちは！\")",[215,1116,1117,1120,1121],{},[120,1118,1119],{},"Separator"," - 読みやすくするために、項目の間に縦方向のスペースを追加します。形式： ",[155,1122,1123],{},"layout.separator()",[1098,1125,1127],{"id":1126},"buttons-inputs-props-and-operators",[120,1128,1129],{},"ボタン、入力、Props（プロパティ）、Operators（オペレーター）",[212,1131,1132],{},[215,1133,1134,1137,1138],{},[120,1135,1136],{},"Operatorボタン"," - オペレーター（Blenderコマンドとして登録された関数）を呼び出すクリック可能なボタンを作成します。書き出し、複製、カスタムスクリプトの実行のようなアクションに使えます。構文： ",[155,1139,1140],{},"layout.operator(\"myaddon.some_action\", text=\"アクションを実行\")",[48,1142,1143,1146,1147,1150,1151,1154],{},[155,1144,1145],{},"layout.prop()"," メソッドは、編集可能なBlenderプロパティを表示するために使います。プロパティには、内蔵データ（例： ",[155,1148,1149],{},"context.object","）のほか、自分で定義したカスタムプロパティも含まれます。たとえば ",[155,1152,1153],{},"layout.prop(context.object, \"name\")"," は、オブジェクトの名前の編集用テキストフィールドを表示します。Blenderは、プロパティの型に応じて適切なウィジェット（テキストボックス、スライダー、チェックボックスなど）を自動で選びます：",[212,1156,1157,1166,1175,1184],{},[215,1158,1159,1162,1163],{},[120,1160,1161],{},"チェックボックス（Booleanプロパティ）"," - トグル式のチェックボックスを表示します。例： ",[155,1164,1165],{},"layout.prop(context.object, \"hide_viewport\")",[215,1167,1168,1171,1172],{},[120,1169,1170],{},"数値フィールド／スライダー（FloatまたはInt）"," - 数値入力を表示し、しばしばスライダー付きです。例： ",[155,1173,1174],{},"layout.prop(context.object, \"location\", index=0, text=\"X位置\")",[215,1176,1177,1180,1181],{},[120,1178,1179],{},"ドロップダウンメニュー（Enumプロパティ）"," - EnumPropertyのときにドロップダウンリストを表示します。例： ",[155,1182,1183],{},"layout.prop(context.object, \"type\")",[215,1185,1186,1189,1190],{},[120,1187,1188],{},"テキスト入力 ","- 文字列プロパティのためのテキストボックスを表示します。例： ",[155,1191,1192],{},"layout.prop(my_settings, \"username\")",[1098,1194,1196],{"id":1195},"organizing-the-layout",[120,1197,1198],{},"レイアウトを整理する",[48,1200,1201],{},"UIを構造化して理解しやすく保つために、Blenderは行、列、ボックスのようなレイアウトコンテナを提供しています。",[48,1203,1204],{},"パネルには行と列があります。行と列には、プロパティ、オペレーター、ラベルが含まれます。Blenderは、テーマやレイアウトルールに合わせて、パディング、整列、スケーリングを自動的に処理します。",[212,1206,1207],{},[215,1208,1209],{},"行（水平グループ）は、要素を横方向に並べます：",[152,1211,1212],{},[155,1213,1215],{"className":1214},[175],"row = layout.row()\nrow.prop(obj, \"location\")\nrow.prop(obj, \"rotation_euler\")",[212,1217,1218],{},[215,1219,1220],{},"列（垂直グループ）は、要素を縦方向に積み重ねます：",[152,1222,1223],{},[155,1224,1226],{"className":1225},[175],"col = layout.column()\ncol.prop(obj, \"scale\")\ncol.prop(obj, \"dimensions\")",[212,1228,1229],{},[215,1230,1231],{},"ボックス（視覚的グループ）は、セクションのような関連するコントロールを視覚的にまとめるための、枠付きのボックスを描画します：",[152,1233,1234],{},[155,1235,1237],{"className":1236},[175],"box = layout.box()\nbox.label(text=\"変換設定\")\nbox.prop(obj, \"location\")\nbox.prop(obj, \"rotation_euler\")",[48,1239,1240,1241,1245],{},"UIコンポーネントの完全な一覧は、",[94,1242,1244],{"href":1243},"https://docs.blender.org/manual/en/latest/interface/index.html?ref=blog.cg-wire.com","公式Blenderドキュメントの「ユーザーインターフェース」ページ","を参照してください。",[61,1247],{},[64,1249,1251],{"id":1250},"_2-where-you-can-put-ui-panels",[120,1252,1253],{},"2. UIパネルを配置できる場所",[48,1255,1256],{},"Blenderでカスタムパネルを作成する際、インターフェースのどこに表示され、どの領域を占有するかを、2つの重要なクラス属性で決められます：",[212,1258,1259,1265],{},[215,1260,1261,1264],{},[155,1262,1263],{},"bl_space_type"," - パネルが属するエディター／ワークスペース（例：3Dビュー、プロパティエディター、ノードエディター）。",[215,1266,1267,1270],{},[155,1268,1269],{},"bl_region_type"," - そのエディターのどの部分にパネルが表示されるか（例：サイドバー、ツールバー、メインウィンドウ）。",[48,1272,1273],{},"カスタムパネルを置く可能性が高い代表的な場所の一覧です：",[72,1275,1277],{"className":1276},[34,75],[77,1278],{"src":1279,"className":1280,"alt":12,"loading":82,"width":1281,"height":1282,"srcSet":1283,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-070d3dfe-eb98-42a2-90a2-d2eabc4fc2d4.png",[81],1125,650,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-070d3dfe-eb98-42a2-90a2-d2eabc4fc2d4.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-070d3dfe-eb98-42a2-90a2-d2eabc4fc2d4.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-070d3dfe-eb98-42a2-90a2-d2eabc4fc2d4.png 1125w",[212,1285,1286],{},[215,1287,1288],{},"3Dビューのサイドバーは、3Dビューポートの右側にあるNパネルサイドバーに表示されます。モデリング、リギング、シーンツールのための最も一般的な配置場所です：",[152,1290,1291],{},[155,1292,1294],{"className":1293},[175],"bl_space_type = 'VIEW_3D'\nbl_region_type = 'UI'",[212,1296,1297],{},[215,1298,1299],{},"プロパティエディター内に、オブジェクト、マテリアル、シーンの各タブの間にパネルを追加できます。アドオンがマテリアル、オブジェクト、レンダー設定、シーンプロパティを扱う場合に使います：",[152,1301,1302],{},[155,1303,1305],{"className":1304},[175],"bl_space_type = 'PROPERTIES'\nbl_region_type = 'WINDOW'",[212,1307,1308],{},[215,1309,1310],{},"UV/Imageエディターのサイドバー（テクスチャツールや画像ユーティリティに便利）：",[152,1312,1313],{},[155,1314,1316],{"className":1315},[175],"bl_space_type = 'IMAGE_EDITOR'\nbl_region_type = 'UI'",[212,1318,1319],{},[215,1320,1321],{},"ノードを扱うツールのための、シェーダー、ジオメトリノード、コンポジターエディターのサイドバー：",[152,1323,1324],{},[155,1325,1327],{"className":1326},[175],"bl_space_type = 'NODE_EDITOR'\nbl_region_type = 'UI'",[48,1329,1330],{},"最適なパネルの配置場所は、ツールの目的によって変わります：",[212,1332,1333,1344,1353,1361],{},[215,1334,1335,1336,1339,1340,1343],{},"モデリング／オブジェクトツール → 3Dビューサイドバー（",[155,1337,1338],{},"VIEW_3D"," + ",[155,1341,1342],{},"UI","）",[215,1345,1346,1347,1339,1350,1343],{},"マテリアルまたはレンダー設定 → プロパティエディター（",[155,1348,1349],{},"PROPERTIES",[155,1351,1352],{},"WINDOW",[215,1354,1355,1356,1339,1359,1343],{},"テクスチャユーティリティ → 画像エディターサイドバー（",[155,1357,1358],{},"IMAGE_EDITOR",[155,1360,1342],{},[215,1362,1363,1364,1339,1367,1343],{},"シェーダー／ジオメトリツール → ノードエディターサイドバー（",[155,1365,1366],{},"NODE_EDITOR",[155,1368,1342],{},[48,1370,1371],{},"適切な「スペース」を選ぶと、ユーザーが自然に期待する場所にアドオンが見つかり、UIをBlenderに合わせて一貫させられます。",[61,1373],{},[64,1375,1377],{"id":1376},"_3-minimal-example-custom-panel-in-the-3d-view-sidebar",[120,1378,1379],{},"3. 最小の例：3Dビューサイドバーにカスタムパネル",[48,1381,1382],{},"簡単なプラグインを試してみましょう。ボタンをクリックすると「Hello world」のテキストアラートを表示する、3Dビューサイドバーのカスタムパネルです。",[1098,1384,1386],{"id":1385},"_1-blinfoaddon-metadata",[120,1387,1388,1389,1392],{},"1) ",[155,1390,1391],{},"bl_info"," - アドオンメタデータ",[48,1394,1395],{},"まず、Blenderに対して、アドオンをどのように潜在ユーザーへ提示するかを伝えるためのアドオンメタデータを指定します：",[152,1397,1398],{},[155,1399,1401],{"className":1400},[175],"bl_info = {\n    \"name\": \"Simple Addon Example\",\n    \"author\": \"Your Name\",\n    \"version\": (1, 0),\n    \"blender\": (4, 0, 0),\n    \"location\": \"View3D > Sidebar > Simple Tab\",\n     \"description\": \"A simple example addon that prints a message\",\n     \"category\": \"3D View\",\n}",[212,1403,1404],{},[215,1405,1406,1408,1409],{},[155,1407,1391],{}," は、Preferences → Add-ons でアドオン情報を表示するためにBlenderが使う、モジュールレベルの辞書です。",[212,1410,1411,1417,1423,1429,1435,1441,1447],{},[215,1412,1413,1416],{},[155,1414,1415],{},"name:"," リストに表示される、読みやすい名前",[215,1418,1419,1422],{},[155,1420,1421],{},"author:"," 著者文字列",[215,1424,1425,1428],{},[155,1426,1427],{},"version:"," アドオンのバージョンを表すタプル",[215,1430,1431,1434],{},[155,1432,1433],{},"blender:"," このアドオンが対象とする最小のBlenderバージョン（タプル）",[215,1436,1437,1440],{},[155,1438,1439],{},"location:"," アドオンUIが表示される場所（ユーザーにとって役立つ）",[215,1442,1443,1446],{},[155,1444,1445],{},"description:"," UIで使われる短い説明",[215,1448,1449,1452],{},[155,1450,1451],{},"category:"," Add-onsリスト内でのカテゴリのグルーピング",[48,1454,1455,1456,1458,1459,1461],{},"インストール済みアドオンをスキャンするときにBlenderが",[155,1457,1391],{},"を読み取るので、",[155,1460,1391],{},"は正確に保つことが重要です。",[1098,1463,1465],{"id":1464},"_2-define-an-operator-class",[120,1466,1467],{},"2) オペレータークラスを定義する",[48,1469,1470],{},"次に、Operatorのサブクラスを定義します。オペレーターは、Blenderでアクションを行うための公式な方法です。UI、ショートカット、検索メニューなどから呼び出せます。",[152,1472,1473,1477],{},[155,1474,1476],{"className":1475},[175],"class SIMPLEADDON_OT_hello(bpy.types.Operator):\n    bl_idname = \"simple_addon.say_hello\"\n    bl_label = \"Say Hello\"\n     bl_description = \"Prints a message to the console\"\n",[48,1478,1479],{},[155,1480,1482],{"className":1481},[175],"    def execute(self, context):\n        self.report({'INFO'}, \"Hello from Blender Addon!\")\n         print(\"Hello from Blender Addon!\")\n         return {'FINISHED'}",[212,1484,1485,1499,1505,1511],{},[215,1486,1487,1490,1491,1494,1495,1498],{},[155,1488,1489],{},"bl_idname"," - ",[155,1492,1493],{},"\"module_name.operator_name\""," という形式の一意な識別子文字列です。すべて小文字で、ドットで区切ります。コードやUIからオペレーターを呼び出す方法です（",[155,1496,1497],{},"bpy.ops.simple_addon.say_hello()","）。",[215,1500,1501,1504],{},[155,1502,1503],{},"bl_label"," - ボタン／メニューに表示されるユーザー向けラベル。",[215,1506,1507,1510],{},[155,1508,1509],{},"bl_description"," - UIに表示されるツールチップ／説明。",[215,1512,1513,1516,1517,1520,1521,1524,1525,1528,1529,310,1532,1535],{},[155,1514,1515],{},"execute(self, context)"," - オペレーターが実行されるときに呼び出される中核メソッド（同期実行）。",[155,1518,1519],{},"context"," は、Blenderの現在の状態（アクティブオブジェクト、シーン、エリアなど）にアクセスできるようにします。",[155,1522,1523],{},"self.report({'INFO'}, \"…\")"," は、Blenderの情報バー／ステータスに小さなメッセージを表示します（ユーザーへのフィードバックに適しています）。",[155,1526,1527],{},"print(\"…\")"," は、システム／Blenderコンソールへ出力します（デバッグに便利です）。",[155,1530,1531],{},"{'FINISHED'}",[155,1533,1534],{},"{'CANCELLED'}"," のような set を返します。Blenderは、この結果を使ってオペレーターが正常に完了したかどうかを判断します。",[1098,1537,1539],{"id":1538},"_3-panel-classui-placement",[120,1540,1541],{},"3) パネルクラス - UIの配置",[48,1543,1544],{},"次に、BlenderにUIを追加するためのPanelのサブクラスに進みます：",[152,1546,1547,1551],{},[155,1548,1550],{"className":1549},[175],"class SIMPLEADDON_PT_panel(bpy.types.Panel):\n    bl_label = \"Simple Addon Panel\"\n    bl_idname = \"SIMPLEADDON_PT_panel\"\n    bl_space_type = 'VIEW_3D'\n    bl_region_type = 'UI'\n    bl_category = 'Simple'",[48,1552,1553],{},[155,1554,1556],{"className":1555},[175],"    def draw(self, context):\n        layout = self.layout\n        layout.operator(\"simple_addon.say_hello\")",[212,1558,1559,1564,1569,1575,1584,1590,1595,1605],{},[215,1560,1561,1563],{},[155,1562,1503],{}," - UIに表示されるパネルのタイトル。",[215,1565,1566,1568],{},[155,1567,1489],{}," - 一意なパネル識別子。",[215,1570,1571,1574],{},[155,1572,1573],{},"bl_space_type = 'VIEW_3D'"," - このパネルが3Dビューポート領域に属することをBlenderに伝えます。",[215,1576,1577,1580,1581,1498],{},[155,1578,1579],{},"bl_region_type = 'UI'"," - 右側の領域（Nパネル）に配置します。他にも領域があります（例：",[155,1582,1583],{},"'TOOLS', 'WINDOW'",[215,1585,1586,1589],{},[155,1587,1588],{},"bl_category = 'Simple'"," - サイドバーのタブ名。このパネルは「Simple」というラベルのタブの下に表示されます。",[215,1591,1592,1594],{},[155,1593,1092],{}," - UIレイアウトを描画するために呼び出されます。",[215,1596,1597,1600,1601,1604],{},[155,1598,1599],{},"self.layout"," は、",[155,1602,1603],{},"UILayout"," オブジェクトで、ボタン、ラベル、プロパティなどを配置するために使います。",[215,1606,1607,1610,1611,1614,1615,1617],{},[155,1608,1609],{},"layout.operator(\"simple_addon.say_hello\")"," は、クリックするとbl_idname ",[155,1612,1613],{},"\"simple_addon.say_hello\""," のオペレーターを呼び出すボタンを作成します。ボタンのテキストは、オペレーターの",[155,1616,1503],{},"から取得されます。",[1098,1619,1621],{"id":1620},"_4-register-unregister-functions",[120,1622,1623],{},"4) 登録／登録解除（register / unregister）関数",[48,1625,1626],{},"Blenderは、UI、オペレーター、パネル、プロパティなどを定義するクラスを登録して、Blenderがそれらについて認識できるようにする必要があります：",[152,1628,1629,1633],{},[155,1630,1632],{"className":1631},[175],"def register():\n    bpy.utils.register_class(SIMPLEADDON_OT_hello)\n    bpy.utils.register_class(SIMPLEADDON_PT_panel)",[48,1634,1635],{},[155,1636,1638],{"className":1637},[175],"def unregister():\n    bpy.utils.unregister_class(SIMPLEADDON_PT_panel)\n    bpy.utils.unregister_class(SIMPLEADDON_OT_hello)",[212,1640,1641,1651,1654],{},[215,1642,1643,1646,1647,1650],{},[155,1644,1645],{},"bpy.utils.register_class(Class)"," はクラスを登録します。",[155,1648,1649],{},"unregister_class"," は削除します。",[215,1652,1653],{},"特にクラス同士が参照し合う場合は、登録解除は登録の逆順で行うことが重要です。そのため、パネルをオペレーターより先に登録解除します。",[215,1655,1656,1657,1660,1661,1664],{},"アドオンがPreferencesで有効化されると、Blenderが",[155,1658,1659],{},"register()","を呼び出します。無効化されると、",[155,1662,1663],{},"unregister()","を呼び出します。",[48,1666,1667,1668,1671],{},"完全なコードは Pythonファイル ",[155,1669,1670],{},"addon.py"," に配置します：",[152,1673,1674,1693],{},[155,1675,1677,1678,1681,1684,1687,1689,1691],{"className":1676},[175],"bl_info = {\n    \"name\": \"Simple Addon Example\",\n    \"author\": \"Your Name\",\n    \"version\": (1, 0),\n    \"blender\": (4, 0, 0),\n    \"location\": \"View3D > Sidebar > Simple Tab\",\n    \"description\": \"A simple example addon that prints a message\",\n    \"category\": \"3D View\",\n}",[48,1679,1680],{},"import bpy",[48,1682,1683],{},"class SIMPLEADDON_OT_hello(bpy.types.Operator):\n    bl_idname = \"simple_addon.say_hello\"\n    bl_label = \"Say Hello\"\n    bl_description = \"Prints a message to the console\"",[48,1685,1686],{},"    def execute(self, context):\n        self.report({'INFO'}, \"Hello from Blender Addon!\")\n        print(\"Hello from Blender Addon!\")\n        return {'FINISHED'}",[48,1688,1550],{},[48,1690,1556],{},[48,1692,1632],{},[48,1694,1695],{},[155,1696,1638],{"className":1697},[175],[61,1699],{},[64,1701,1703],{"id":1702},"_4-running-and-packaging-your-add-on",[120,1704,1705],{},"4. アドオンの実行とパッケージ化",[48,1707,1708],{},"アドオンのスクリプトを書いたら、それをBlenderに読み込んで、すぐにテストできます。特別なツールは不要です。",[1710,1711,1712,1719,1722,1729],"ol",{},[215,1713,1714,1715,1718],{},"スクリプトを保存する - ",[155,1716,1717],{},"my_addon.py"," のように分かりやすい名前でPythonファイルを保存します。",[215,1720,1721],{},"BlenderのAdd-ons Preferencesを開く - Edit → Preferences → Add-onsへ移動します。ここでBlenderは、インストールされた拡張機能をすべて管理します。",[215,1723,1724,1725,1728],{},"アドオンをインストールする - Preferencesウィンドウ上部の「Install…」ボタンをクリックします。",[155,1726,1727],{},"Select your my_addon.py"," ファイルを選択して、「Install Add-on」をクリックします。",[215,1730,1731],{},"有効化する - インストール後、アドオンはリストに表示されます。「My Add-on」を探し、まだ有効になっていない場合はチェックを入れて有効化します。",[72,1733,1735],{"className":1734},[34,75],[77,1736],{"src":1737,"className":1738,"alt":12,"loading":82,"width":1739,"height":1740,"srcSet":1741,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-27ff3592-fed1-4347-8930-9dd62b2d950b.png",[81],1227,800,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-27ff3592-fed1-4347-8930-9dd62b2d950b.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-27ff3592-fed1-4347-8930-9dd62b2d950b.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-27ff3592-fed1-4347-8930-9dd62b2d950b.png 1227w",[1710,1743,1745],{"start":1744},5,[215,1746,1747],{},"インターフェースで確認する - 3Dビューポートを開き、サイドバーを開いて「Simple」という名前のタブを探します。カスタムパネルがそこにあり、すぐに使えます！",[72,1749,1751],{"className":1750},[34,75],[77,1752],{"src":1753,"className":1754,"alt":12,"loading":82,"width":1739,"height":1755,"srcSet":1756,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-2a90e13f-b338-4235-a830-f9c8d8060562.png",[81],741,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-2a90e13f-b338-4235-a830-f9c8d8060562.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-2a90e13f-b338-4235-a830-f9c8d8060562.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-2a90e13f-b338-4235-a830-f9c8d8060562.png 1227w",[48,1758,1759],{},"アドオンを他の人と共有したいときは、配布用にGitHub、Blender Artists、Gumroadへアップロードできます。アドオンが何をするのか、どうやってインストールするのかを説明する短いREADME.mdを用意しましょう。",[48,1761,1762,1763,1766,1767,1770,1771,1777],{},"複数ファイルのアドオン（例：別々のモジュール、アイコン、リソースなど）がある場合は、フォルダーを作成して、そのフォルダー全体をZIPにして（",[155,1764,1765],{},"my_addon.zip","）共有します。Blenderは同じ「Install…」ボタンから直接",[155,1768,1769],{},".zip","アーカイブをインストールできるため、事前に展開する必要はありません。メインのエントリポイントは",[155,1772,1773,1776],{},[120,1774,1775],{},"init",".py","という名前である必要があります。BlenderがそれをPythonパッケージとして扱うためです。",[61,1779],{},[64,1781,1782],{"id":507},[120,1783,508],{},[48,1785,1786],{},"BlenderアドオンのためのUIを作るのは、最初は気後れするかもしれません。しかし、自分で作ったツールを共有するための最も簡単な方法の1つです。パネルとレイアウトの仕組みを理解すれば、ユーザーが直感的に使えるボタン、プロパティ、整理されたセクションを素早く追加できます。",[48,1788,1789,600],{},[94,1790,1791],{"href":1045},"GitHub上のコードリポジトリを見て、ぜひこの例を試してみてください",[48,1793,1794],{},"まずは小さく、シンプルなパネル、ラベル、ボタンを追加してアクションを作り、そこから広げていきましょう！",[31,1796,1798,1801],{"className":1797},[34,35,36],[31,1799,524],{"className":1800},[40],[31,1802,1804,1805,1808],{"className":1803},[45],"アニメーションの制作プロセスについてもっと知るには ",[94,1806,961],{"href":531,"rel":1807},[533],"！私たちはベストプラクティスを共有する千人以上の専門家とつながっており、時々現地イベントも企画しています。ぜひ歓迎します！ 😊",[31,1810,1812],{"className":1811},[34,539,540],[94,1813,546],{"href":531,"className":1814},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":1816},[1817,1823,1824,1831,1832],{"id":1051,"depth":548,"text":1054,"children":1818},[1819,1821,1822],{"id":1100,"depth":1820,"text":1103},3,{"id":1126,"depth":1820,"text":1129},{"id":1195,"depth":1820,"text":1198},{"id":1250,"depth":548,"text":1253},{"id":1376,"depth":548,"text":1379,"children":1825},[1826,1828,1829,1830],{"id":1385,"depth":1820,"text":1827},"1) bl_info - アドオンメタデータ",{"id":1464,"depth":1820,"text":1467},{"id":1538,"depth":1820,"text":1541},{"id":1620,"depth":1820,"text":1623},{"id":1702,"depth":548,"text":1705},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1760548425425-e42e77fa38f1?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fGNvZGluZyUyMGludGVyZmFjZSUyMHRvb2xzfGVufDB8fHx8MTc2Mzg5MzE4MXww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":1835,"featured_at":561,"visibility":562},"2026-02-20T06:03:59.000+01:00","/blog-i18n/ja/blender-addon-ui-scripting-guide","2025-11-24T10:00:34.000+01:00",{"title":994,"description":12},"blender-addon-ui-scripting-guide","blog-i18n/ja/blender-addon-ui-scripting-guide/index",[1842,1843],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1844,"name":1845,"slug":1846,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1847},"69c20ddbcb09d8000107cfe5","Blender","blender","https://blog.cg-wire.com/tag/blender/","jAsYseHWs1DZX2U_wuc_p9fraLT43R7kQvoByh2mUOE",{"id":1850,"title":1851,"authors":1852,"body":1854,"description":12,"extension":557,"feature_image":2576,"html":7,"meta":2577,"navigation":13,"path":2579,"published_at":2580,"seo":2581,"slug":2582,"stem":2583,"tags":2584,"__hash__":2587,"updated_at":2578,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/blender-kitsu-breakdown-automation/index.md","PythonとKitsuでBlenderショットを自動生成する方法（2026）",[1853],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":1855,"toc":2567},[1856,1867,1874,1881,1884,1887,1894,1920,1922,1928,1944,1947,1950,1991,2001,2007,2010,2019,2025,2052,2057,2060,2062,2068,2079,2082,2124,2129,2136,2139,2141,2147,2150,2157,2164,2170,2178,2181,2183,2189,2200,2211,2223,2242,2245,2247,2253,2264,2279,2292,2302,2304,2310,2313,2323,2492,2497,2506,2516,2524,2526,2531,2534,2543,2546,2561],[31,1857,1859,1863],{"className":1858},[34,35,36],[31,1860,1862],{"className":1861},[40],"🧩",[31,1864,1866],{"className":1865},[45],"ショットのセットアップを自動化し、手作業のアセット配置にかかる何時間もの作業をなくしましょう。",[48,1868,1869,1870,1873],{},"アニメーションスタジオでは、各ショットにどのアセットを登場させる必要があるかを追跡するために ",[120,1871,1872],{},"ブレイクダウンリスト"," が使われます。",[48,1875,1876,1877,1880],{},"想像してみてください。最新の制作で、VFXアーティストとしてBlenderの何もないビューポートを前にしているあなた。マネージャーが、アセット、ショット、タイミングの手がかりが詳細に書かれたリストを渡し、",[655,1878,1879],{},"\"これをBlenderのシーンにして。\"","と言ってきます。",[48,1882,1883],{},"最初に思いつくのは、アセットマネージャーにログインして全てのオブジェクトを手作業で配置することかもしれません。しかし、数百のアセットが含まれる複雑なシーンはどうでしょうか？",[48,1885,1886],{},"ここで役立つのが、シンプルな自動化です。PythonのBlenderスクリプトを使えば、Kitsuのブレイクダウンデータを読み取り、数分で初期シーンを自動生成できます。",[48,1888,1889,1890,1893],{},"この記事では、完全な例を順に説明します。",[120,1891,1892],{},"Gazu"," のPython APIでブレイクダウンを取得し、新しいBlenderシーンを作成し、アセットをダウンロードして、Blenderにインポートします。最後には、レイアウトまたはアニメーションにすぐ使える状態で、シーンを自動構築する最小限のパイプラインが手に入ります。",[31,1895,1897,1900],{"className":1896},[34,35,108],[31,1898,112],{"className":1899},[40],[31,1901,1903,1907,1909,1911,1912,1914,134,1916],{"className":1902},[45],[117,1904,1905],{},[120,1906,623],{"style":122},[125,1908],{},[125,1910],{},"このガイドで紹介している例の統合に関する完全なソースコードは、GitHubで確認できます:",[125,1913],{},[125,1915],{},[94,1917,1919],{"href":1918},"https://github.com/cgwire/blender-kitsu-automated-scene-composition?ref=blog.cg-wire.com","https://github.com/cgwire/blender-kitsu-automated-scene-composition",[61,1921],{},[64,1923,1925],{"id":1924},"_1-getting-the-breakdown",[120,1926,1927],{},"1. ブレイクダウンを取得する",[48,1929,1930,1931,1943],{},"すべての3Dショットは何もない状態のキャンバスから始まりますが、そのキャンバスを埋めるための指示はKitsuにすでに存在します。",[94,1932,1934,1935],{"href":1933},"https://blog.cg-wire.com/3d-animation-process/"," ",[1936,1937,1938,1939,1942],"u",{},"the ",[120,1940,1941],{},"breakdown"," が、ステージ上に必要なものを正確に指示します","。これにより、アニメーターが作業を始める前に確認できます。",[48,1945,1946],{},"典型的なブレイクダウンは、スクリプトがシーンを組み立てるために必要な重要な物語的な文脈を提供します。ステージ（シーケンス情報に保存されている開始・終了フレーム、尺、およびその他の注記）と、キャスト（キャラクターモデル、小道具、環境アセットの実際のブレイクダウン）です。",[48,1948,1949],{},"コードを書く前に、Kitsuのダッシュボードでブレイクダウンを定義する必要があります。ここでは、3Dアセットのライブラリを、必要とされる特定のショットに手動でリンクします。ここで新しいモデルを作るわけではありません。既存の「俳優」（アセット）を、特定のショットに割り当てるだけです:",[1710,1951,1952,1962,1971,1981],{},[215,1953,1954,1957,1958,1961],{},[120,1955,1956],{},"制作プロジェクトを開く"," - Kitsuでプロジェクトに移動し、",[120,1959,1960],{},"Shots"," タブを開きます。",[215,1963,1964,1490,1967,1970],{},[120,1965,1966],{},"キャスティングシートを探す",[120,1968,1969],{},"Breakdown"," タブを探します（通常は右側のパネル、またはバージョンに応じて専用タブにあります）。",[215,1972,1973,1976,1977,1980],{},[120,1974,1975],{},"ショットを選択する"," - 詳細なキャスティング表示を開くために、入力したい特定のショット（例: ",[155,1978,1979],{},"SH01","）をクリックします。",[215,1982,1983,1986,1987,1990],{},[120,1984,1985],{},"アセットを割り当てる"," - 右側のパネルで、",[120,1988,1989],{},"+（プラス）"," ボタン、または「Add Asset」をクリックします。ここで各アセットに必要な数量を指定することもできます。",[72,1992,1994],{"className":1993},[34,75],[77,1995],{"src":1996,"className":1997,"alt":12,"loading":82,"width":1998,"height":1999,"srcSet":2000,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-ef6fba58-9c73-4a38-b466-0b9d92e4efc0.png",[81],1466,804,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-ef6fba58-9c73-4a38-b466-0b9d92e4efc0.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-ef6fba58-9c73-4a38-b466-0b9d92e4efc0.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-ef6fba58-9c73-4a38-b466-0b9d92e4efc0.png 1466w",[48,2002,2003,2006],{},[120,2004,2005],{},"Assets"," ページが、使用したいモデル（Characters、Propsなど）ですでに埋まっていることを確認してください。",[48,2008,2009],{},"保存を押すと、リンクが確立されます。これで、PythonスクリプトがGazuに「このショットに何が入っている？」と尋ねると、Kitsuは先ほど割り当てたアセットのリストを返します。あなたのPythonスクリプトはブリッジの役割を担い、そのキャスティング情報を解析して自動的にBlenderのビューポートへ反映します。",[48,2011,2012,2013,2018],{},"ローカルの開発環境が必要なら、",[94,2014,1934,2015],{"href":786},[1936,2016,2017],{},"Custom DCC BridgeガイドでDockerからKitsuをインストールする方法"," を確認してください。",[48,2020,2021,2022,2024],{},"Kitsuはデータを保持していますが、それを取得する手段が必要です。そこで登場するのが、KitsuのREST API向けのPython SDK ",[120,2023,1892],{}," です:",[152,2026,2027,2046],{},[155,2028,176,2030,2039,2043],{"className":2029},[175],[48,2031,2032,2033,2036,2037,869],{},"gazu.set_host(\"\u003C",[94,2034,185],{"href":185,"rel":2035},[187],">\")\nuser = gazu.log_in(\"",[94,2038,192],{"href":191},[48,2040,261,2041],{},[263,2042,265],{},[48,2044,2045],{},"sequence = gazu.shot.get_sequence_by_name(project, \"SQ01\")\nshot = gazu.shot.get_shot_by_name(sequence, \"SH01\")",[48,2047,2048],{},[155,2049,2051],{"className":2050},[175],"assets = gazu.casting.get_shot_casting(shot)",[48,2053,2054,2056],{},[125,2055],{},"ローカルのKitsuインスタンスに接続し、次に最初の制作（名前で取得することもできます）と、キャスティングを取得したいショットを選びます。",[48,2058,2059],{},"このショットIDを使うことで、対応するアセットのキャスティング（ブレイクダウンリスト）を取得できます。",[61,2061],{},[64,2063,2065],{"id":2064},"_2-getting-assets-from-a-breakdown",[120,2066,2067],{},"2. ブレイクダウンからアセットを取得する",[48,2069,2070,2071,2074,2075,2078],{},"いま、",[655,2072,2073],{},"誰","がショットに入るかは分かりました。次は ",[655,2076,2077],{},"どのように見えるか"," を把握する必要があります。",[48,2080,2081],{},"Kitsuでは、アセットに応じて利用できるプレビュー用のファイルが複数存在し、リビジョンによって使い分けられます。スクリプトは、各アセットの最新リビジョンを取得できるように、このデータを辿る必要があります:",[152,2083,2084,2118],{},[155,2085,2087,2088,2090,2091,2094,2095,2098,2099,2104,2107],{"className":2086},[175],"local_paths = ",[263,2089],{},"\nfor asset in assets:\n    tasks = gazu.task.all_tasks_for_asset(asset",[263,2092,2093],{},"\"asset_id\"",")\n    last_task = max(tasks, key=lambda x: x",[263,2096,2097],{},"\"updated_at\"",")",[48,2100,2101,2102,2098],{},"    preview_files = gazu.files.get_all_preview_files_for_task(last_task)\n    last_preview_file = max(preview_files, key=lambda x: x",[263,2103,2097],{},[48,2105,2106],{},"    download_dir = \"./previews\"\n    os.makedirs(download_dir, exist_ok=True)",[48,2108,2109,2110,2113,2114,2117],{},"    save_path = os.path.join(\n        download_dir,\n        last_preview_file",[263,2111,2112],{},"\"original_name\""," + \".\" + last_preview_file",[263,2115,2116],{},"\"extension\"",",\n    )\n    gazu.files.download_preview_file(last_preview_file, save_path)",[48,2119,2120],{},[155,2121,2123],{"className":2122},[175],"    local_paths.append(save_path)",[48,2125,2126,2128],{},[125,2127],{},"各アセットについて、あらゆる種類（'Modeling'、'Animation'など）や状態（'done'、'todo'...）に該当するすべてのタスクのリストを取得します。このリストをフィルタして、最も更新が新しいタスクを取り出します。",[48,2130,2131,2132,2135],{},"このタスクIDを使うことで、最新の対応するプレビューファイルのリビジョンを取得し、ローカルフォルダ ",[155,2133,2134],{},"previews"," にダウンロードできます。これらのダウンロードパスは、インポート手順のためにメモリに保持します。",[48,2137,2138],{},"このループの最後には、データベースのエントリが、Blenderが取り込める実体のあるモデルファイルへと変換され、ハードドライブ上に用意できています。",[61,2140],{},[64,2142,2144],{"id":2143},"_3-creating-a-new-blender-scene",[120,2145,2146],{},"3. 新しいBlenderシーンを作成する",[48,2148,2149],{},"アセットファイルは安全にダウンロード済みなので、次の作業は、それらを新しいキャストメンバーとして受け取るためのBlender環境の準備です。",[48,2151,2152,2153,2156],{},"BlenderのネイティブPython APIである ",[155,2154,2155],{},"bpy"," モジュールは、アプリケーションのあらゆる要素を操作するためのコマンドコンソールとして働きます。",[48,2158,2159,2160,2163],{},"Kitsuのアセットをインポートする前に、新しいBlenderシーンに付属しているデフォルトのオブジェクトを削除する必要があります。このシンプルなチュートリアルでは、デフォルトの ",[120,2161,2162],{},"Cube"," を対象にします。これは、デフォルトのCameraとLight以外で存在することが多い唯一のオブジェクトだからです:",[152,2165,2166],{},[155,2167,2169],{"className":2168},[175],"bpy.data.objects.remove(bpy.data.objects.get(\"Cube\"), do_unlink=True)",[48,2171,2172,2174,2177],{},[125,2173],{},[155,2175,2176],{},"do_unlink=True"," フラグは、他のどのオブジェクトからも使われていないなら、オブジェクトのデータブロック（メッシュデータなど）をBlenderに完全に削除させ、後に残る不要なもの（クラッター）を作らないようにします。",[48,2179,2180],{},"これで、インポートしたアセットがそれぞれの場所に配置される準備が整いました。",[61,2182],{},[64,2184,2186],{"id":2185},"_4-importing-asset-files",[120,2187,2188],{},"4. アセットファイルをインポートする",[48,2190,2191,2192,2195,2196,2199],{},"いよいよ成果です！Kitsuからダウンロードしたファイルは、ジオメトリと基本マテリアルを扱える標準化されたインターチェンジ形式 ",[155,2193,2194],{},".glb"," です。そのため、Blenderの専用 ",[155,2197,2198],{},"gltf"," インポートオペレーターを使用します。",[48,2201,2202,2203,2206,2207,2210],{},"重要なポイントは、ダウンロードしたアセットへの正しい ",[120,2204,2205],{},"絶対ファイルパス","（",[155,2208,2209],{},"glb_path","）を渡すことです。幸いなことに、それらは先ほどのコードスニペットで保存されています:",[152,2212,2213,2217],{},[155,2214,2216],{"className":2215},[175],"for path in local_paths:\n    if path.lower().endswith((\".glb\")):\n        print(f\"Importing: {path}\")\n        bpy.ops.import_scene.gltf(filepath=path)",[48,2218,2219],{},[155,2220,2222],{"className":2221},[175],"print(\"All preview GLB files imported successfully!\")",[48,2224,2225,2227,2230,2231,658,2234,2237,2238,2241],{},[125,2226],{},[155,2228,2229],{},"bpy.ops.import_scene.gltf()"," が実行されると、Blenderはファイルを読み取り、現在のシーンに対応する ",[120,2232,2233],{},"オブジェクト",[120,2235,2236],{},"メッシュ","、および ",[120,2239,2240],{},"マテリアル"," を自動で作成します。",[48,2243,2244],{},"インポートされたアセットは、ワールド原点（0, 0, 0）に配置された、完成済みのBlenderオブジェクトになります。以降のパイプライン手順の準備ができました。",[61,2246],{},[64,2248,2250],{"id":2249},"_5-saving-the-scene",[120,2251,2252],{},"5. シーンを保存する",[48,2254,2255,2256,2259,2260,2263],{},"このパイプラインの最後のステップは、組み立てたレイアウトを恒久的で、バージョン管理可能なファイルとして保存することです。この手順をせずにBlenderを閉じると、すべての自動作業が失われます。そこで、",[155,2257,2258],{},"bpy.ops.wm.save_as_mainfile"," オペレーターを使います。これは、Blenderのインターフェースで ",[120,2261,2262],{},"File &gt; Save As"," をクリックするのと同等の、プログラム上の操作です:",[152,2265,2266,2273],{},[155,2267,2269,2270],{"className":2268},[175],"scene_save_dir = \"./\"\nos.makedirs(scene_save_dir, exist_ok=True)",[48,2271,2272],{},"blend_filename = \"SH01.blend\"\nblend_path = os.path.join(scene_save_dir, blend_filename)",[48,2274,2275],{},[155,2276,2278],{"className":2277},[175],"bpy.ops.wm.save_as_mainfile(filepath=blend_path)",[48,2280,2281,2283,2284,2287,2288,2291],{},[125,2282],{},"結果として、",[155,2285,2286],{},"SH01.blend"," という新しいBlenderファイルが作成されます。これはKitsuの ",[120,2289,2290],{},"ブレイクダウン要件"," を正確に反映しており、次の部署が受け取る準備が整っています。",[72,2293,2295],{"className":2294},[34,75],[77,2296],{"src":2297,"className":2298,"alt":12,"loading":82,"width":2299,"height":2300,"srcSet":2301,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-91e5cf8e-acb1-4ac0-b5ec-d2c37a6a1ed6.png",[81],1460,828,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-91e5cf8e-acb1-4ac0-b5ec-d2c37a6a1ed6.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-91e5cf8e-acb1-4ac0-b5ec-d2c37a6a1ed6.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-91e5cf8e-acb1-4ac0-b5ec-d2c37a6a1ed6.png 1460w",[61,2303],{},[64,2305,2307],{"id":2306},"_6-user-friendly-addon",[120,2308,2309],{},"6. ユーザーフレンドリーなアドオン",[48,2311,2312],{},"スクリプトは期待どおりに動きますが、アーティストはどうでしょう？スクリプトの実行方法を知っている人ばかりではありません。",[48,2314,2315,2316,2322],{},"コードを少しだけ変更して、",[94,2317,1934,2319],{"href":2318},"https://blog.cg-wire.com/blender-addon-ui-scripting-guide/",[1936,2320,2321],{},"Blenderのアドオンに変える"," ことにしましょう:",[152,2324,2325,2482],{},[155,2326,2328,2329,2332,2335,2338,2355,2372,2387,2390,2393,2396,2399,2402,2405,2408,2413,2419,2425,2430,2439,2442,2445,2448,2451,2458,2461,2464,2467,2470,2473,2476,2479],{"className":2327},[175],"bl_info = {\n    \"name\": \"Kitsu Shot Auto-Importer\",\n    \"description\": \"Pick a project and shot and auto-import the latest preview assets\",\n    \"author\": \"cgwire\",\n    \"version\": (1, 0, 0),\n    \"blender\": (3, 0, 0),\n    \"location\": \"Viewport > N-Panel > Kitsu\",\n    \"category\": \"Import-Export\",\n}",[48,2330,2331],{},"import os\nimport sys",[48,2333,2334],{},"sys.path.append(\"~/.local/lib/python3.11/site-packages\")",[48,2336,2337],{},"import bpy\nimport gazu\nfrom bpy.props import EnumProperty, StringProperty",[48,2339,2340,2341,2352,2353],{},"def get_projects():\n    try:\n        projects = gazu.project.all_projects()\n        return ",[263,2342,2343,2344,2347,2348,2351],{},"(p",[263,2345,2346],{},"\"id\"",", p",[263,2349,2350],{},"\"name\"",", \"\") for p in projects","\n    except:\n        return ",[263,2354],{},[48,2356,2357,2358,2360,2361,2352,2370],{},"def get_sequences(project_id):\n    if not project_id:\n        return ",[263,2359],{},"\n    try:\n        seqs = gazu.shot.all_sequences_for_project(project_id)\n        return ",[263,2362,2363,2364,2366,2367,2369],{},"(s",[263,2365,2346],{},", s",[263,2368,2350],{},", \"\") for s in seqs",[263,2371],{},[48,2373,2374,2375,2377,2378,2352,2385],{},"def get_shots(sequence_id):\n    if not sequence_id:\n        return ",[263,2376],{},"\n    try:\n        shots = gazu.shot.all_shots_for_sequence(sequence_id)\n        return ",[263,2379,2363,2380,2366,2382,2384],{},[263,2381,2346],{},[263,2383,2350],{},", \"\") for s in shots",[263,2386],{},[48,2388,2389],{},"class KITSU_Props(bpy.types.PropertyGroup):\n    project: EnumProperty(name=\"Project\", items=lambda self, context: get_projects())",[48,2391,2392],{},"    sequence: EnumProperty(\n        name=\"Sequence\", items=lambda self, context: get_sequences(self.project)\n    )",[48,2394,2395],{},"    shot: EnumProperty(\n        name=\"Shot\", items=lambda self, context: get_shots(self.sequence)\n    )",[48,2397,2398],{},"class KITSU_OT_import_shot(bpy.types.Operator):\n    bl_idname = \"kitsu.import_shot_assets\"\n    bl_label = \"Import Shot Assets\"\n    bl_description = (\n        \"Download and import latest preview GLB/GLTF files for selected shot\"\n    )",[48,2400,2401],{},"    def execute(self, context):\n        props = context.scene.kitsu_props",[48,2403,2404],{},"        # Fetch shot data\n        shot = gazu.shot.get_shot(props.shot)\n        assets = gazu.casting.get_shot_casting(shot)",[48,2406,2407],{},"        download_dir = os.path.join(bpy.app.tempdir, \"kitsu_previews\")\n        os.makedirs(download_dir, exist_ok=True)",[48,2409,2410,2411],{},"        local_paths = ",[263,2412],{},[48,2414,2415,2416,2418],{},"        for asset in assets:\n            tasks = gazu.task.all_tasks_for_asset(asset",[263,2417,2093],{},")\n            if not tasks:\n                continue",[48,2420,2421,2422,2424],{},"            last_task = max(tasks, key=lambda x: x",[263,2423,2097],{},")\n            preview_files = gazu.files.get_all_preview_files_for_task(last_task)\n            if not preview_files:\n                continue",[48,2426,2427,2428,2098],{},"            last_preview = max(preview_files, key=lambda x: x",[263,2429,2097],{},[48,2431,2432,2433,2435,2436,2438],{},"            save_path = os.path.join(\n                download_dir,\n                last_preview",[263,2434,2112],{}," + \".\" + last_preview",[263,2437,2116],{},",\n            )",[48,2440,2441],{},"            gazu.files.download_preview_file(last_preview, save_path)\n            local_paths.append(save_path)",[48,2443,2444],{},"        # Clean default cube\n        obj = bpy.data.objects.get(\"Cube\")\n        if obj:\n            bpy.data.objects.remove(obj, do_unlink=True)",[48,2446,2447],{},"        # Import GLB/GLTF assets\n        for path in local_paths:\n            if path.lower().endswith((\".glb\", \".gltf\")):\n                bpy.ops.import_scene.gltf(filepath=path)",[48,2449,2450],{},"        # Auto-save blend file\n        save_dir = os.path.join(os.path.expanduser(\"~\"), \"kitsu_scenes\")\n        os.makedirs(save_dir, exist_ok=True)",[48,2452,2453,2454,2457],{},"        blend_path = os.path.join(save_dir, f\"{shot",[263,2455,2456],{},"'name'","}.blend\")\n        bpy.ops.wm.save_as_mainfile(filepath=blend_path)",[48,2459,2460],{},"        self.report({\"INFO\"}, f\"Imported assets and saved: {blend_path}\")\n        return {\"FINISHED\"}",[48,2462,2463],{},"class KITSU_PT_panel(bpy.types.Panel):\n    bl_label = \"Kitsu Auto-Importer\"\n    bl_idname = \"KITSU_PT_auto_importer\"\n    bl_space_type = \"VIEW_3D\"\n    bl_region_type = \"UI\"\n    bl_category = \"Kitsu\"",[48,2465,2466],{},"    def draw(self, context):\n        props = context.scene.kitsu_props\n        layout = self.layout",[48,2468,2469],{},"        layout.separator()\n        layout.prop(props, \"project\")\n        layout.prop(props, \"sequence\")\n        layout.prop(props, \"shot\")",[48,2471,2472],{},"        layout.separator()\n        layout.operator(\"kitsu.import_shot_assets\", icon=\"IMPORT\")",[48,2474,2475],{},"classes = (\n    KITSU_Props,\n    KITSU_OT_import_shot,\n    KITSU_PT_panel,\n)",[48,2477,2478],{},"def register():\n    for c in classes:\n        bpy.utils.register_class(c)\n    bpy.types.Scene.kitsu_props = bpy.props.PointerProperty(type=KITSU_Props)",[48,2480,2481],{},"def unregister():\n    for c in classes:\n        bpy.utils.unregister_class(c)\n    del bpy.types.Scene.kitsu_props",[48,2483,2484],{},[155,2485,855,2487,859,2489,2491],{"className":2486},[175],[120,2488,858],{},[120,2490,862],{},"\":\n    register()",[48,2493,2494,2496],{},[125,2495],{},"これで、制作プロジェクト、シーケンス、ショットを手動で選択して、ブレイクダウンデータを取得し、対応するキャスティングを現在のBlenderビューポートにインポートできます。",[72,2498,2500],{"className":2499},[34,75],[77,2501],{"src":2502,"className":2503,"alt":12,"loading":82,"width":2504,"height":2505},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-bf3ea18d-fd62-4db5-9977-6374b3ee1aef.png",[81],480,270,[48,2507,2508,2509,2511,2512,2515],{},"ロジックはシンプルです。",[155,2510,165],{}," の同じコードを使ってドロップダウンメニューを埋め込み、それらをビューポート内のパネルにまとめます。",[155,2513,2514],{},"import"," ボタンを押すと、対応するブレイクダウンアセットがすべてダウンロードされ、現在のワークスペースにインポートされます。",[48,2517,2518,2520,2521,2523],{},[155,2519,2334],{}," を追加することで、BlenderがあなたのシステムのPythonインストールを使って ",[155,2522,165],{}," のような外部ライブラリを読み込めるようになります。Blenderには独自に隔離されたPython環境が同梱されているため、パッケージのインストール管理は不便になりがちです。パスを拡張することで、Blenderにローカルのモジュールも確認させるだけで済みます。自分の環境に合わせて、このパスを調整してください。",[61,2525],{},[64,2527,2528],{"id":507},[120,2529,2530],{},"まとめ",[48,2532,2533],{},"Kitsuからブレイクダウンリストを直接取得し、Blenderをスクリプトで制御してシーンを組み立てることで、繰り返し発生する手作業をなくし、すべてのショット間でアセットの整合性を保てます。これは単に時間を節約するだけでなく、人為的なミスを減らし、プロデューサーが必要とする正しいアセットのバージョンとシーン構成から、すべてのアーティストが作業を開始できるようにします。こうすれば、10ショットでも10,000ショットでも、同じ信頼性で対応できます。",[48,2535,2536,2537,2542],{},"とはいえ、私たちの言葉だけを信じる必要はありません。",[94,2538,1934,2539],{"href":1918},[1936,2540,2541],{},"Githubリポジトリをクローンして実際に試してみてください","！",[48,2544,2545],{},"このワークフローは、アニメーション中に作成される新しいリビジョンから自動プレビューやレポートを生成したり、アセット情報を更新したりすることで拡張できます。",[31,2547,2549,2552],{"className":2548},[34,35,36],[31,2550,524],{"className":2551},[40],[31,2553,2555,2556,2560],{"className":2554},[45],"アニメーション制作プロセスについてもっと知りたいなら",[94,2557,2559],{"href":531,"rel":2558},[533],"Discordコミュニティへの参加を検討してください","！ベストプラクティスを共有する1,000人以上の専門家とつながり、時にはオフラインイベントも開催しています。ぜひ歓迎します！ 😊",[31,2562,2564],{"className":2563},[34,539,540],[94,2565,546],{"href":531,"className":2566},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":2568},[2569,2570,2571,2572,2573,2574,2575],{"id":1924,"depth":548,"text":1927},{"id":2064,"depth":548,"text":2067},{"id":2143,"depth":548,"text":2146},{"id":2185,"depth":548,"text":2188},{"id":2249,"depth":548,"text":2252},{"id":2306,"depth":548,"text":2309},{"id":507,"depth":548,"text":2530},"https://images.unsplash.com/photo-1725888358557-9f70661012c4?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fGFuaW1hdGlvbiUyMHBpcGVsaW5lfGVufDB8fHx8MTc2NTA5ODQ2Mnww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":2578,"featured_at":561,"visibility":562},"2026-02-20T06:04:00.000+01:00","/blog-i18n/ja/blender-kitsu-breakdown-automation","2025-12-07T18:11:31.000+01:00",{"title":1851,"description":12},"blender-kitsu-breakdown-automation","blog-i18n/ja/blender-kitsu-breakdown-automation/index",[2585,2586],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1844,"name":1845,"slug":1846,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1847},"NGVgpuWqmUywvK6_dWbVv6GNEseHyTtiWN2FSvxYwvo",{"id":2589,"title":2590,"authors":2591,"body":2593,"description":12,"extension":557,"feature_image":3189,"html":7,"meta":3190,"navigation":13,"path":3192,"published_at":3193,"seo":3194,"slug":3195,"stem":3196,"tags":3197,"__hash__":3200,"updated_at":3191,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/blender-kitsu-low-res-preview/index.md","Kitsu（2026）を使ったBlenderでの低解像度アニメーションプレビューの自動化",[2592],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":2594,"toc":3179},[2595,2606,2609,2612,2615,2618,2635,2638,2665,2667,2673,2676,2679,2695,2704,2706,2712,2719,2733,2736,2739,2741,2747,2754,2764,2785,2792,2795,2798,2801,2807,2817,2820,2822,2828,2842,2845,2863,2900,2903,2911,2918,2920,2926,2935,2938,3002,3021,3031,3034,3037,3047,3050,3060,3062,3068,3071,3078,3084,3087,3093,3102,3104,3110,3113,3116,3125,3127,3131,3134,3154,3157,3160,3173],[31,2596,2598,2602],{"className":2597},[34,35,36],[31,2599,2601],{"className":2600},[40],"⚡",[31,2603,2605],{"className":2604},[45],"数時間ではなく数秒でレンダーできる軽量なプレビューで、アニメーションレビューを高速化します。",[48,2607,2608],{},"フル解像度のレンダーを待ってからショットを確認するのは、制作全体の進行を遅らせます。アーティストは待ち時間に時間を取られ、スーパーバイザーもフィードバックを受け取るのが遅れてしまいます。反復ループの効率が悪いのです。",[48,2610,2611],{},"そこで、Blender上で低解像度のアニメーションプレビューを直接作成し、アニメーションパイプラインの一部としてPythonでKitsuへ自動アップロードしましょう。これらのプレビューはレンダーが速く、レビューしやすく、承認のためにKitsuで素早く利用できます。",[48,2613,2614],{},"これは大きな効果があります。フル解像度のレンダーは数時間かかることがあり、何千ものショットを扱うとクラウドストレージやネットワーク帯域のコストも決して軽くありません。1080pから480pにするだけで、サイズを最大5倍まで（＝最大5分の1）にできます！",[48,2616,2617],{},"本チュートリアルでは、次の内容を扱います：",[212,2619,2620,2623,2626,2632],{},[215,2621,2622],{},"低解像度プレビュー用にBlenderのレンダー設定を調整する",[215,2624,2625],{},"Pythonでレンダープロセスを自動化する",[215,2627,2628,2631],{},[155,2629,2630],{},"ffmpeg","を使って動画に透かしとタイムスタンプを追加し、素早く状況を把握できるようにする",[215,2633,2634],{},"動画を出力し、Kitsuへアップロードする",[48,2636,2637],{},"最後には、レビューにかかる時間を短縮しつつ、フィードバックの質を犠牲にしないスクリプトが手に入ります。",[31,2639,2641,2644],{"className":2640},[34,35,108],[31,2642,112],{"className":2643},[40],[31,2645,2647,2652,2654,2656,2657,2659,134,2661],{"className":2646},[45],[117,2648,2649],{},[120,2650,2651],{"style":122},"動く実例を探していますか？",[125,2653],{},[125,2655],{},"このガイドで紹介している例の統合（インテグレーション）の完全なソースコードは、私たちのGitHubで確認できます：",[125,2658],{},[125,2660],{},[94,2662,2664],{"href":2663},"https://github.com/cgwire/blender-kitsu-low-res-preview?ref=blog.cg-wire.com","https://github.com/cgwire/blender-kitsu-low-res-preview",[61,2666],{},[64,2668,2670],{"id":2669},"_1-simple-blender-scene-setup",[120,2671,2672],{},"1. シンプルなBlenderシーンのセットアップ",[48,2674,2675],{},"アニメーション付きプレビューを作る前に、シーン内に開始用のオブジェクトが必要です。このチュートリアルでは、Blenderのデフォルトのキューブを使います。",[48,2677,2678],{},"まず、シーンとキューブの参照を作成します：",[152,2680,2681,2685],{},[155,2682,2684],{"className":2683},[175],"import bpy\n",[48,2686,2687],{},[155,2688,2690,2691,2694],{"className":2689},[175],"cube = bpy.data.objects",[263,2692,2693],{},"\"Cube\"","\nscene = bpy.context.scene",[72,2696,2698],{"className":2697},[34,75],[77,2699],{"src":2700,"className":2701,"alt":12,"loading":82,"width":83,"height":2702,"srcSet":2703,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-bf950a7a-c387-4b8d-9318-49e5bd3251bd.png",[81],901,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-bf950a7a-c387-4b8d-9318-49e5bd3251bd.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-bf950a7a-c387-4b8d-9318-49e5bd3251bd.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-bf950a7a-c387-4b8d-9318-49e5bd3251bd.png 1600w",[61,2705],{},[64,2707,2709],{"id":2708},"_2-adding-keyframes-for-animation",[120,2710,2711],{},"2. アニメーション用のキーフレームを追加する",[48,2713,2714,2715,2718],{},"次のステップはキューブをアニメーション化することです。モデリングのプレビューを素早く行うには、短いシーケンスが理想です。ここでは",[120,2716,2717],{},"360°回転","を48フレーム（24 FPSで2秒）で作成します：",[152,2720,2721],{},[155,2722,2724,2725,2728,2729,2732],{"className":2723},[175],"for frame, angle in ",[263,2726,2727],{},"(1, 0), (12, 1.57), (24, 3.14), (36, 4.71), (48, 6.28)",":\n    scene.frame_set(frame)\n    cube.rotation_euler",[263,2730,2731],{},"2"," = angle\n    cube.keyframe_insert(data_path=\"rotation_euler\", index=2)",[48,2734,2735],{},"このループは一定間隔でキーフレームを設定し、Z軸の周りにpi/2ずつ滑らかに回転させます。フレーム数を少なくすることでレンダーが速くなり、プレビュー用途に最適になります。",[48,2737,2738],{},"この時点で、Blender上でタイムラインをスクラブして、キューブが期待どおりに回転するか確認できます。",[61,2740],{},[64,2742,2744],{"id":2743},"_3-low-resolution-rendering",[120,2745,2746],{},"3. 低解像度レンダリング",[48,2748,2749,2750,2753],{},"アニメーションが用意できたら、Blenderで",[120,2751,2752],{},"高速で低解像度のプレビュー","をレンダーするように設定します。目的は品質よりもスピードです。レビューに十分に見やすく、かつ作成が素早いものを目指します。",[48,2755,2756,2757,2763],{},"ここでは、",[94,2758,1934,2760],{"href":2759},"https://blog.cg-wire.com/getting-started-with-blender-rendering/",[1936,2761,2762],{},"スピードのためのEeveeレンダリングエンジンを使い、不要なレンダリングのオーバーヘッドを減らします","。Eeveeは単純なラスターライズ（画像の格子化）エンジンなので、Cyclesよりはるかに高速です。90%のケースでは、超リアルな出力は必要ありません。",[152,2765,2766,2779],{},[155,2767,2769,2770,2773,2776],{"className":2768},[175],"scene.render.engine = \"BLENDER_EEVEE\"",[48,2771,2772],{},"scene.render.resolution_x = 1920\nscene.render.resolution_y = 1080\nscene.render.resolution_percentage = 50",[48,2774,2775],{},"scene.render.fps = 24\nscene.frame_start = 1\nscene.frame_end = 48  # アニメーションの長さに合わせてください",[48,2777,2778],{},"scene.render.image_settings.file_format = \"FFMPEG\"\nscene.render.ffmpeg.format = \"MPEG4\"\nscene.render.ffmpeg.codec = \"H264\"",[48,2780,2781],{},[155,2782,2784],{"className":2783},[175],"scene.render.filepath = \"//preview.mp4\"",[48,2786,2787,2788,2791],{},"古典的な横長の解像度を使いつつも、",[155,2789,2790],{},"resolution_percentage","を下げたり、Eeveeで高品質サンプリングをオフにしたりすると、プレビューのレンダー時間を大幅に減らせます。",[48,2793,2794],{},"残りの設定はかなり標準的です。24 FPSで合計48フレーム、出力はH264エンコードのmp4動画（圧縮を速くするため）で、スクリプトの現在のフォルダに書き込まれます。",[48,2796,2797],{},"用途に応じて、解像度、フレームレート、ビットレートを下げれば、プレビューのサイズも小さくできます。ただし、レビュー工程に必要なだけの品質は確保する必要があるので、パフォーマンスとの最適なバランスになるよう設定を調整してください。",[48,2799,2800],{},"最後に、レンダーを1行でトリガーできます：",[152,2802,2803],{},[155,2804,2806],{"className":2805},[175],"bpy.ops.render.render(animation=True)",[72,2808,2810],{"className":2809},[34,75],[77,2811],{"src":2812,"className":2813,"alt":12,"loading":82,"width":2814,"height":2815,"srcSet":2816,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-27b0c802-b589-4306-b52b-5f910b58320b.png",[81],1088,722,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-27b0c802-b589-4306-b52b-5f910b58320b.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-27b0c802-b589-4306-b52b-5f910b58320b.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-27b0c802-b589-4306-b52b-5f910b58320b.png 1088w",[48,2818,2819],{},"このプレビュービデオは、すぐにレビューに使うことができるほか、Kitsuへアップロードする前にFFmpegのようなツールでタイムスタンプや透かし、または独自の命名規則を追加するなど、追加処理も可能です。",[61,2821],{},[64,2823,2825],{"id":2824},"_4-ffmpeg-processing-timestamp-naming-watermark",[120,2826,2827],{},"4. FFmpeg処理：タイムスタンプ、命名、透かし",[48,2829,2830,2831,2834,2835,2841],{},"Blenderがアニメーションを動画ファイルにレンダーしたら、次は",[120,2832,2833],{},"FFmpeg","でさらに処理できます。これは",[94,2836,1934,2838],{"href":2837},"https://blog.cg-wire.com/ffmpeg-commands-for-animators/",[1936,2839,2840],{},"制作パイプラインでよくある手順","で、タイムスタンプ、透かし、またはカスタムの命名などを追加して、レビューに使える状態に整えます。",[48,2843,2844],{},"プレビューをレンダーした後、ターミナルで次のコマンドを実行します：",[152,2846,2847],{},[155,2848,2850,2851,2854,2855,2858,2859,2862],{"className":2849},[158],"ffmpeg -framerate 24 \\\\\n  -i preview.mp4 \\\\\n  -i watermark.png \\\\\n  -filter_complex \"\\\\\n    ",[263,2852,2853],{},"0:v","drawtext=text='%{pts\\\\:hms}':x=10:y=10:fontsize=24:fontcolor=white:bordercolor=black:borderw=2",[263,2856,2857],{},"v1","; \\\\\n    [v1]",[263,2860,2861],{},"1:v","overlay=W-w-20:H-h-20\" \\\\\n  -c:v libx264 -crf 22 -pix_fmt yuv420p \\\\\n  preview_with_stamp.mp4",[212,2864,2865,2873,2885,2893],{},[215,2866,2867,2872],{},[120,2868,2869],{},[155,2870,2871],{},"drawtext"," は左上に現在進行中のタイムスタンプを重ねて表示します。",[215,2874,2875,2880,2881,2884],{},[155,2876,2877],{},[120,2878,2879],{},"overlay"," は右下に透かし画像（",[155,2882,2883],{},"watermark.png","）を配置します。",[215,2886,2887,2892],{},[120,2888,2889],{},[155,2890,2891],{},"c:v libx264 -crf 22 -pix_fmt yuv420p"," は動画再生の互換性と品質を確保します。",[215,2894,2895,2896,2899],{},"出力ファイル ",[155,2897,2898],{},"preview_with_stamp.mp4"," が、レビュー準備完了の最終プレビューです。",[48,2901,2902],{},"もちろん、チームやクライアントのレビュー用にプレビューを標準化するため、必要に応じてフォントサイズ、位置、透かしの配置などを調整できます。",[72,2904,2906],{"className":2905},[34,75],[77,2907],{"src":2908,"className":2909,"alt":12,"loading":82,"width":2814,"height":2815,"srcSet":2910,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-aaed9f6c-1b29-4592-b629-1830a6f2aa79.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-aaed9f6c-1b29-4592-b629-1830a6f2aa79.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-aaed9f6c-1b29-4592-b629-1830a6f2aa79.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-aaed9f6c-1b29-4592-b629-1830a6f2aa79.png 1088w",[48,2912,2913,2914,2917],{},"これで、制作に向けた低解像度アニメーションプレビューの準備が完了です。ファイルは、素早いフィードバックのために",[120,2915,2916],{},"Kitsu","へアップロードする準備ができています。",[61,2919],{},[64,2921,2923],{"id":2922},"_5-uploading-to-kitsu-via-gazu",[120,2924,2925],{},"5. Gazu経由でKitsuへアップロードする",[48,2927,2928,2929,2931,2932,2934],{},"低解像度プレビューが用意できたら、ダッシュボードから直接",[120,2930,2916],{},"へアップロードするか、",[155,2933,165],{},"のPython SDKを使えます。Kitsuは、アーティストやスーパーバイザーがプレビューにすぐアクセスしてレビューできる共同作業型のパイプライントラッカーです。",[48,2936,2937],{},"次のPythonスクリプトは、プロジェクトとタスクを選んでプレビューをアップロードできる、シンプルな対話型CLIを提供します：",[152,2939,2940,2996],{},[155,2941,2943,2944,2953,2967,2980,2987,2990,2993],{"className":2942},[175],"import gazu",[48,2945,2946,2947,2949,2950],{},"def pickProject(label, list_of_items):\n    \"\"\"Helper UI to pick one item from a list.\"\"\"\n    for i, item in enumerate(list_of_items):\n        print(f\"{i + 1}. {item",[263,2948,2456],{},"}\")\n    idx = int(input(f\"Choose {label} number: \")) - 1\n    return list_of_items",[263,2951,2952],{},"idx",[48,2954,2955,2956,2959,2960,2963,2964,2098],{},"def pickTask(label, list_of_items):\n    \"\"\"Helper UI to pick one item from a list.\"\"\"\n    for i, item in enumerate(list_of_items):\n        asset = gazu.entity.get_entity(item",[263,2957,2958],{},"\"entity_id\"",")\n        status = gazu.task.get_task_status(item",[263,2961,2962],{},"\"task_status_id\"",")\n        type = gazu.task.get_task_type(item",[263,2965,2966],{},"\"task_type_id\"",[48,2968,2969,2970,2972,2973,2975,2976,2949,2978],{},"        print(f\"{i + 1}. {asset",[263,2971,2456],{},"} {type",[263,2974,2456],{},"} {status",[263,2977,2456],{},[263,2979,2952],{},[48,2981,2032,2982,2036,2985,869],{},[94,2983,185],{"href":185,"rel":2984},[187],[94,2986,192],{"href":191},[48,2988,2989],{},"projects = gazu.project.all_projects()\nproject = pickProject(\"project\", projects)",[48,2991,2992],{},"tasks = gazu.task.all_tasks_for_project(project)\ntask = pickTask(\"task\", tasks)",[48,2994,2995],{},"print(\"Uploading preview...\")\ntask_status = gazu.task.get_task_status_by_name(\"todo\")\nresult = gazu.task.publish_preview(\n    task,\n    task_status,\n    comment=\"Auto-generated preview\",\n    preview_file_path=\"./preview.mp4\",\n)",[48,2997,2998],{},[155,2999,3001],{"className":3000},[175],"print(\"Done:\", result)",[48,3003,3004,3005,3007,3008,3013,3014,3017,3018,3020],{},"まず、",[155,3006,165],{},"であなたの資格情報を使ってKitsuにログインします。ここでは、",[94,3009,1934,3010],{"href":786},[1936,3011,3012],{},"Kitsu Dockerによるローカル開発環境のインストール","を使用します。このプログラムでは、利用可能な異なるKitsu APIエンドポイントを使って制作データをすべて取得し、そこから",[120,3015,3016],{},"プロジェクト","と",[120,3019,686],{},"を選択できます：",[72,3022,3024],{"className":3023},[34,75],[77,3025],{"src":3026,"className":3027,"alt":12,"loading":82,"width":3028,"height":3029,"srcSet":3030,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-21091709-64dd-41c6-875e-2cdce8b5b178.png",[81],1343,816,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-21091709-64dd-41c6-875e-2cdce8b5b178.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-21091709-64dd-41c6-875e-2cdce8b5b178.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-21091709-64dd-41c6-875e-2cdce8b5b178.png 1343w",[48,3032,3033],{},"そして、前のステップで生成したプレビュー動画を、選択したタスクへアップロードします。",[48,3035,3036],{},"完了すると、プレビューはKitsuのレビュー画面で利用可能になり、高解像度のレンダーを待たずに、チームメンバーやスーパーバイザーがフィードバックを出しやすくなります。",[72,3038,3040],{"className":3039},[34,75],[77,3041],{"src":3042,"className":3043,"alt":12,"loading":82,"width":3044,"height":3045,"srcSet":3046,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-78d2cd48-21e9-4599-9b2b-a5e5bef63f76.png",[81],985,948,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-78d2cd48-21e9-4599-9b2b-a5e5bef63f76.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-78d2cd48-21e9-4599-9b2b-a5e5bef63f76.png 985w",[48,3048,3049],{},"レビューエンジンは、フレームに素早く注釈を付け、正確なショットに対してコメントを追加するのに最適です：",[72,3051,3053],{"className":3052},[34,75],[77,3054],{"src":3055,"className":3056,"alt":12,"loading":82,"width":3057,"height":3058,"srcSet":3059,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-6ae9b3dd-18e9-4d85-9fa6-e5106babc87e.png",[81],1438,809,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-6ae9b3dd-18e9-4d85-9fa6-e5106babc87e.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-6ae9b3dd-18e9-4d85-9fa6-e5106babc87e.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-6ae9b3dd-18e9-4d85-9fa6-e5106babc87e.png 1438w",[61,3061],{},[64,3063,3065],{"id":3064},"_6-putting-it-all-together",[120,3066,3067],{},"6. すべてをまとめる",[48,3069,3070],{},"タスクを最初から最後まで自動化するには、簡単なbashコマンドを書きます：",[48,3072,3073],{},[120,3074,3075],{},[1936,3076,3077],{},"preview.sh",[152,3079,3080],{},[155,3081,3083],{"className":3082},[175],"python3 render.py && ./watermark.sh && python3 upload.py",[48,3085,3086],{},"その後、プレビューを共有する必要があるたびにスクリプトを実行できます：",[152,3088,3089],{},[155,3090,3092],{"className":3091},[175],"./preview.sh",[48,3094,3095,3096,3101],{},"最終結果を自分で試すには、私たちの",[94,3097,1934,3098],{"href":2663},[1936,3099,3100],{},"Githubリポジトリ blender-kitsu-low-res-preview","をご覧ください。",[61,3103],{},[64,3105,3107],{"id":3106},"_7-artist-friendly-addon-overview",[120,3108,3109],{},"7. アーティスト向けアドオンの概要",[48,3111,3112],{},"この記事の範囲外ですが、このコードをBlenderのアドオンにまとめて、アーティストが簡単に使えるようにすることも可能です。",[48,3114,3115],{},"アップロードするために、制作物（プロダクション）、アセット、タスクを選ぶドロップダウンメニューを格納するメインパネルが必要になります。そして、アップロード用のボタンをクリックするだけでよい形にします。アップロードのロジックでは、レンダリング、透かし処理のためのffmpegをサブプロセスとして呼び出し、さらに一時ファイルを実際にKitsuへ送信します。",[48,3117,3118,3119,3124],{},"詳しくは",[94,3120,1934,3121],{"href":2318},[1936,3122,3123],{},"Blender Add-on UI Development","に関する記事をご覧ください。",[61,3126],{},[64,3128,3129],{"id":507},[120,3130,508],{},[48,3132,3133],{},"ここまでで、完全なパイプラインを構築できました。Blenderでシンプルな3Dオブジェクトを作り、アニメーションさせ、低解像度のプレビューを生成し、タイムスタンプと透かしを追加し、そしてKitsuへアップロードします。得られるメリットはすぐに明確です：",[212,3135,3136,3142,3148],{},[215,3137,3138,3141],{},[120,3139,3140],{},"より速いレビュー"," - スーパーバイザーやチームメンバーは、フル解像度のレンダーを待たずに、プレビューをすぐに視聴できます。",[215,3143,3144,3147],{},[120,3145,3146],{},"より速い反復"," - アーティストはより早くフィードバックを受け取れます。これにより反復ループが短くなり、ボトルネックが減ります。",[215,3149,3150,3153],{},[120,3151,3152],{},"より少ない詰まり（ブロッカー）"," - 自動化されたプレビューとアップロードにより、パイプラインでの反復的な手作業がなくなり、成果物の一貫性が保たれます。",[48,3155,3156],{},"これまで1時間かかっていた手作業は、いくつかのスクリプトで処理できるようになり、チームは制作の「創造的な側面」に集中する時間を増やせます。",[48,3158,3159],{},"さらに、あなたのアニメーションスタジオのニーズに応じてこのワークフローを発展させることもできます。Blenderにボタンやパネルを追加してワンクリックでパイプライン全体を実行したり、単一のスクリプトで複数のショットやシーンのプレビューを自動で一括生成したり、といったことが可能です。",[31,3161,3163,3166],{"className":3162},[34,35,36],[31,3164,524],{"className":3165},[40],[31,3167,1804,3169,3172],{"className":3168},[45],[94,3170,961],{"href":531,"rel":3171},[533],"！ 私たちはベストプラクティスを共有する1000人以上の専門家とつながっており、時々対面イベントも企画しています。ぜひようこそお迎えしたいです！ 😊",[31,3174,3176],{"className":3175},[34,539,540],[94,3177,546],{"href":531,"className":3178},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":3180},[3181,3182,3183,3184,3185,3186,3187,3188],{"id":2669,"depth":548,"text":2672},{"id":2708,"depth":548,"text":2711},{"id":2743,"depth":548,"text":2746},{"id":2824,"depth":548,"text":2827},{"id":2922,"depth":548,"text":2925},{"id":3064,"depth":548,"text":3067},{"id":3106,"depth":548,"text":3109},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1653200256306-6dc84510dfb6?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDN8fGFuaW1hdGlvbiUyMHBpcGVsaW5lfGVufDB8fHx8MTc2NTA5ODQ2Mnww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":3191,"featured_at":561,"visibility":562},"2026-02-20T06:04:01.000+01:00","/blog-i18n/ja/blender-kitsu-low-res-preview","2025-12-15T10:00:23.000+01:00",{"title":2590,"description":12},"blender-kitsu-low-res-preview","blog-i18n/ja/blender-kitsu-low-res-preview/index",[3198,3199],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1844,"name":1845,"slug":1846,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1847},"XwK7MTrna4oNLckd4xU2SaNAY416u1FGLnjftZQa5yg",{"id":3202,"title":3203,"authors":3204,"body":3206,"description":12,"extension":557,"feature_image":3892,"html":7,"meta":3893,"navigation":13,"path":3894,"published_at":3895,"seo":3896,"slug":3897,"stem":3898,"tags":3899,"__hash__":3902,"updated_at":3191,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/blender-kitsu-versioning-addon/index.md","KitsuバージョニングアドオンでBlenderファイルのリビジョン管理を行う（2026）",[3205],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":3207,"toc":3883},[3208,3219,3226,3229,3234,3237,3240,3243,3246,3249,3251,3257,3260,3263,3289,3292,3318,3320,3326,3335,3359,3368,3371,3374,3404,3414,3417,3420,3423,3425,3431,3437,3457,3466,3473,3476,3479,3495,3498,3501,3516,3523,3537,3540,3582,3585,3591,3594,3596,3602,3605,3612,3630,3633,3636,3669,3671,3677,3684,3687,3690,3707,3710,3713,3738,3741,3743,3749,3757,3774,3804,3807,3828,3831,3841,3843,3847,3850,3853,3862,3877],[31,3209,3211,3215],{"className":3210},[34,35,36],[31,3212,3214],{"className":3213},[40],"🧱",[31,3216,3218],{"className":3217},[45],"混乱したファイル命名を、Blenderリビジョンの単一の真実の情報源で置き換えましょう。",[48,3220,3221,3222,3225],{},"すべてのプロジェクトは、良い意図から始まります。きれいな",[155,3223,3224],{},"model.blend","、整理されたフォルダ、そして「今回はちゃんと整頓しておこう」という約束からスタートします。",[48,3227,3228],{},"しかし締切が近づくにつれ、制作に静かに忍び寄るエントロピーが現実になります。やがてプロジェクトのディレクトリは、パニック気味の直前編集が積み重なった、考古学的な発掘現場のように見え始めます：",[152,3230,3231],{},[155,3232,3233],{},"model.blend\nmodel_v2.blend\nmodel_v2b.blend\nmodel_final.blend\nmodel_final_really_final.blend\nmodel_FINAL_v3.blend",[48,3235,3236],{},"お分かりの通りです。誰かが急な変更を必要とし、別のアーティストが「念のため」でバージョンを枝分かれさせます。そうして、いったいどのファイルが「本物」なのか、誰も確信を持てなくなっていきます。チャットのコメントはファイル名と矛盾し、古いバージョンからショットがレンダーされ、そしてスーパーバイザーは深くため息をつきます。",[48,3238,3239],{},"アニメーションスタジオでは、このような小さなカオスが積み重なります。そこで必要になるのが、きちんとした真実の情報源です。",[48,3241,3242],{},"多くのチームでは、その情報源がKitsuです。そしてBlenderアーティストにとって不足しているのは、ファイルのバージョンが管理され、追跡でき、プロジェクトの制作データと確実に揃う状態を保つ自動化されたブリッジです。",[48,3244,3245],{},"そこで方針を決めます。BlenderがKitsuと連携し、パイプラインがついに「味方してくれている」感覚になるようなバージョニングシステムを作るのです。",[48,3247,3248],{},"このチュートリアルでは、Blender上から直接ファイルのリビジョンを管理するアドオンを作成します。BlenderをKitsuプロジェクトに接続し、3Dモデルのリビジョンを作成・アップロードし、既存のすべてのリビジョンを閲覧し、さらに過去のリビジョンをBlenderへ呼び戻せるようになります。",[61,3250],{},[64,3252,3254],{"id":3253},"workflow-overview",[120,3255,3256],{},"ワークフローの概要",[48,3258,3259],{},"一般的なKitsu主導のワークフローでは、アーティストがBlenderでシーンを開き作業を行い、マイルストーンに到達したらリビジョンをアップロードします。アーティストはレビューし、改良し、修正し、そして再度アップロードします。Kitsuは各ステップをきれいに管理してくれます。",[48,3261,3262],{},"ただ、クリックひとつでリビジョンをアップロードしたり、引き戻したりできれば便利ですよね？",[1710,3264,3265,3271,3277,3283],{},[215,3266,3267,3270],{},[120,3268,3269],{},"Blenderから始める"," - 作業用シーンを開きます。モデリング、シェーディング、リギングなど、いま必要な作業に応じて対応します。",[215,3272,3273,3276],{},[120,3274,3275],{},"作業をチェックポイント化する"," - マイルストーン（「ブロッキング完了」「レビュー準備完了」など）に到達したら、Kitsu上で新しいリビジョンを作成します。",[215,3278,3279,3282],{},[120,3280,3281],{},"履歴を確認する"," - Kitsuはすべてのリビジョンを保存するため、スーパーバイザーには明確なタイムラインが提示され、ファイルを掘り起こさずにバージョン比較が可能になります。",[215,3284,3285,3288],{},[120,3286,3287],{},"新しい変更を取り込む"," - 別のバージョンが必要になったら、現在のワークスペースにアセットを取り込むだけです。",[48,3290,3291],{},"これは非常に基本的なワークフローなので、競合解決の扱い（同じショットに対して2人のアーティストが作業し、それぞれが新しいリビジョンを作成したら？ どう処理する？）といった問題に直面するのは避けられませんが、まずはアニメーションパイプラインのニーズに合わせて後で改善できる、機能するアドオンを作るには十分です。",[31,3293,3295,3298],{"className":3294},[34,35,108],[31,3296,112],{"className":3297},[40],[31,3299,3301,3305,3307,3309,3310,3312,134,3314],{"className":3300},[45],[117,3302,3303],{},[120,3304,123],{"style":122},[125,3306],{},[125,3308],{},"このガイドで紹介する例の統合について、完全なソースコードはGitHubで確認できます：",[125,3311],{},[125,3313],{},[94,3315,3317],{"href":3316},"https://github.com/cgwire/blender-kitsu-versioning-addon?ref=blog.cg-wire.com","https://github.com/cgwire/blender-kitsu-versioning-addon",[61,3319],{},[64,3321,3323],{"id":3322},"_1-populating-the-kitsu-dashboard",[120,3324,3325],{},"1. Kitsuダッシュボードを準備する",[48,3327,3328,3329,3334],{},"KitsuのWebインターフェースは、プロデューサー、コーディネーター、リードがプロジェクトの構造を素早く設定できるように設計されています。Blenderアーティストがリビジョンを公開する前に、制作中のアセットで制作データを埋めておく必要があります。",[94,3330,1934,3331],{"href":786},[1936,3332,3333],{},"ローカル開発用のKitsu Dockerインスタンス","では：",[1710,3336,3337,3343,3350,3356],{},[215,3338,3339,3342],{},[120,3340,3341],{},"Kitsuダッシュボード","にログインします。",[215,3344,3345,3346,3349],{},"メインのナビゲーションバーで",[120,3347,3348],{},"Productions","に移動します。",[215,3351,3352,3355],{},[120,3353,3354],{},"「Create production」","をクリックします（通常は右上）。",[215,3357,3358],{},"制作情報を入力します",[72,3360,3362],{"className":3361},[34,75],[77,3363],{"src":3364,"className":3365,"alt":12,"loading":82,"width":3044,"height":3366,"srcSet":3367,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-58cb0571-2b74-4110-9b07-9e15030bbd05.png",[81],694,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-58cb0571-2b74-4110-9b07-9e15030bbd05.png 600w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-58cb0571-2b74-4110-9b07-9e15030bbd05.png 985w",[48,3369,3370],{},"新しい制作はリストに表示されるので、開いてアセットの追加を開始できます。",[48,3372,3373],{},"アセットはプロジェクトの構成要素です。キャラクター、小道具、環境、車両... 制作管理が必要なものは何でも対象になります。",[1710,3375,3376,3382,3388,3394],{},[215,3377,3378,3381],{},[120,3379,3380],{},"Productions → あなたの制作名","へ移動します。",[215,3383,3384,3385,3387],{},"制作内の",[120,3386,2005],{},"タブに切り替えます。",[215,3389,3390,3393],{},[120,3391,3392],{},"「Create Asset」","をクリックします。",[215,3395,3396,3399,3400,3403],{},[120,3397,3398],{},"アセット名","（例：「RobotHead」）と",[120,3401,3402],{},"アセット種別","（Character, Prop, Setなど）を入力します。",[72,3405,3407],{"className":3406},[34,75],[77,3408],{"src":3409,"className":3410,"alt":12,"loading":82,"width":3411,"height":3412,"srcSet":3413,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-f4336c33-57ef-4baa-9715-e0c749f7d9b4.png",[81],1270,870,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-f4336c33-57ef-4baa-9715-e0c749f7d9b4.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-f4336c33-57ef-4baa-9715-e0c749f7d9b4.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-f4336c33-57ef-4baa-9715-e0c749f7d9b4.png 1270w",[48,3415,3416],{},"これでアセットが作成され、3つのタスクが割り当てられました。 ",[48,3418,3419],{},"タスクは、各アセットに対してアーティストが行う制作手順（モデリング、シェーディング、リギングなど）を定義します。",[48,3421,3422],{},"これで、アドオンをテストするための準備が整いました。",[61,3424],{},[64,3426,3428],{"id":3427},"_2-linking-the-current-blender-project-to-a-kitsu-task",[120,3429,3430],{},"2. 現在のBlenderプロジェクトをKitsuのタスクに紐づける",[48,3432,3433,3434,3436],{},"まずは、UIの配置を定義し、",[155,3435,165],{},"を読み込み、ドロップダウンメニューで公開するデータを準備する最小限のアドオン宣言から始めます：",[152,3438,3439,3451],{},[155,3440,3442,3443,3446,3448],{"className":3441},[175],"bl_info = {\n    \"name\": \"Model Versioning (Production/Task/Asset/Revisions)\",\n    \"author\": \"cgwire\",\n    \"version\": (1, 0, 0),\n    \"blender\": (2, 80, 0),\n    \"location\": \"View3D > Sidebar > ModelVersioning\",\n    \"description\": \"Browse productions, tasks, assets, and manage revisions (list/create/load)\",\n     \"category\": \"3D View\",\n}\n",[48,3444,3445],{},"import sys",[48,3447,2334],{},[48,3449,3450],{},"import os\nimport tempfile",[48,3452,3453],{},[155,3454,3456],{"className":3455},[175],"import bpy\nimport gazu\nfrom bpy.props import EnumProperty, PointerProperty\nfrom bpy.types import Operator, Panel, PropertyGroup",[48,3458,3459,3460,3462,3463,3465],{},"注目点として、",[155,3461,2334],{},"により、",[155,3464,165],{},"のような外部パッケージへアクセスするためにローカルのPythonインストールを使用できます。デフォルトではBlenderが独自のPython環境を動かすため、パッケージのインストールはやや面倒です。そこで、ローカルモジュールを参照するようBlenderに伝えます。このパスは、あなたのシステム設定に合わせて適宜更新してください。",[48,3467,3468,3469,3472],{},"バージョニングを自動化する前に、BlenderがKitsu上の",[655,3470,3471],{},"どこ","に現在のモデルが属するのかを理解する必要があります。つまり、プロジェクト、アセット、タスク、そして最終的にそれに紐づくリビジョンを特定します。",[48,3474,3475],{},"最初のステップは簡単です。Kitsuで認証し、利用可能な制作（Productions）を取得し、アーティストがサイドバーUIからコンテキストを直接選べるようにします。",[48,3477,3478],{},"アドオンが読み込まれたら、認証し、アドオンをKitsu APIホストへ向けます：",[152,3480,3481,3489],{},[155,3482,2032,3484,2036,3487,869],{"className":3483},[175],[94,3485,185],{"href":185,"rel":3486},[187],[94,3488,192],{"href":191},[48,3490,3491],{},[155,3492,3494],{"className":3493},[175],"temp_dir_path = tempfile.gettempdir()",[48,3496,3497],{},"これにより、制作を閲覧し、タスクを見つけ、そして最終的にリビジョンを作成するために使うセッションが確立されます。",[48,3499,3500],{},"ここから制作の構造を公開し始められます。プロジェクト、アセット、タスク、リビジョンの検索用ヘルパー関数を用意し、各ドロップダウンを動的に埋めます：",[152,3502,3503,3510],{},[155,3504,3506,3507],{"className":3505},[175],"def find_project(name):\n    return gazu.project.get_project_by_name(name)",[48,3508,3509],{},"def find_asset(project, name):\n    return gazu.asset.get_asset_by_name(project, name)",[48,3511,3512],{},[155,3513,3515],{"className":3514},[175],"def find_task(asset, type_id):\n    return gazu.task.get_task_by_name(asset, type_id, \"main\")",[48,3517,3518,3519,3522],{},"各",[155,3520,3521],{},"EnumProperty","のコールバックは、Kitsuから新しいデータを取得します：",[152,3524,3525],{},[155,3526,3528,3529,3531,3532,2347,3534,3536],{"className":3527},[175],"def enum_projects(self, context):\n    items = ",[263,3530],{},"\n    projects = gazu.project.all_projects()\n    for p in projects:\n        items.append((p",[263,3533,2350],{},[263,3535,2350],{},", \"\"))\n    if not items:\n        items.append((\"NONE\", \"--- no productions ---\", \"\"))\n    return items",[48,3538,3539],{},"アセット、タスク、リビジョンも同じパターンに従います：",[152,3541,3542,3566],{},[155,3543,3545,3546,3548,3549,3551,3552,3554,3555],{"className":3544},[175],"def enum_assets(self, context):\n    project = find_project(context.scene.mv_state.project)\n    items = ",[263,3547],{},"\n    if project:\n        assets = gazu.asset.all_assets_for_project(project)\n        for t in assets:\n            items.append((t",[263,3550,2350],{},", t",[263,3553,2350],{},", \"\"))\n    if not items:\n        items.append((\"NONE\", \"--- no tasks ---\", \"\"))\n    return items",[48,3556,3557,3558,3560,3561,3551,3563,3554],{},"def enum_tasks(self, context):\n    project = find_project(context.scene.mv_state.project)\n    asset = find_asset(project, context.scene.mv_state.asset)\n    items = ",[263,3559],{},"\n    if asset:\n        tasks = gazu.task.all_tasks_for_asset(asset)\n        for t in tasks:\n            items.append((t",[263,3562,2966],{},[263,3564,3565],{},"\"task_type_name\"",[48,3567,3568],{},[155,3569,3571,3572,3574,3575,3578,3579,3581],{"className":3570},[175],"def enum_revisions(self, context):\n    project = find_project(context.scene.mv_state.project)\n    asset = find_asset(project, context.scene.mv_state.asset)\n    task = find_task(asset, context.scene.mv_state.task)\n    items = ",[263,3573],{},"\n    if task:\n        revisions = gazu.files.get_all_preview_files_for_task(task)\n        for r in revisions:\n            items.append((str(r",[263,3576,3577],{},"\"revision\"","), str(r",[263,3580,3577],{},"), \"\"))\n    if not items:\n        items.append((\"NONE\", \"--- no revisions ---\", \"\"))\n    return items",[48,3583,3584],{},"最後に、すべてのUI選択を1つの状態（state）オブジェクトに保存します：",[152,3586,3587],{},[155,3588,3590],{"className":3589},[175],"class MV_State(PropertyGroup):\n    project: EnumProperty(\n        name=\"Project\", description=\"Select project\", items=enum_projects\n    )\n    asset: EnumProperty(name=\"Asset\", description=\"Select asset\", items=enum_assets)\n    task: EnumProperty(name=\"Task\", description=\"Select task\", items=enum_tasks)\n    revision: EnumProperty(\n        name=\"Revision\", description=\"Select revision\", items=enum_revisions\n    )",[48,3592,3593],{},"これはパイプライン統合の土台です。これでBlenderはKitsuを閲覧でき、アーティストが作業中の“正確なタスク”に自分自身を紐づけられるようになりました。ここから、リビジョンのライフサイクルに取り組み始めます。",[61,3595],{},[64,3597,3599],{"id":3598},"_3-creating-a-new-revision-button",[120,3600,3601],{},"3. 「新規リビジョン」ボタンを作成する",[48,3603,3604],{},"まずアーティストが最も頻繁に触れる部分の自動化を始められます。それが新しいリビジョンの作成です。通常の手作業ワークフローでは、ファイルをエクスポートして、正しいタスクに対してKitsuへアップロードします。私たちのアドオンでは、その作業をBlender内の1つのボタン操作にまとめます。",[48,3606,3607,3608,3611],{},"Kitsuは",[155,3609,3610],{},"publish_preview()","を通じて新しいリビジョンを処理します。これはファイルとメタデータの両方を送信します：",[152,3613,3614,3624],{},[155,3615,3617,3618,3621],{"className":3616},[175],"temp_file_path = os.path.join(temp_dir_path, \"new_version.glb\")",[48,3619,3620],{},"bpy.ops.export_scene.gltf(filepath=temp_file_path, export_format=\"GLB\")",[48,3622,3623],{},"(comment, preview_file) = gazu.task.publish_preview(\n    task,\n    task_status,\n    revision=new_revision,\n    comment=\"increment revision\",\n    preview_file_path=temp_file_path,\n)",[48,3625,3626],{},[155,3627,3629],{"className":3628},[175],"os.remove(temp_file_path)",[48,3631,3632],{},"アドオンでは、これをサイドバーのボタンからトリガーします。",[48,3634,3635],{},"オペレーターは主に3つのステップを実行します。アドオンの状態からユーザーの選択を取得し、次のリビジョン番号を計算し、エクスポートしたファイルを新しいリビジョンとしてアップロードします：",[152,3637,3638,3663],{},[155,3639,3641,3642,3645,3648,3651,3654,3657,3660],{"className":3640},[175],"class MV_OT_create_revision(Operator):\n    bl_idname = \"mv.create_revision\"\n    bl_label = \"Create Revision\"",[48,3643,3644],{},"    def invoke(self, context, event):\n        wm = context.window_manager\n        return wm.invoke_props_dialog(self, width=400)",[48,3646,3647],{},"    def execute(self, context):\n        project = find_project(context.scene.mv_state.project)\n        asset = find_asset(project, context.scene.mv_state.asset)\n        task = find_task(asset, context.scene.mv_state.task)\n        revision = context.scene.mv_state.revision\n        new_revision = int(revision) + 1",[48,3649,3650],{},"        task_status = gazu.task.get_task_status_by_name(\"todo\")",[48,3652,3653],{},"        temp_file_path = os.path.join(temp_dir_path, \"new_version.glb\")",[48,3655,3656],{},"        bpy.ops.export_scene.gltf(filepath=temp_file_path, export_format=\"GLB\")",[48,3658,3659],{},"        (comment, preview_file) = gazu.task.publish_preview(\n            task,\n            task_status,\n            revision=new_revision,\n            comment=\"increment revision\",\n            preview_file_path=temp_file_path,\n        )",[48,3661,3662],{},"        os.remove(temp_file_path)",[48,3664,3665],{},[155,3666,3668],{"className":3667},[175],"        self.report({\"INFO\"}, \"Revision created\")\n        return {\"FINISHED\"}",[61,3670],{},[64,3672,3674],{"id":3673},"_4-pulling-a-revision-into-blender",[120,3675,3676],{},"4. リビジョンをBlenderへ取り込む",[48,3678,3679,3680,3683],{},"バージョニングは、公開することだけではありません。",[655,3681,3682],{},"戻る","ことも重要です。以前の段階をレビューしたり、トポロジを比較したり、前回の反復から細部を復元したりする場合、Blenderへ新しいリビジョンや古いリビジョンを素早く確実に読み込む手段が必要です。",[48,3685,3686],{},"タスクが選択されると、Kitsuからリビジョンを取り出すのは簡単な2ステップになります。選択したリビジョンに紐づくプレビューファイルをダウンロードし、それをBlenderへインポートします。",[48,3688,3689],{},"現在のタスクに対するすべてのプレビューファイルを取得したら、インデックスで目的のリビジョンを特定し、アセットを直接Blenderへ取り込みます：",[152,3691,3692,3702],{},[155,3693,3617,3695],{"className":3694},[175],[48,3696,3697,3698,3701],{},"preview_file = preview_files",[263,3699,3700],{},"int(revision) - 1","\ngazu.files.download_preview_file(preview_file, temp_file_path)\nbpy.ops.import_scene.gltf(filepath=temp_file_path)",[48,3703,3704],{},[155,3705,3629],{"className":3706},[175],[48,3708,3709],{},"これにより、制作のその時点での状態そのままのアセットを、統一された手順で取得できるようになります。",[48,3711,3712],{},"このワークフローを、作成（Create Revision）ボタンの構造と同様のオペレーターにまとめます：",[152,3714,3715,3732],{},[155,3716,3718,3719,3722,3724,3730],{"className":3717},[175],"class MV_OT_load_revision(Operator):\n    bl_idname = \"mv.load_revision\"\n    bl_label = \"Load Revision\"",[48,3720,3721],{},"    def execute(self, context):\n        project = find_project(context.scene.mv_state.project)\n        asset = find_asset(project, context.scene.mv_state.asset)\n        task = find_task(asset, context.scene.mv_state.task)\n        revision = context.scene.mv_state.revision\n        preview_files = gazu.files.get_all_preview_files_for_task(task)",[48,3723,3653],{},[48,3725,3726,3727,3729],{},"        preview_file = preview_files",[263,3728,3700],{},"\n        gazu.files.download_preview_file(preview_file, temp_file_path)\n        bpy.ops.import_scene.gltf(filepath=temp_file_path)",[48,3731,3662],{},[48,3733,3734],{},[155,3735,3737],{"className":3736},[175],"        self.report({\"INFO\"}, \"Opened Revision\")\n        return {\"FINISHED\"}",[48,3739,3740],{},"このオペレーターにより、アーティストはBlenderを離れることなく、Kitsuに保存されている任意のバージョンを閲覧して読み込むことが簡単になります。",[61,3742],{},[64,3744,3746],{"id":3745},"_5-registering-the-addon",[120,3747,3748],{},"5. アドオンを登録する",[48,3750,3751,3756],{},[94,3752,3753],{"href":2318},[1936,3754,3755],{},"このパネルが、リビジョンのワークフロー全体をつなぎます","：",[212,3758,3759,3762,3765,3768,3771],{},[215,3760,3761],{},"プロジェクトを選択",[215,3763,3764],{},"アセットを選択",[215,3766,3767],{},"タスクを選択",[215,3769,3770],{},"リビジョンを閲覧",[215,3772,3773],{},"クリックひとつでバージョンを作成または読み込み",[152,3775,3776,3798],{},[155,3777,3779,3780,3783,3786,3789,3792,3795],{"className":3778},[175],"class MV_PT_panel(Panel):\n    bl_label = \"Model Versioning\"\n    bl_idname = \"MV_PT_panel\"\n    bl_space_type = \"VIEW_3D\"\n    bl_region_type = \"UI\"\n    bl_category = \"ModelVersion\"",[48,3781,3782],{},"    def draw(self, context):\n        layout = self.layout\n        scene = context.scene\n        mv = scene.mv_state",[48,3784,3785],{},"        layout.label(text=\"Project\")\n         layout.prop(mv, \"project\", text=\"\")\n        layout.separator()",[48,3787,3788],{},"        layout.label(text=\"Asset\")\n         layout.prop(mv, \"asset\", text=\"\")\n        layout.separator()",[48,3790,3791],{},"        layout.label(text=\"Task\")\n         layout.prop(mv, \"task\", text=\"\")\n        layout.separator()",[48,3793,3794],{},"        layout.label(text=\"Revision\")\n         layout.prop(mv, \"revision\", text=\"\")\n        layout.separator()",[48,3796,3797],{},"        row = layout.row(align=True)\n        row.operator(\"mv.create_revision\", text=\"Create Revision\", icon=\"ADD\")",[48,3799,3800],{},[155,3801,3803],{"className":3802},[175],"        layout.operator(\n            \"mv.load_revision\", text=\"Load Selected Revision\", icon=\"IMPORT\"\n        )",[48,3805,3806],{},"最後に、オペレーター、パネル、状態（state）を登録して、BlenderがUIを構築できるようにします：",[152,3808,3809,3819],{},[155,3810,3812,3813,3816],{"className":3811},[175],"classes = (\n    MV_State,\n    MV_OT_create_revision,\n    MV_OT_load_revision,\n    MV_PT_panel,\n)",[48,3814,3815],{},"def register():\n    for c in classes:\n        bpy.utils.register_class(c)\n    bpy.types.Scene.mv_state = PointerProperty(type=MV_State)",[48,3817,3818],{},"def unregister():\n    for c in reversed(classes):\n        bpy.utils.unregister_class(c)\n    if hasattr(bpy.types.Scene, \"mv_state\"):\n        del bpy.types.Scene.mv_state",[48,3820,3821],{},[155,3822,855,3824,859,3826,2491],{"className":3823},[175],[120,3825,858],{},[120,3827,862],{},[48,3829,3830],{},"この時点で、モデルのバージョニングワークフローは完全に双方向になっています。Blenderから新しいリビジョンを公開でき、以前のものを即座に取得できます。",[72,3832,3834],{"className":3833},[34,75],[77,3835],{"src":3836,"className":3837,"alt":12,"loading":82,"width":3838,"height":3839,"srcSet":3840,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-00e861e7-3b2e-4bdc-80b8-1af740cab480.png",[81],759,488,"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-00e861e7-3b2e-4bdc-80b8-1af740cab480.png 600w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-00e861e7-3b2e-4bdc-80b8-1af740cab480.png 759w",[61,3842],{},[64,3844,3845],{"id":507},[120,3846,508],{},[48,3848,3849],{},"Blender APIのオペレーターを数個と、Gazu SDKの便利さを組み合わせることで、Blenderの中にそのまま存在し、Kitsuと同期し続ける、実用的（ただし基本的な）バージョニングワークフローを構築しました。アーティストはBlenderのシーンをKitsuのプロジェクト、アセット、タスクに紐づけ、新しいリビジョンをボタンひとつで作成し、任意のタスクのリビジョン履歴をすべて閲覧し、比較や復元が必要になったときは古いバージョンを直接Blenderへ取り込めます。",[48,3851,3852],{},"このワークフローは、まだ始まりにすぎません。ここから、アドオンを拡張して自動エクスポート、サムネイルやトゥルーターンテーブルのレンダリング、複数の出力形式の対応、スーパーバイザー向けレビュー用ツール、さらにはレンダーファームへの連携などに広げられるでしょう。",[48,3854,3855,3856,3861],{},"まずは、このバージョニングアドオンの",[94,3857,1934,3858],{"href":3316},[1936,3859,3860],{},"GitHubリポジトリ","をクローンして、自分でも試してみてください！",[31,3863,3865,3868],{"className":3864},[34,35,36],[31,3866,524],{"className":3867},[40],[31,3869,3871,3872,3876],{"className":3870},[45],"アニメーション制作のプロセスについてさらに学ぶには、",[94,3873,3875],{"href":531,"rel":3874},[533],"Discordコミュニティへの参加をご検討ください","。私たちは1,000人以上の専門家とつながっており、ベストプラクティスを共有し、時には現地イベントも開催しています。ぜひ歓迎します！ 😊",[31,3878,3880],{"className":3879},[34,539,540],[94,3881,546],{"href":531,"className":3882},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":3884},[3885,3886,3887,3888,3889,3890,3891],{"id":3253,"depth":548,"text":3256},{"id":3322,"depth":548,"text":3325},{"id":3427,"depth":548,"text":3430},{"id":3598,"depth":548,"text":3601},{"id":3673,"depth":548,"text":3676},{"id":3745,"depth":548,"text":3748},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1617746533234-288e5cf484e2?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDMwfHxhbmltYXRpb24lMjBwaXBlbGluZXxlbnwwfHx8fDE3NjYzODE5ODZ8MA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":3191,"featured_at":561,"visibility":562},"/blog-i18n/ja/blender-kitsu-versioning-addon","2025-12-22T10:00:20.000+01:00",{"title":3203,"description":12},"blender-kitsu-versioning-addon","blog-i18n/ja/blender-kitsu-versioning-addon/index",[3900,3901],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1844,"name":1845,"slug":1846,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1847},"eGBSo-eSNAi3-nyZ73vJVVakmWAlmsvIl8-iRrOIFuA",{"id":3904,"title":3905,"authors":3906,"body":3908,"description":12,"extension":557,"feature_image":4383,"html":7,"meta":4384,"navigation":13,"path":4386,"published_at":4387,"seo":4388,"slug":4389,"stem":4390,"tags":4391,"__hash__":4394,"updated_at":4385,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/blender-programmatic-rendering/index.md","Python（2026）でBlenderにおけるプログラムによる動画レンダリング",[3907],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":3909,"toc":4374},[3910,3921,3924,3927,3930,3933,3939,3942,3944,3950,3953,3997,4000,4003,4029,4032,4057,4059,4065,4068,4074,4084,4093,4095,4101,4104,4110,4117,4120,4126,4129,4137,4139,4145,4155,4158,4164,4167,4173,4176,4184,4186,4192,4201,4212,4215,4221,4224,4230,4233,4239,4242,4248,4251,4257,4260,4265,4267,4273,4280,4306,4309,4315,4318,4326,4342,4344,4348,4351,4354,4368],[31,3911,3913,3917],{"className":3912},[34,35,36],[31,3914,3916],{"className":3915},[40],"🧠",[31,3918,3920],{"className":3919},[45],"数行のPythonだけで、Blenderをプログラム可能なレンダリングエンジンに変えます。",[48,3922,3923],{},"3DアーティストとしてBlenderを学ぶことは、通常はそのアドオン・エコシステムについて学ぶことを意味します。リグ付けのように何時間もかかってしまう作業も、Rigifyのようなアドオンによって数秒に短縮できます。同じことはほとんどのワークフローでも言えます。私たちはしばしば、同じような繰り返しの疑問を抱きます。「Blenderはこれを自動でできるのだろうか？」",[48,3925,3926],{},"答えは「はい」です。ポイントはプログラミング言語のPythonです。",[48,3928,3929],{},"Blenderには強力な内蔵スクリプトエンジンがあり、数行のコードでオブジェクトを作成し、カメラを配置し、さらにはフルレンダリングをトリガーできます。",[48,3931,3932],{},"自分でアドオンを作れるなら、アドオンにお金を払う必要はありません。そしてアドオンの本質は、カスタムのBlenderユーザーインターフェースで包まれた単なるスクリプトです。",[48,3934,3935,3936,3938],{},"Blenderでスクリプトを書いたことがない場合、",[155,3937,2155],{},"モジュールを見つける体験は、すでに知っているはずのツールの中にある「秘密の扉を開く」ようなものです。すると、突然インターフェースのあらゆる部分がプログラム可能になります。もはやボタンをクリックしているだけではなく、反復可能な仕組みを作るための指示を出しているのです。",[48,3940,3941],{},"自動化できる最も重要なワークフローの1つがレンダリングです。パイプラインを速くするだけでなく、レンダリング設定を一貫していて予測しやすい状態に保つのにも役立ちます。このチュートリアルでは、3Dテキストを自動でアニメーションさせ、フルHDの動画に変換するための基本的なプログラムによるレンダリングシステムを実装します。ゼロから始めて、BlenderでPythonを実行する方法、そしてシーンを制御する方法を探っていきます。最後には、一般的なアニメーション作業を自動化する方法の全体像をしっかり掴めるはずです。",[61,3943],{},[64,3945,3947],{"id":3946},"use-cases",[120,3948,3949],{},"ユースケース",[48,3951,3952],{},"プログラムによるレンダリングは、従来の手作業によるシーン構築をはるかに超えた、多様で強力なワークフローを開放します：",[212,3954,3955,3961,3967,3973,3979,3985,3991],{},[215,3956,3957,3960],{},[120,3958,3959],{},"データ駆動モーショングラフィックス"," — アニメーション化されたチャート、リアルタイムのAPI駆動による放送用グラフィックス、または自動生成されるソーシャル動画。",[215,3962,3963,3966],{},[120,3964,3965],{},"生成アート"," — コードから進化していくプロシージャルなパターン、ノイズフィールド、粒子実験、アルゴリズムによるイラスト。",[215,3968,3969,3972],{},[120,3970,3971],{},"バッチレンダリングされたバリエーション"," — パーソナライズされた広告、製品の色違い、アスペクト比の自動トリミング、大量のソーシャル素材生成。",[215,3974,3975,3978],{},[120,3976,3977],{},"プロシージャルな3Dコンテンツ"," — 地形ビルダー、パラメトリックモデリング、植生／ワールドの人口、3Dアセットのバリエーションを自動で生成。",[215,3980,3981,3984],{},[120,3982,3983],{},"生成UI & デザインシステム"," — ダイナミックなSVG、テンプレート化されたバナー、ブランドに一貫したグラフィックスを必要なときにレンダリング。",[215,3986,3987,3990],{},[120,3988,3989],{},"VFXおよびアニメーションのスクリプト化"," — 自動化されたリグ制御、群衆システム、粒子の増殖、反復可能なシミュレーション設定。",[215,3992,3993,3996],{},[120,3994,3995],{},"シミュレーションの可視化"," — 流体や煙のシミュレーション、交通や群衆のダイナミクス、科学的／物理ベースのレンダリング。",[48,3998,3999],{},"多くの3Dモデリング作業は反復的で時間がかかります。これらを自動化された、スクリプト駆動のパイプラインに統合することで、Pythonが面倒な部分を裏で処理し、アーティストは創造的なワールド構築により集中できます。",[48,4001,4002],{},"いずれの場合でも、開発ワークフローはほぼ同じです：",[1710,4004,4005,4011,4017,4023],{},[215,4006,4007,4010],{},[120,4008,4009],{},"セットアップ"," - 必要な入力データを定義し、シーンをクリーンアップ",[215,4012,4013,4016],{},[120,4014,4015],{},"ジオメトリ生成"," - タスクに必要な実際のアセットをモデリング",[215,4018,4019,4022],{},[120,4020,4021],{},"アニメーション"," - トランスフォームとそれに関連するキーフレームを定義",[215,4024,4025,4028],{},[120,4026,4027],{},"出力"," - 望む成果物（3Dモデル、動画、画像シーケンスなど）",[48,4030,4031],{},"そして、これがまさに私たちが3Dテキスト動画レンダリングの例で辿る道です。",[31,4033,4035,4038],{"className":4034},[34,35,108],[31,4036,112],{"className":4037},[40],[31,4039,4041,4045,4047,129,4049,4051,134,4053],{"className":4040},[45],[117,4042,4043],{},[120,4044,2651],{"style":122},[125,4046],{},[125,4048],{},[125,4050],{},[125,4052],{},[94,4054,4056],{"href":4055},"https://github.com/cgwire/blender-programmatic-rendering?ref=blog.cg-wire.com","https://github.com/cgwire/blender-programmatic-rendering",[61,4058],{},[64,4060,4062],{"id":4061},"_1-scene-setup",[120,4063,4064],{},"1. シーン設定",[48,4066,4067],{},"シーンを生成する前に、まずはきれいなスタート地点が必要です。Blenderを開くと、通常はキューブ、カメラ、ライトを含むデフォルトのシーンが読み込まれます。このチュートリアルでは後者2つだけを使います。",[48,4069,4070,4071,4073],{},"Blenderをプログラム的に使う最初のステップは、",[155,4072,2155],{},"モジュールをインポートすることです。これによりPythonからBlenderのデータ、ツール、レンダリングパイプラインへ直接フルアクセスできます：",[152,4075,4076,4079],{},[155,4077,2684],{"className":4078},[175],[48,4080,4081],{},[155,4082,2169],{"className":4083},[175],[48,4085,4086,4087,4089,4090,4092],{},"ここではデフォルトの",[120,4088,2162],{},"オブジェクトを削除します。",[155,4091,2176],{},"というパラメータにより、Blenderはオブジェクトを削除するだけでなく、それを参照している可能性のあるどのシーンからもアンリンクします。",[61,4094],{},[64,4096,4098],{"id":4097},"_2-manipulating-3d-text",[120,4099,4100],{},"2. 3Dテキストの操作",[48,4102,4103],{},"次に、シーンへ3Dテキストオブジェクトを追加し、これを操作し、最終的にプログラムによってレンダリングする中核要素にします。",[152,4105,4106],{},[155,4107,4109],{"className":4108},[175],"bpy.ops.object.text_add(location=(0, 0, 0))\ntext_obj = bpy.context.object\ntext_obj.name = \"CaptionText\"\ntext_obj.data.body = \"Hello world!\"",[48,4111,4112,4113,4116],{},"このコードスニペットは、ワールド原点に新しいテキストオブジェクトを作成し、読みやすい名前を割り当て、表示テキストを",[155,4114,4115],{},"\"Hello world!\"","に設定します。",[48,4118,4119],{},"テキストにシーン内での存在感を持たせるために、ジオメトリを調整できます。サイズを大きくし、押し出し（エクストルード）を追加することで完全な3Dテキストになり、さらに両軸で中心揃えにしておくと、将来の変換やアニメーションが簡単になります：",[152,4121,4122],{},[155,4123,4125],{"className":4124},[175],"text_obj.data.size = 0.6\ntext_obj.data.extrude = 0.05\ntext_obj.data.align_x = \"CENTER\"\ntext_obj.data.align_y = \"CENTER\"",[48,4127,4128],{},"これらの調整により、テキストはきれいに中央揃えされ、適切にスケールされ、さらなる処理の準備が整います。",[72,4130,4132],{"className":4131},[34,75],[77,4133],{"src":4134,"className":4135,"alt":12,"loading":82,"width":83,"height":2702,"srcSet":4136,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-8cb519b5-e128-4bdd-9348-9aa0dfe2c36c.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-8cb519b5-e128-4bdd-9348-9aa0dfe2c36c.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-8cb519b5-e128-4bdd-9348-9aa0dfe2c36c.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-8cb519b5-e128-4bdd-9348-9aa0dfe2c36c.png 1600w",[61,4138],{},[64,4140,4142],{"id":4141},"_3-adding-keyframes",[120,4143,4144],{},"3. キーフレームを追加する",[48,4146,4147,4148,4154],{},"次に、",[94,4149,1934,4151],{"href":4150},"https://blog.cg-wire.com/stepped-animation/",[1936,4152,4153],{},"キーフレームを挿入してテキスト位置のシンプルなアニメーションを作成","し、時間の経過に沿って動かします。",[48,4156,4157],{},"まず、タイムラインカーソルをフレーム1に移動し、テキストを開始位置に配置して、その位置をキーフレームとして記録します：",[152,4159,4160],{},[155,4161,4163],{"className":4162},[175],"bpy.context.scene.frame_set(1)\ntext_obj.location = (-4.0, 0.0, 1.0)\ntext_obj.keyframe_insert(data_path=\"location\", frame=1)",[48,4165,4166],{},"次にフレーム40へ進め、X軸方向にテキストをシフトさせて、新しい位置を示すもう1つのキーフレームを挿入します：",[152,4168,4169],{},[155,4170,4172],{"className":4171},[175],"bpy.context.scene.frame_set(40)\ntext_obj.location = (0.0, 0.0, 1.0)\ntext_obj.keyframe_insert(data_path=\"location\", frame=40)",[48,4174,4175],{},"これら2つのキーフレームが揃うと、Blenderは自動的にその間の移動を補間し、テキストがフレーム中央へ滑り込むような滑らかなアニメーションを作成します。",[72,4177,4179],{"className":4178},[34,75],[77,4180],{"src":4181,"className":4182,"alt":12,"loading":82,"width":83,"height":2702,"srcSet":4183,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-c33d7b37-264c-4c9f-a1ea-e8f2e2a39ff2.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-c33d7b37-264c-4c9f-a1ea-e8f2e2a39ff2.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-c33d7b37-264c-4c9f-a1ea-e8f2e2a39ff2.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-c33d7b37-264c-4c9f-a1ea-e8f2e2a39ff2.png 1600w",[61,4185],{},[64,4187,4189],{"id":4188},"_4-video-rendering",[120,4190,4191],{},"4. 動画のレンダリング",[48,4193,4194,4195,4200],{},"残っているのは、",[94,4196,1934,4197],{"href":2759},[1936,4198,4199],{},"Blenderのレンダリング設定を構成","して、最終的な動画を出力するだけです。",[48,4202,4203,4204,4207,4208,4211],{},"まず、どのレンダリングエンジンを使うかを選びます：",[120,4205,4206],{},"Eevee"," か ",[120,4209,4210],{},"Cycles"," です。",[48,4213,4214],{},"Eeveeはリアルタイムのラスタライズエンジンなので非常に高速で、プレビューやスタイライズされたアニメーションに最適です。一方Cyclesは、物理ベースのパストレーサでより現実的なライティングを生成しますが、レンダリング時間がはるかに長くなります。素早い反復と多くの自動化ワークフローでは、Eeveeが一般により良い選択肢です：",[152,4216,4217],{},[155,4218,4220],{"className":4219},[175],"bpy.context.scene.render.engine = \"BLENDER_EEVEE\"",[48,4222,4223],{},"次に、出力解像度を指定します：",[152,4225,4226],{},[155,4227,4229],{"className":4228},[175],"bpy.context.scene.render.resolution_x = 1920\nbpy.context.scene.render.resolution_y = 1080",[48,4231,4232],{},"次にフレームレートとアニメーション範囲を設定します。ここでは24 fpsで60フレームのショットです：",[152,4234,4235],{},[155,4236,4238],{"className":4237},[175],"bpy.context.scene.render.fps = 24\nbpy.context.scene.frame_start = 1\nbpy.context.scene.frame_end = 60",[48,4240,4241],{},"Blenderは、最終動画をどのようにエンコードするかも知る必要があります。レンダリング速度のため、H.264の動画エンコーディングを使ってMP4として書き出します：",[152,4243,4244],{},[155,4245,4247],{"className":4246},[175],"bpy.context.scene.render.image_settings.file_format = \"FFMPEG\"\nbpy.context.scene.render.ffmpeg.format = \"MPEG4\"\nbpy.context.scene.render.ffmpeg.codec = \"H264\"",[48,4249,4250],{},"最後に、利便性のためカレントフォルダを使って出力ファイルの保存先を選びます：",[152,4252,4253],{},[155,4254,4256],{"className":4255},[175],"bpy.context.scene.render.filepath = \"//render.mp4\"",[48,4258,4259],{},"すべてが設定できたら、次の1つのコマンドでレンダリング処理を開始できます：",[152,4261,4262],{},[155,4263,2806],{"className":4264},[175],[61,4266],{},[64,4268,4270],{"id":4269},"_5-putting-it-all-together",[120,4271,4272],{},"5. まとめる",[48,4274,4275,4276,4279],{},"コードは完成しているので、あとはそれをPythonファイル",[155,4277,4278],{},"render.py","に入れるだけです：",[152,4281,4282,4301],{},[155,4283,1680,4285,4287,4289,4291,4293,4295,4298],{"className":4284},[175],[48,4286,2169],{},[48,4288,4109],{},[48,4290,4125],{},[48,4292,4163],{},[48,4294,4172],{},[48,4296,4297],{},"bpy.context.scene.render.engine = \"BLENDER_EEVEE\"\nbpy.context.scene.render.resolution_x = 1920\nbpy.context.scene.render.resolution_y = 1080\nbpy.context.scene.render.resolution_percentage = 100\nbpy.context.scene.render.fps = 24\nbpy.context.scene.frame_start = 1\nbpy.context.scene.frame_end = 60",[48,4299,4300],{},"bpy.context.scene.render.image_settings.file_format = \"FFMPEG\"\nbpy.context.scene.render.ffmpeg.format = \"MPEG4\"  # container\nbpy.context.scene.render.ffmpeg.codec = \"H264\"\nbpy.context.scene.render.ffmpeg.constant_rate_factor = \"HIGH\"\nbpy.context.scene.render.ffmpeg.gopsize = 12\nbpy.context.scene.render.ffmpeg.audio_codec = \"AAC\"\nbpy.context.scene.render.filepath = \"//render.mp4\"",[48,4302,4303],{},[155,4304,2806],{"className":4305},[175],[48,4307,4308],{},"レンダリングを開始するために、スクリプトを実行します：",[152,4310,4311],{},[155,4312,4314],{"className":4313},[158],"python3 render.py",[48,4316,4317],{},"レンダリングが完了したら、作業ディレクトリを確認してください。完全にプログラムで生成されたアニメーションが、これで視聴できる状態になっているはずです。",[72,4319,4321],{"className":4320},[34,75],[77,4322],{"src":4323,"className":4324,"alt":12,"loading":82,"width":2814,"height":2815,"srcSet":4325,"sizes":86},"https://blog.cg-wire.com/content/images/2025/12/data-src-image-2b287259-a96b-456b-b95e-375bf116e3a1.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/12/data-src-image-2b287259-a96b-456b-b95e-375bf116e3a1.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/12/data-src-image-2b287259-a96b-456b-b95e-375bf116e3a1.png 1000w, https://blog.cg-wire.com/content/images/2025/12/data-src-image-2b287259-a96b-456b-b95e-375bf116e3a1.png 1088w",[31,4327,4329,4333],{"className":4328},[34,35,108],[31,4330,4332],{"className":4331},[40],"🔗",[31,4334,4336,4337],{"className":4335},[45],"コードは、再現しやすいようにGithubのリポジトリで確認できます：",[94,4338,1934,4339],{"href":4055},[1936,4340,4341],{},"github.com/cgwire/blender-programmatic-rendering",[61,4343],{},[64,4345,4346],{"id":507},[120,4347,508],{},[48,4349,4350],{},"この手順解説では、Blenderの中に完全な自動化パイプラインを構築しました。クリーンなシーンを用意し、3Dテキストを作成・修正し、キーフレームでアニメーションさせ、スムーズな補間でシーケンスをレンダリングしたのです。必要な手作業は一切ありません。すべてPythonだけで処理されます！",[48,4352,4353],{},"Blender APIがどれほどの制御を提供してくれるかを見た今、これらのアイデアをさらに大きく広げられます。ワークフローを自動化し、データからグラフィックスを生成し、シーンを組み立てる内部ツールを作り、バリエーションをレンダリングし、あるいは1つのコマンドでまるごとアニメーションを作ることもできます... アニメーション制作チームをもっと生産的にするための道が尽きることはありません。",[31,4355,4357,4360],{"className":4356},[34,35,36],[31,4358,524],{"className":4359},[40],[31,4361,4363,4364,4367],{"className":4362},[45],"アニメーションのプロセスについてさらに学ぶには ",[94,4365,2559],{"href":531,"rel":4366},[533],"！ベストプラクティスを共有する1,000人以上の専門家とつながれ、時には対面イベントも開催しています。ぜひあなたをお迎えできればうれしいです！ 😊",[31,4369,4371],{"className":4370},[34,539,540],[94,4372,546],{"href":531,"className":4373},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":4375},[4376,4377,4378,4379,4380,4381,4382],{"id":3946,"depth":548,"text":3949},{"id":4061,"depth":548,"text":4064},{"id":4097,"depth":548,"text":4100},{"id":4141,"depth":548,"text":4144},{"id":4188,"depth":548,"text":4191},{"id":4269,"depth":548,"text":4272},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1622547748225-3fc4abd2cca0?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fHJlbmRlcnN8ZW58MHx8fHwxNzY2MzgyNjA1fDA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":4385,"featured_at":561,"visibility":562},"2026-02-20T06:04:02.000+01:00","/blog-i18n/ja/blender-programmatic-rendering","2025-12-29T10:00:10.000+01:00",{"title":3905,"description":12},"blender-programmatic-rendering","blog-i18n/ja/blender-programmatic-rendering/index",[4392,4393],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1844,"name":1845,"slug":1846,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1847},"oWbNO3-IVpDw_voRr6qrAq6lQPAjmF1KehdW3Cbw1Zg",{"id":4396,"title":4397,"authors":4398,"body":4400,"description":12,"extension":557,"feature_image":5243,"html":7,"meta":5244,"navigation":13,"path":5246,"published_at":5247,"seo":5248,"slug":5249,"stem":5250,"tags":5251,"__hash__":5254,"updated_at":5245,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/blender-scripting-animation/index.md","Blender スクリプトによるアニメーションパイプライン入門: 2026",[4399],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":4401,"toc":5234},[4402,4413,4416,4419,4421,4427,4430,4433,4454,4456,4462,4465,4484,4511,4513,4519,4530,4539,4542,4548,4551,4562,4571,4574,4580,4583,4589,4592,4594,4600,4603,4612,4615,4618,4629,4643,4646,4652,4682,4685,4691,4709,4712,4718,4738,4747,4750,4759,4782,4785,4791,4795,4798,4821,4823,4829,4832,4838,4845,4852,4860,4867,4873,4880,4883,4889,4893,4899,4917,4920,4922,4928,4931,4937,5059,5062,5193,5195,5199,5202,5208,5211,5214,5228],[31,4403,4405,4409],{"className":4404},[34,35,36],[31,4406,4408],{"className":4407},[40],"⚙️",[31,4410,4412],{"className":4411},[45],"ほんの数行のコードで、Blenderを思い通りに操れます。繰り返しのクリック作業？ もう不要。複雑なシーン？ 数秒で構築。カスタムツール？ あなたがデザインします。これがスクリプトの魔法です。",[48,4414,4415],{},"Blenderのグラフィカルなユーザーインターフェースは間違いなく素晴らしいですが、どうしても「やるのが面倒」に感じる作業がいくつかあります。チームにプレビューを共有すること、新しいプロジェクトで延々と設定を調整すること、そして同じ手順を何度も繰り返すことです。時には、ただ「それを実行するボタン」が欲しくなるでしょう。スクリプトは、それを実現する鍵です！",[48,4417,4418],{},"この記事では、Pythonというプログラミング言語を使ってBlenderのスクリプト機能を掘り下げます。最初のスクリプトの書き方、実行方法、そしてBlenderのスクリプトモジュールがどのように整理されているかを学びます。最後まで読めば、制作パイプラインを最適化し始めるための理解がしっかり得られます。",[61,4420],{},[64,4422,4424],{"id":4423},"what-can-i-do-with-scripting",[120,4425,4426],{},"スクリプトで何ができる？",[48,4428,4429],{},"Blenderのスクリプトは、趣味の人のためのちょっとした小技というだけではありません。あらゆる規模のスタジオにとって必須のものです。",[48,4431,4432],{},"制作現場では、スピードと一貫性がすべてです。スタジオは常に厳しい締切、大量のアセットライブラリ、そして複数のワークステーション間で多数のショットやシーンを完全に同期させ続ける必要に直面します。これを手作業でやるのは遅く、ミスが起きやすく、高コストです。だからこそ自動化が非常に重要になるのです！",[48,4434,4435,4436,4439,4440,4443,4444,4449,4450,4453],{},"スクリプトは「コードを書く」ことが目的ではありません。あなた自身に創造的なショートカットや超能力を与えることが目的です。Pythonを使えば、時間を奪う退屈で繰り返しの多い作業を自動化したり、手順的ジオメトリ（プロシージャルな幾何）やマテリアル、さらには環境そのものを数行で生成したりできます。",[120,4437,4438],{},"制作フローに合わせて自分だけのツールやメニューを設計","でき、",[120,4441,4442],{},"シーンを完全にコントロール","し、",[94,4445,1934,4446],{"href":2759},[1936,4447,4448],{},"レンダー設定","、カメラ、ライトを思い通りに扱えます。スクリプトならさらに、",[120,4451,4452],{},"Blenderを外部ツールやAPIと連携","できるため、より大きなパイプラインの中でも強力な役割を果たします。",[61,4455],{},[64,4457,4459],{"id":4458},"prerequisites",[120,4460,4461],{},"前提条件",[48,4463,4464],{},"始める前に、次のものが用意できていることを確認してください：",[212,4466,4467,4478],{},[215,4468,4469,1490,4471,4477],{},[120,4470,1845],{},[94,4472,1934,4474],{"href":4473},"https://www.blender.org/download/?ref=blog.cg-wire.com",[1936,4475,4476],{},"blender.org","から最新バージョンをダウンロードしてインストールします。",[215,4479,4480,4483],{},[120,4481,4482],{},"Python"," - Blenderのネイティブスクリプトモジュールを使い、OSのターミナルからプログラムを実行するために、Pythonプログラミング言語が必要です。",[31,4485,4488,4491],{"className":4486},[34,35,4487],"kg-callout-card-green",[31,4489,112],{"className":4490},[40],[31,4492,4494,4498,4500,4502,4503,4505,134,4507],{"className":4493},[45],[117,4495,4496],{},[120,4497,2651],{"style":122},[125,4499],{},[125,4501],{},"このガイドで紹介している例の統合について、完全なソースコードはGitHubで確認できます：",[125,4504],{},[125,4506],{},[94,4508,4510],{"href":4509},"https://github.com/cgwire/intro-blender-scripting?ref=blog.cg-wire.com","https://github.com/cgwire/intro-blender-scripting",[61,4512],{},[64,4514,4516],{"id":4515},"_1-create-a-new-script",[120,4517,4518],{},"1. 新しいスクリプトを作成する",[48,4520,4521,4522,4525,4526,4529],{},"Blenderの中で",[120,4523,4524],{},"スクリプト作業スペース","を開きます。",[120,4527,4528],{},"New","をクリックすると、新しいスクリプトを作成できるテキストエディタのパネルが表示されます。ここでPythonコードを書けます。特に、結果をリアルタイムで確認できる点が便利です：",[72,4531,4533],{"className":4532},[34,75],[77,4534],{"src":4535,"className":4536,"alt":12,"loading":82,"width":83,"height":4537,"srcSet":4538,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-05bcd44b-e1a3-4f6a-a5c7-edb11e40b1fb.png",[81],731,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-05bcd44b-e1a3-4f6a-a5c7-edb11e40b1fb.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-05bcd44b-e1a3-4f6a-a5c7-edb11e40b1fb.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-05bcd44b-e1a3-4f6a-a5c7-edb11e40b1fb.png 1600w",[48,4540,4541],{},"制作パイプラインでは、コマンドラインインターフェースからスクリプトを実行するほうが、たいていはより役に立ちます。幸い、PythonにはBlender用のモジュールが同梱されています。このチュートリアルでは、グラフィカルユーザーインターフェースを行き来する手順を省くために、OSのターミナルから直接Pythonプログラムを実行します。まずは必要なBlenderモジュールをインストールしましょう：",[152,4543,4544],{},[155,4545,4547],{"className":4546},[158],"pip install bpy==3.6.0 --extra-index-url \u003Chttps://download.blender.org/pypi/>",[48,4549,4550],{},"テストとして、Pythonで新しい空のBlenderファイルを作成してみましょう：",[152,4552,4553,4556],{},[155,4554,2684],{"className":4555},[175],[48,4557,4558],{},[155,4559,4561],{"className":4560},[175],"bpy.ops.wm.save_as_mainfile(filepath=\"./new_empty_file.blend\")",[48,4563,4564,4565,4568,4570],{},"まず、Blenderの",[120,4566,4567],{},"Python APIモジュール",[155,4569,2155],{},"をインポートします。これにより、Blenderのほぼすべてを操作できます（オブジェクト、マテリアル、レンダリングなど）。次に、現在のワークスペースを新しいファイルとして保存します。",[48,4572,4573],{},"ターミナルでプログラムを次のように実行できます：",[152,4575,4576],{},[155,4577,4579],{"className":4578},[175],"python3 script.py",[48,4581,4582],{},"新しく作成したファイルは、BlenderのCLIから開くこともできます：",[152,4584,4585],{},[155,4586,4588],{"className":4587},[158],"blender new_empty_file.blend",[48,4590,4591],{},"おめでとうございます！これで最初のスクリプトは完了です。次は、もっと実用的な例として「3Dテキストの生成」に進みましょう。",[61,4593],{},[64,4595,4597],{"id":4596},"_2-hello-world-text-example",[120,4598,4599],{},"2. Hello Worldテキストの例",[48,4601,4602],{},"スター・ウォーズのオープニングアニメーションを作りたいと想像してみてください。つまり、角度をつけた状態でテキストがゆっくり上にスクロールしていくあの演出です。",[72,4604,4606],{"className":4605},[34,75],[77,4607],{"src":4608,"className":4609,"alt":12,"loading":82,"width":83,"height":4610,"srcSet":4611,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-02ff3b4e-8e6f-4f1a-b6d0-e4fb9e0622eb.png",[81],681,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-02ff3b4e-8e6f-4f1a-b6d0-e4fb9e0622eb.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-02ff3b4e-8e6f-4f1a-b6d0-e4fb9e0622eb.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-02ff3b4e-8e6f-4f1a-b6d0-e4fb9e0622eb.png 1600w",[48,4613,4614],{},"編集しやすいように、これを効率よく行うにはどうすればいいでしょう？もちろんスクリプトを使います！では、簡単な例としていくつかの3Dテキストを生成してみましょう。",[48,4616,4617],{},"新しいファイルを作成し、シーン内のすべてのオブジェクトを削除して、最初はスッキリした状態から始めます：",[152,4619,4620,4623],{},[155,4621,1680],{"className":4622},[175],[48,4624,4625],{},[155,4626,4628],{"className":4627},[175],"bpy.ops.object.select_all(action='SELECT')\nbpy.ops.object.delete(use_global=False)",[212,4630,4631,4637],{},[215,4632,4633,4636],{},[155,4634,4635],{},"bpy.ops.object.select_all(action='SELECT')",": 現在シーン内にあるすべてのオブジェクトを選択します。",[215,4638,4639,4642],{},[155,4640,4641],{},"bpy.ops.object.delete(use_global=False)",": 選択されたすべてのオブジェクトを削除します。",[48,4644,4645],{},"シーンに新しいテキストオブジェクトを追加するには、次の2つの指示だけで十分です：",[152,4647,4648],{},[155,4649,4651],{"className":4650},[175],"bpy.ops.object.text_add(enter_editmode=False, location=(0, 0, 0))\ntext_obj = bpy.context.object",[212,4653,4654,4668],{},[215,4655,4656,4659,4660,4663,4664,4667],{},[155,4657,4658],{},"bpy.ops.object.text_add(...)",": 3Dワールド（XYZ座標）の",[155,4661,4662],{},"(0, 0, 0)","に",[120,4665,4666],{},"テキストオブジェクト","を追加します。",[215,4669,4670,4673,4674,4677,4678,4681],{},[155,4671,4672],{},"text_obj = bpy.context.object",": 新しく作成したテキストオブジェクトへの参照を、変数",[155,4675,4676],{},"text_obj","に保存します。何かを新しく追加すると、Blenderはそれをアクティブオブジェクトにします。アクティブオブジェクトは",[155,4679,4680],{},"bpy.context.object","でアクセスできます。",[48,4683,4684],{},"テキストの文字列を「Hello World」に変更します：",[152,4686,4687],{},[155,4688,4690],{"className":4689},[175],"text_obj.data.body = \"Hello World\"",[212,4692,4693,4703],{},[215,4694,4695,4698,4699,4702],{},[155,4696,4697],{},"text_obj.data","は",[120,4700,4701],{},"Text DataBlock","を指し、テキストオブジェクトの実際の内容や設定です。",[215,4704,4705,4708],{},[155,4706,4707],{},".body = \"Hello World\"","で、表示する文字列を「Hello World」に設定します。",[48,4710,4711],{},"次に、テキストに少し厚みを出して、X軸とY軸の中央に配置します：",[152,4713,4714],{},[155,4715,4717],{"className":4716},[175],"text_obj.data.extrude = 0.05\ntext_obj.data.align_x = 'CENTER'\ntext_obj.data.align_y = 'CENTER'",[212,4719,4720,4726,4732],{},[215,4721,4722,4725],{},[155,4723,4724],{},"extrude = 0.05",": テキストの奥行きを与え、平面の2Dテキストから、少し押し出された3Dテキストにします。",[215,4727,4728,4731],{},[155,4729,4730],{},"align_x = 'CENTER'",": テキストを水平方向に中央揃えします。",[215,4733,4734,4737],{},[155,4735,4736],{},"align_y = 'CENTER'",": テキストを垂直方向に中央揃えします。",[48,4739,4740,4741],{},"他にも多くのオプションは、",[94,4742,1934,4744],{"href":4743},"https://docs.blender.org/manual/en/latest/modeling/texts/properties.html?ref=blog.cg-wire.com",[1936,4745,4746],{},"Blenderのテキストオブジェクトのプロパティに関するドキュメント",[48,4748,4749],{},"最後に、BlenderのテキストはデフォルトでXY平面に平たく置かれるため、地面に寝かせた状態ではなく、カメラのほうを向くように回転させます：",[152,4751,4752],{},[155,4753,4755,4756,4758],{"className":4754},[175],"text_obj.rotation_euler",[263,4757,265],{}," = 1.5708   # 90 degrees in radians",[212,4760,4761,4773],{},[215,4762,4763,4768,4769,4772],{},[155,4764,4765,4766],{},"rotation_euler",[263,4767,265],{},": ",[120,4770,4771],{},"X軸まわりの回転","を指します。",[215,4774,4775,4778,4779,600],{},[155,4776,4777],{},"1.5708","ラジアン ≈ ",[120,4780,4781],{},"90度",[48,4783,4784],{},"結果を保存するには、先ほどの指示を使います：",[152,4786,4787],{},[155,4788,4790],{"className":4789},[175],"bpy.ops.wm.save_as_mainfile(filepath=\"./text.blend\")",[48,4792,4793],{},[125,4794],{},[48,4796,4797],{},"まとめると、最終的なコードは次のようになります：",[152,4799,4800,4816],{},[155,4801,1680,4803,4805,4807,4809,4811],{"className":4802},[175],[48,4804,4628],{},[48,4806,4651],{},[48,4808,4690],{},[48,4810,4717],{},[48,4812,4755,4813,4815],{},[263,4814,265],{}," = 1.5708",[48,4817,4818],{},[155,4819,4790],{"className":4820},[175],[61,4822],{},[64,4824,4826],{"id":4825},"_3-how-to-run-a-script-script-loading",[120,4827,4828],{},"3. スクリプトの実行方法（スクリプト読み込み）",[48,4830,4831],{},"前述のとおり、ヘッドレスモードでスクリプトを実行する構文は、基本的にどんなPythonプログラムと同じです：",[152,4833,4834],{},[155,4835,4837],{"className":4836},[175],"python3 text.py",[48,4839,4840,4841,4844],{},"以上です！これで、最初の",[655,4842,4843],{},"実用的な","Blenderスクリプトを実行できました。自動化、パイプライン、バッチ処理にとても役立ちます。",[48,4846,4847,4848,4851],{},"あとは",[155,4849,4850],{},"text.blend","ファイルを開いて結果を確認するだけです：",[72,4853,4855],{"className":4854},[34,75],[77,4856],{"src":4857,"className":4858,"alt":12,"loading":82,"width":83,"height":4537,"srcSet":4859,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-eab235c1-3513-4b9d-9f89-8a4d7c1cd122.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-eab235c1-3513-4b9d-9f89-8a4d7c1cd122.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-eab235c1-3513-4b9d-9f89-8a4d7c1cd122.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-eab235c1-3513-4b9d-9f89-8a4d7c1cd122.png 1600w",[48,4861,4862,4863,4866],{},"また、特定の",[155,4864,4865],{},".blend","ファイルを開き、そのコンテキスト内でスクリプトを実行することもできます：",[152,4868,4869],{},[155,4870,4872],{"className":4871},[175],"bpy.ops.wm.open_mainfile(filepath='my_scene.blend')",[48,4874,4875,4876,4879],{},"まず",[155,4877,4878],{},"my_scene.blend","を読み込み、その後に残りのスクリプトをそれに対して実行します。",[48,4881,4882],{},"場合によっては、独自の引数を渡したいこともあります：",[152,4884,4885],{},[155,4886,4888],{"className":4887},[158],"python3 args.py – --text \"CLI Hello\"",[48,4890,4891],{},[125,4892],{},[48,4894,4895,4898],{},[155,4896,4897],{},"args.py","の中では、このようにして引数にアクセスできます：",[152,4900,4901,4911],{},[155,4902,3445,4904],{"className":4903},[175],[48,4905,4906,4907,4910],{},"argv = sys.argv\nargv = argv",[263,4908,4909],{},"argv.index(\"--\") + 1:","  # get args after --",[48,4912,4913],{},[155,4914,4916],{"className":4915},[175],"print(\"Custom args:\", argv)",[48,4918,4919],{},"基本はここまでですが、まだまだ発見できることはたくさんあります。",[61,4921],{},[64,4923,4925],{"id":4924},"_4-scripting-modules-explained",[120,4926,4927],{},"4. スクリプトモジュールを解説",[48,4929,4930],{},"Blenderは、さまざまなモジュールを通じてスクリプト機能を公開しています。それぞれのモジュールが何をするのかを理解すると、何をスクリプトできるのか、そしてドキュメントをどう検索してコード化するかがわかってきます。",[48,4932,4933,4934,4936],{},"まず、コアとなる",[155,4935,2155],{},"モジュールです：",[212,4938,4939,4951,4966,4975,4988,5007,5019,5031,5047],{},[215,4940,4941,4947,4948,4950],{},[120,4942,4943,4946],{},[155,4944,4945],{},"bpy.context","（コンテキストアクセス）"," - Blenderの現在の状態（アクティブオブジェクト、シーン、モード、選択中のオブジェクトなど）に関する情報を提供します。たとえば",[155,4949,4680],{},"でアクティブオブジェクトが取得できます。",[215,4952,4953,4959,4960,4965],{},[120,4954,4955,4958],{},[155,4956,4957],{},"bpy.data","（データアクセス）"," - メッシュ、オブジェクト、マテリアル、カメラなど、Blenderのデータブロックに直接アクセスできます。例：",[155,4961,4962,4963],{},"bpy.data.objects",[263,4964,2693],{},"でCubeオブジェクトを取得します。",[215,4967,4968,4974],{},[120,4969,4970,4973],{},[155,4971,4972],{},"bpy.msgbus","（メッセージバス）"," - Blenderのデータの変更を監視し、フレーム変更イベントへの購読のようなコールバックをトリガーするためのpub/subシステムです。",[215,4976,4977,4983,4984,4987],{},[120,4978,4979,4982],{},[155,4980,4981],{},"bpy.ops","（オペレーター）"," - オブジェクトの追加、削除、レンダリングといったUI操作を模倣する関数を公開します。例：",[155,4985,4986],{},"bpy.ops.mesh.primitive_cube_add()","でキューブを追加します。",[215,4989,4990,4996,4997,658,5000,658,5003,5006],{},[120,4991,4992,4995],{},[155,4993,4994],{},"bpy.types","（タイプ）"," - 拡張やカスタマイズのために、Blenderのデータのコアクラス（例：",[155,4998,4999],{},"Object",[155,5001,5002],{},"Mesh",[155,5004,5005],{},"Material","）を定義し、カスタムパネルやオペレーターを作成できます。",[215,5008,5009,5015,5016,600],{},[120,5010,5011,5014],{},[155,5012,5013],{},"bpy.utils","（ユーティリティ）"," - クラス登録、アドオン処理、システムのパスアクセスなどのためのヘルパー関数を提供します。例：",[155,5017,5018],{},"bpy.utils.register_class(MyOperator)",[215,5020,5021,5027,5028,600],{},[120,5022,5023,5026],{},[155,5024,5025],{},"bpy.path","（パスユーティリティ）"," - 相対パスの解決や絶対パスの作成など、ファイルパスを扱うためのツールです。例：",[155,5029,5030],{},"bpy.path.abspath(\"//textures/wood.png\")",[215,5032,5033,5039,5040,4698,5043,5046],{},[120,5034,5035,5038],{},[155,5036,5037],{},"bpy.app","（アプリケーションデータ）"," - バージョン、ビルド情報、実行モードなど、Blender自身に関する情報を提供します。例：",[155,5041,5042],{},"bpy.app.version",[155,5044,5045],{},"(3, 6, 2)","を返します。",[215,5048,5049,5055,5056,600],{},[120,5050,5051,5054],{},[155,5052,5053],{},"bpy.props","（プロパティ定義）"," - オペレーター、パネル、アドオンのために、数値、文字列、列挙型などのカスタムプロパティを定義するのに使われます。例：",[155,5057,5058],{},"my_prop: bpy.props.IntProperty(name=\"My Number\")",[48,5060,5061],{},"次に、さらに専門的なライブラリもあります：",[212,5063,5064,5073,5086,5095,5107,5116,5125,5134,5145,5154,5163,5172],{},[215,5065,5066,5072],{},[120,5067,5068,5071],{},[155,5069,5070],{},"aud","（オーディオシステム）"," - サウンドの再生、ファイルの読み込み、オーディオのミキシングのためのBlenderのオーディオライブラリです。例：Pythonで直接Blenderに.wavファイルを再生します。",[215,5074,5075,5081,5082,5085],{},[120,5076,5077,5080],{},[155,5078,5079],{},"bgl","（OpenGLラッパー）"," - カスタム3Dビューポート描画のための低レベルOpenGLラッパー（",[155,5083,5084],{},"gpu","に置き換えられています）。たとえばカスタムオーバーレイを描画するために使います。",[215,5087,5088,5094],{},[120,5089,5090,5093],{},[155,5091,5092],{},"bl_math","（追加の数学関数）"," - 補間、距離計算、ジオメトリ操作などのための追加の数学ヘルパー。たとえば点同士の距離を計算します。",[215,5096,5097,5103,5104,600],{},[120,5098,5099,5102],{},[155,5100,5101],{},"blf","（フォント描画）"," - ビューポートオーバーレイやパネル内でテキストを描画するためのBlenderのフォント描画モジュールです。例：",[155,5105,5106],{},"blf.draw(font_id, \"Hello World\")",[215,5108,5109,5115],{},[120,5110,5111,5114],{},[155,5112,5113],{},"bmesh","（BMeshモジュール）"," - プロシージャルモデリングやトポロジー操作のために、Blenderのメッシュ編集システムへ直接低レベルにアクセスできます。例：編集モードで頂点や面を作成または変更する。",[215,5117,5118,5124],{},[120,5119,5120,5123],{},[155,5121,5122],{},"bpy_extras","（追加ユーティリティ）"," - インポート/エクスポート対応、数学の変換、view3dユーティリティなどのヘルパー関数を含みます。例：座標変換を簡略化します。",[215,5126,5127,5133],{},[120,5128,5129,5132],{},[155,5130,5131],{},"freestyle","（Freestyleモジュール）"," - 写真のようなレンダリングではないエッジ描画のための、BlenderのFreestyleラインレンダリングを制御します。例：ラインスタイルや可視性ルールの調整。",[215,5135,5136,5141,5142,5144],{},[120,5137,5138,5140],{},[155,5139,5084],{},"（GPUモジュール）"," - カスタムシェーダーやビューポートオーバーレイを可能にする最新のGPU描画API（",[155,5143,5079],{},"の後継）。例：カスタムGLSLシェーダーで描画する。",[215,5146,5147,5153],{},[120,5148,5149,5152],{},[155,5150,5151],{},"gpu_extras","（GPUユーティリティ）"," - 完全なGLSLコードなしで図形描画を簡単にするためのGPU描画ヘルパー関数。例：シンプルな長方形を描画する。",[215,5155,5156,5162],{},[120,5157,5158,5161],{},[155,5159,5160],{},"idprop.types","（IDプロパティアクセス）"," - 辞書/配列形式でBlenderのカスタムIDプロパティに構造化されたアクセスを提供します。例：オブジェクト上のカスタムメタデータを操作する。",[215,5164,5165,5171],{},[120,5166,5167,5170],{},[155,5168,5169],{},"imbuf","（画像バッファ）"," - 画像バッファを扱い、読み込み、保存、ピクセルレベルの操作を可能にします。例：プロシージャルな画像生成。",[215,5173,5174,1490,5180,658,5183,658,5186,5189,5190,600],{},[120,5175,5176,5179],{},[155,5177,5178],{},"mathutils","（数学タイプ & ユーティリティ）",[155,5181,5182],{},"Vector",[155,5184,5185],{},"Matrix",[155,5187,5188],{},"Quaternion","、および幾何ユーティリティを提供するBlenderの数学ライブラリ。例：",[155,5191,5192],{},"Vector((1,0,0)).cross(Vector((0,1,0))) → (0,0,1)",[61,5194],{},[64,5196,5197],{"id":507},[120,5198,508],{},[48,5200,5201],{},"PythonによるBlenderスクリプトは、ワークフローを拡張し、パーソナライズするための最も強力な方法の一つです。",[48,5203,5204,5205,5207],{},"この記事では、スクリプトの作成と実行方法、3D空間で最初の「Hello World」を表示する方法、そして",[155,5206,2155],{},"モジュールを使ってBlenderを思い通りに動かす方法を見てきました。",[48,5209,5210],{},"一見するとスクリプトは難しそうに感じるかもしれませんが、見てきたように、ほんの数行でもまったく新しい可能性への扉が開きます！",[48,5212,5213],{},"あとはあなたの番です。退屈な作業は自動化し、制作スタジオのパイプライン用のツールは最初から作り上げましょう。できます！",[31,5215,5217,5220],{"className":5216},[34,35,36],[31,5218,524],{"className":5219},[40],[31,5221,5223,5224,5227],{"className":5222},[45],"アニメーションの制作プロセスについてさらに学ぶには ",[94,5225,961],{"href":531,"rel":5226},[533],"！ 私たちはベストプラクティスを共有する1,000人以上の専門家とつながっており、時には対面イベントも企画しています。ぜひあなたを歓迎したいです！😊",[31,5229,5231],{"className":5230},[34,539,540],[94,5232,546],{"href":531,"className":5233},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":5235},[5236,5237,5238,5239,5240,5241,5242],{"id":4423,"depth":548,"text":4426},{"id":4458,"depth":548,"text":4461},{"id":4515,"depth":548,"text":4518},{"id":4596,"depth":548,"text":4599},{"id":4825,"depth":548,"text":4828},{"id":4924,"depth":548,"text":4927},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1760548425425-e42e77fa38f1?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDd8fCUyMHNjcmlwdGluZ3xlbnwwfHx8fDE3NjA2MTMxODl8MA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":5245,"featured_at":561,"visibility":562},"2026-02-20T06:04:03.000+01:00","/blog-i18n/ja/blender-scripting-animation","2025-10-21T10:00:42.000+02:00",{"title":4397,"description":12},"blender-scripting-animation","blog-i18n/ja/blender-scripting-animation/index",[5252,5253],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1844,"name":1845,"slug":1846,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1847},"NijcIXb7bCm7ihcnD1FGpArXKjDyaWOvCTdNCWywkhE",{"id":5256,"title":5257,"authors":5258,"body":5260,"description":12,"extension":557,"feature_image":5985,"html":7,"meta":5986,"navigation":13,"path":5988,"published_at":5989,"seo":5990,"slug":5991,"stem":5992,"tags":5993,"__hash__":5996,"updated_at":5987,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/blender-scripting-geometry-nodes-2/index.md","BlenderでPythonを使ってGeometry Nodesをスクリプトする方法（2026）",[5259],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":5261,"toc":5969},[5262,5273,5276,5279,5282,5288,5290,5296,5299,5302,5305,5308,5334,5336,5342,5345,5356,5363,5365,5371,5374,5417,5422,5432,5434,5440,5443,5453,5461,5468,5475,5477,5483,5486,5489,5495,5502,5508,5511,5517,5520,5532,5546,5552,5562,5568,5575,5581,5584,5590,5628,5634,5643,5657,5679,5685,5688,5694,5701,5707,5710,5764,5808,5811,5899,5902,5912,5915,5923,5925,5929,5932,5938,5946,5949,5963],[31,5263,5265,5269],{"className":5264},[34,35,36],[31,5266,5268],{"className":5267},[40],"🐍",[31,5270,5272],{"className":5271},[45],"手作業でノードを配線するよりも、コードでノードを生成すると、手続き的モデリングははるかに強力になります。",[48,5274,5275],{},"Geometry Nodesは信じられないほど優れたBlenderの機能ですが、BlenderのPython APIでも、他のデータブロックと同じようにGeometry Nodesをスクリプトできることをご存じでしたか？",[48,5277,5278],{},"ノードを作成し、パラメータを設定し、プログラム的に接続することで、数行のコードだけでシーン生成を自動化したり、カスタムツールを作ったり、手作業で何十個ものノードを配線する代わりに、モデルのプロトタイプを素早く作成したりできるようになります。",[48,5280,5281],{},"このチュートリアルでは、Pythonスクリプトだけでジオメトリノードのセットアップをすべて作成する方法を学びます。新しいノードツリーを構築するところから、それをオブジェクトに割り当てるところまで、Blenderのスクリプトエディタにそのまま貼り付けられる明確な例を使って、全手順を解説します。",[48,5283,5284,5285,3101],{},"見逃していた場合は、まず",[94,5286,5287],{"href":1015},"Blenderスクリプトの入門",[61,5289],{},[64,5291,5293],{"id":5292},"why-script-geometry-nodes",[120,5294,5295],{},"なぜGeometry Nodesをスクリプトするのか？",[48,5297,5298],{},"BlenderのGeometry Nodesエディタは、手続き的ツールを作るための優れたビジュアルシステムです。直感的で柔軟性が高く、使い方を掴めば実験もしやすいです。とはいえ、プロジェクトが複雑になってくると、大きなノードネットワークを手作業で管理するのは面倒になり、特に多数の3Dモデリングパイプライン全体で再利用する必要がある場合は、保守が難しくなります。",[48,5300,5301],{},"スクリプトを使うと、ノードを自動生成・変更・接続できます。同じセットアップを複数のプロジェクトで毎回作り直す代わりに、スクリプトを書いておけば必要なときにいつでも再利用でき、時間を節約したり、アニメーションをより一貫したものにしたりできます。",[48,5303,5304],{},"スクリプトされたノードセットアップは、単一の.blendファイルに紐づきません。コードの一部と同じように保存でき、バージョン管理でき、共有もできます。これにより、さまざまなプロジェクトで再利用したり、他のアーティストや開発者と共有したりできる手続き的ツールのライブラリを作りやすくなります。",[48,5306,5307],{},"では、いくつかのコードスニペットで、スクリプトが実際にどのように機能するのか見てみましょう。",[31,5309,5311,5314],{"className":5310},[34,35,108],[31,5312,112],{"className":5313},[40],[31,5315,5317,5321,5323,5325,5326,5328,134,5330],{"className":5316},[45],[117,5318,5319],{},[120,5320,2651],{"style":122},[125,5322],{},[125,5324],{},"このガイドで紹介されている例の統合の完全なソースコードは、GitHub上で確認できます：",[125,5327],{},[125,5329],{},[94,5331,5333],{"href":5332},"https://github.com/cgwire/blender-scripting-geometry-nodes?ref=blog.cg-wire.com","https://github.com/cgwire/blender-scripting-geometry-nodes",[61,5335],{},[64,5337,5339],{"id":5338},"_1-creating-a-new-node-tree",[120,5340,5341],{},"1. 新しいノードツリーを作成する",[48,5343,5344],{},"すべてのGeometry Nodesのセットアップはノードツリーとして始まり、ノードとそれらの接続を保持します。このようなツリーは、BlenderのデータAPIを使ってPythonから作成できます：",[152,5346,5347,5350],{},[155,5348,2684],{"className":5349},[175],[48,5351,5352],{},[155,5353,5355],{"className":5354},[175],"node_tree = bpy.data.node_groups.new(\"MyGeoNodesTree\", 'GeometryNodeTree')",[48,5357,5358,5359,5362],{},"この",[155,5360,5361],{},"node_tree","を、すべての手続き的ロジックを保持するデジタルキャンバスだと考えると分かりやすいです。作成したら、ノードを追加し、接続し、プロパティをBlenderのグラフィカルユーザーインターフェースと同じように設定できます。",[61,5364],{},[64,5366,5368],{"id":5367},"_2-add-nodes-and-connect-them",[120,5369,5370],{},"2. ノードを追加して接続する",[48,5372,5373],{},"次に、いくつかの基本ノードを追加しましょう。Input Geometryノード、Subdivision Surfaceノード、Group Outputノードを作成し、接続してから、その結果をキューブに適用します。",[152,5375,5376,5411],{},[155,5377,5379,5380,5383,5386,5391,5407],{"className":5378},[175],"# ADD NODES\ngeo_input = node_tree.interface.new_socket(\n    name=\"Geometry\",\n    in_out='INPUT',\n    socket_type='NodeSocketGeometry'\n)\ngeo_output = node_tree.interface.new_socket(\n    name=\"Geometry\",\n    in_out='OUTPUT',\n    socket_type='NodeSocketGeometry'\n)",[48,5381,5382],{},"input_node = node_tree.nodes.new(\"NodeGroupInput\")\nsubdivide_node = node_tree.nodes.new(\"GeometryNodeSubdivideMesh\")\noutput_node = node_tree.nodes.new(\"NodeGroupOutput\")",[48,5384,5385],{},"input_node.location = (-300, 0)\nsubdivide_node.location = (0, 0)\noutput_node.location = (300, 0)",[5387,5388,5390],"h1",{"id":5389},"link-nodes","LINK NODES",[48,5392,5393,5394,5397,5398,5401,5402,5404,5405,2098],{},"node_tree.links.new(input_node.outputs",[263,5395,5396],{},"'Geometry'",", subdivide_node.inputs",[263,5399,5400],{},"'Mesh'",")\nnode_tree.links.new(subdivide_node.outputs",[263,5403,5400],{},", output_node.inputs",[263,5406,5396],{},[5387,5408,5410],{"id":5409},"apply-to-current-object","APPLY TO CURRENT OBJECT",[48,5412,5413],{},[155,5414,5416],{"className":5415},[175],"obj = bpy.context.object\nmod = obj.modifiers.new(\"MyGeoNodesModifier\", \"NODES\")\nmod.node_group = node_tree",[48,5418,5419,5421],{},[125,5420],{},"このスクリプトを実行すると、適用した任意のジオメトリをサブディビジョンする、動作する（ただしシンプルな）ジオメトリノードのセットアップが得られます：",[72,5423,5425],{"className":5424},[34,75],[77,5426],{"src":5427,"className":5428,"alt":12,"loading":82,"width":5429,"height":5430,"srcSet":5431,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-de23dbc9-781f-4730-9a46-a6fec93c97a7.png",[81],1314,889,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-de23dbc9-781f-4730-9a46-a6fec93c97a7.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-de23dbc9-781f-4730-9a46-a6fec93c97a7.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-de23dbc9-781f-4730-9a46-a6fec93c97a7.png 1314w",[61,5433],{},[64,5435,5437],{"id":5436},"_3-set-parameters-and-link-geometry-to-objects",[120,5438,5439],{},"3. パラメータを設定し、ジオメトリをオブジェクトにリンクする",[48,5441,5442],{},"ノードのプロパティ経由で、パラメータを直接変更できます。たとえば、サブディビジョンレベルを上げて、このノードグループをオブジェクトに適用してみましょう：",[152,5444,5445],{},[155,5446,5448,5449,5452],{"className":5447},[175],"subdivide_node.inputs",[263,5450,5451],{},"'Level'",".default_value = 3",[72,5454,5456],{"className":5455},[34,75],[77,5457],{"src":5458,"className":5459,"alt":12,"loading":82,"width":5429,"height":5430,"srcSet":5460,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-18e48250-6a76-4eda-b14c-ce8065b78f9e.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-18e48250-6a76-4eda-b14c-ce8065b78f9e.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-18e48250-6a76-4eda-b14c-ce8065b78f9e.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-18e48250-6a76-4eda-b14c-ce8065b78f9e.png 1314w",[48,5462,5463,5464,5467],{},"入力に対する",[155,5465,5466],{},"default_value","を調整するのは、セットアップをパラメータ化する簡単な方法です。",[48,5469,5470,5471,1245],{},"利用可能なパラメータとタイプの完全な内訳については、",[94,5472,5474],{"href":5473},"https://docs.blender.org/api/current/bpy.types.Node.html?ref=blog.cg-wire.com","公式のBlender Python APIドキュメント",[61,5476],{},[64,5478,5480],{"id":5479},"_4-create-a-custom-%E2%80%9Ccube-crowd-generator%E2%80%9D-node-group-programmatically",[120,5481,5482],{},"4. カスタム「Cube Crowd Generator」ノードグループをプログラム的に作成する",[48,5484,5485],{},"ここまで、Geometry Nodesをプログラム的に定義する方法は分かりましたが、再利用可能なカスタムノードを作るにはどうすればよいのでしょうか？",[48,5487,5488],{},"では、表面上に多数のキューブを散布する小さな手続き的システムを構築する新しい例に取り組みましょう。このスクリプトは、表面を入力として受け取り、その上に点を散布し、それらの点をランダムにオフセットし、各点にキューブを配置（インスタンス）し、インスタンスを実際のジオメトリに変換し、最終的なメッシュを「Cubes」として出力する、Geometry Nodesのグループを作成します。",[1098,5490,5492],{"id":5491},"_1-create-a-new-node-group",[120,5493,5494],{},"1) 新しいノードグループを作成する",[48,5496,5497,5498,5501],{},"まず、Blenderで新しいGeometry Nodeグループを作成し、その名前を",[155,5499,5500],{},"\"CubeCrowdGenerator\"","にします。",[152,5503,5504],{},[155,5505,5507],{"className":5506},[175],"crowd_group = bpy.data.node_groups.new(\"CubeCrowdGenerator\", \"GeometryNodeTree\")",[48,5509,5510],{},"関数のように、このノードを後でGeometry Nodesモディファイアと一緒に任意のオブジェクトに取り付けられるようにしたいです。",[1098,5512,5514],{"id":5513},"_2-add-group-input-and-output-nodes-uientry-points",[120,5515,5516],{},"2) グループの入力・出力ノードを追加する（UI/エントリポイント）",[48,5518,5519],{},"いつも通り、キャンバス上に標準の入出力グループを配置します：",[152,5521,5522,5526],{},[155,5523,5525],{"className":5524},[175],"group_in = crowd_group.nodes.new(\"NodeGroupInput\")\ngroup_out = crowd_group.nodes.new(\"NodeGroupOutput\")",[48,5527,5528],{},[155,5529,5531],{"className":5530},[175],"group_in.location = (-600, 0)\ngroup_out.location = (600, 0)",[212,5533,5534,5543],{},[215,5535,5536,3017,5539,5542],{},[155,5537,5538],{},"group_in",[155,5540,5541],{},"group_out","は、Geometry Nodesエディタ上で表示されるノードグループのソケットです。",[215,5544,5545],{},"スクリプトは、グラフが読みやすくなるように、それらの位置も配置します。",[1098,5547,5549],{"id":5548},"_3-define-the-group-interface-what-the-group-acceptsreturns",[120,5550,5551],{},"3) グループインターフェースを定義する（何を受け取り、何を返すか）",[48,5553,5554,5557,5558,5561],{},[120,5555,5556],{},"入力ソケット「Surface」","を公開して、そこに埋め込みたいメッシュ（例：プレーン）を差し込みます。そして、結果として生成されるジオメトリを返す",[120,5559,5560],{},"出力ソケット「Cubes」","を用意する必要があります。",[152,5563,5564],{},[155,5565,5567],{"className":5566},[175],"interface = crowd_group.interface\ninterface.new_socket(name=\"Surface\", in_out=\"INPUT\", socket_type=\"NodeSocketGeometry\")\ninterface.new_socket(name=\"Cubes\", in_out=\"OUTPUT\", socket_type=\"NodeSocketGeometry\")",[48,5569,5570,5571,5574],{},"実際には、このノードグループをオブジェクトに追加するとき、その表面（オブジェクトの元のジオメトリ）を",[155,5572,5573],{},"Surface","に接続することになります。",[1098,5576,5578],{"id":5577},"_4-create-the-internal-nodes-the-building-blocks",[120,5579,5580],{},"4) 内部ノード（構成要素）を作成する",[48,5582,5583],{},"次に、実際の内部ロジックを作っていきます：",[152,5585,5586],{},[155,5587,5589],{"className":5588},[175],"distribute = crowd_group.nodes.new(\"GeometryNodeDistributePointsOnFaces\")\nrand_vec = crowd_group.nodes.new(\"FunctionNodeRandomValue\")\nset_pos = crowd_group.nodes.new(\"GeometryNodeSetPosition\")\ncube = crowd_group.nodes.new(\"GeometryNodeMeshCube\")\ninstance = crowd_group.nodes.new(\"GeometryNodeInstanceOnPoints\")\nrealize = crowd_group.nodes.new(\"GeometryNodeRealizeInstances\")",[212,5591,5592,5598,5604,5610,5616,5622],{},[215,5593,5594,5597],{},[120,5595,5596],{},"GeometryNodeDistributePointsOnFaces",": 入力サーフェス上に点を作成します（点の数や分布を制御します）。",[215,5599,5600,5603],{},[120,5601,5602],{},"FunctionNodeRandomValue（Float Vector）",": 各点ごとに使う、オフセット用のランダムな3Dベクトルを生成します。",[215,5605,5606,5609],{},[120,5607,5608],{},"GeometryNodeSetPosition",": ベクトル（ランダムオフセット）により、各点を移動します。",[215,5611,5612,5615],{},[120,5613,5614],{},"GeometryNodeMeshCube",": インスタンスとして使われるキューブメッシュを生成します。",[215,5617,5618,5621],{},[120,5619,5620],{},"GeometryNodeInstanceOnPoints",": 各点にキューブを配置します。これは実際のジオメトリを作るわけではなく、元のキューブの安価なインスタンスを作るだけです。",[215,5623,5624,5627],{},[120,5625,5626],{},"GeometryNodeRealizeInstances",": インスタンスを実際のメッシュジオメトリに変換し、1つのメッシュとして出力できるようにします。",[1098,5629,5631],{"id":5630},"_5-configure-the-random-vector-node",[120,5632,5633],{},"5) ランダムベクトルノードを設定する",[48,5635,5636,5639,5640,5642],{},[155,5637,5638],{},"Random Value","ノードを、3成分のベクトル",[120,5641,1934],{},"として返すように設定し、3D空間内で生成されたキューブをオフセットするために使います：",[152,5644,5645],{},[155,5646,5648,5649,5652,5653,5656],{"className":5647},[175],"rand_vec.data_type = \"FLOAT_VECTOR\"\nrand_vec.inputs",[263,5650,5651],{},"\"Min\"",".default_value = (-0.5, -0.5, 0.0)\nrand_vec.inputs",[263,5654,5655],{},"\"Max\"",".default_value = (0.5, 0.5, 0.5)",[212,5658,5659,5676],{},[215,5660,5661,3017,5664,5667,5668,5671,5672,5675],{},[155,5662,5663],{},"Min",[155,5665,5666],{},"Max","は各成分の範囲を定義します。たとえばXは",[155,5669,5670],{},"-0.5","から",[155,5673,5674],{},"0.5","の間になります。",[215,5677,5678],{},"結果：各点にわずかに異なるオフセットが割り当てられるため、キューブが互いの上に完全に重なって配置されることはありません。",[1098,5680,5682],{"id":5681},"_6-node-layout-ui-only",[120,5683,5684],{},"6) ノードレイアウト（UIのみ）",[48,5686,5687],{},"Blenderでワークフローを確認したいときに分かりやすいように、内部ノードを配置します：",[152,5689,5690],{},[155,5691,5693],{"className":5692},[175],"distribute.location = (-400, 0)\nrand_vec.location = (-200, -200)\nset_pos.location = (-100, 0)\ninstance.location = (100, 0)\ncube.location = (-400, -200)\nrealize.location = (300, 0)",[48,5695,5696,5697,5700],{},"これらの",[155,5698,5699],{},"location","の割り当ては、ノードエディタ上での見た目の配置だけに影響します。グラフが行う処理内容には影響しません。",[1098,5702,5704],{"id":5703},"_7-wire-the-nodes-together",[120,5705,5706],{},"7) ノードをつなぐ",[48,5708,5709],{},"最後に、データの流れを定義します：",[152,5711,5712],{},[155,5713,5715,5716,5719,5720,5723,5724,5727,5728,5731,5732,5727,5735,5738,5739,5741,5742,5744,5745,5741,5747,5750,5751,5754,5755,5757,5758,5760,5761,2098],{"className":5714},[175],"links.new(group_in.outputs",[263,5717,5718],{},"\"Surface\"",", distribute.inputs",[263,5721,5722],{},"\"Mesh\"",")\nlinks.new(distribute.outputs",[263,5725,5726],{},"\"Points\"",", set_pos.inputs",[263,5729,5730],{},"\"Geometry\"",")\nlinks.new(rand_vec.outputs",[263,5733,5734],{},"\"Value\"",[263,5736,5737],{},"\"Offset\"",")\nlinks.new(set_pos.outputs",[263,5740,5730],{},", instance.inputs",[263,5743,5726],{},")\nlinks.new(cube.outputs",[263,5746,5722],{},[263,5748,5749],{},"\"Instance\"",")\nlinks.new(instance.outputs",[263,5752,5753],{},"\"Instances\"",", realize.inputs",[263,5756,5730],{},")\nlinks.new(realize.outputs",[263,5759,5730],{},", group_out.inputs",[263,5762,5763],{},"\"Cubes\"",[1710,5765,5766,5772,5778,5784,5790,5796,5802],{},[215,5767,5768,5771],{},[120,5769,5770],{},"Surface → DistributePointsOnFaces",": 入力サーフェス（プレーン）が散布用の点を作るために使われます。",[215,5773,5774,5777],{},[120,5775,5776],{},"Points → SetPosition（Geometry）",": set positionは、移動されるジオメトリとして点を受け取ります。",[215,5779,5780,5783],{},[120,5781,5782],{},"RandomValue → SetPosition（Offset）",": 各点にランダムなベクトルのオフセットが付与されます。",[215,5785,5786,5789],{},[120,5787,5788],{},"SetPosition → InstanceOnPoints（Points）",": 移動された点が、インスタンスのアンカーポイントになります。",[215,5791,5792,5795],{},[120,5793,5794],{},"Cube Mesh → InstanceOnPoints（Instance）",": 各点にキューブのインスタンスが割り当てられます。",[215,5797,5798,5801],{},[120,5799,5800],{},"InstanceOnPoints → RealizeInstances",": インスタンスがメッシュジオメトリに変換されます。",[215,5803,5804,5807],{},[120,5805,5806],{},"RealizeInstances → Group Output（\"Cubes\"）",": 最終結果がグループ出力として利用可能になります。",[48,5809,5810],{},"これが、得られた完全なコードです：",[152,5812,5813,5865],{},[155,5814,1680,5816,5820,5822,5826,5828,5830,5834,5836,5840,5843,5847,5855,5859,5861],{"className":5815},[175],[5387,5817,5819],{"id":5818},"create-a-new-geometry-node-group","Create a new Geometry Node group",[48,5821,5507],{},[5387,5823,5825],{"id":5824},"create-inputoutput-nodes","Create input/output nodes",[48,5827,5525],{},[48,5829,5531],{},[5387,5831,5833],{"id":5832},"define-group-interface-sockets","Define group interface sockets",[48,5835,5567],{},[5387,5837,5839],{"id":5838},"create-internal-nodes","Create internal nodes",[48,5841,5842],{},"distribute = crowd_group.nodes.new(\"GeometryNodeDistributePointsOnFaces\")\ninstance = crowd_group.nodes.new(\"GeometryNodeInstanceOnPoints\")\ncube = crowd_group.nodes.new(\"GeometryNodeMeshCube\")\nrealize = crowd_group.nodes.new(\"GeometryNodeRealizeInstances\")\nset_pos = crowd_group.nodes.new(\"GeometryNodeSetPosition\")\nrand_vec = crowd_group.nodes.new(\"FunctionNodeRandomValue\")",[5387,5844,5846],{"id":5845},"configure-random-vector-node","Configure random vector node",[48,5848,5648,5849,5851,5852,5854],{},[263,5850,5651],{},".default_value = (-0.5, -0.5, 0.0)  # minimum offset\nrand_vec.inputs",[263,5853,5655],{},".default_value = (0.5, 0.5, 0.5)  # maximum offset",[5387,5856,5858],{"id":5857},"layout-nodes","Layout nodes",[48,5860,5693],{},[5387,5862,5864],{"id":5863},"create-links","Create links",[48,5866,5867],{},[155,5868,5870,5871,5719,5873,5723,5875,5727,5877,5731,5879,5727,5881,5738,5883,5741,5885,5744,5887,5741,5889,5750,5891,5754,5893,5757,5895,5760,5897,2098],{"className":5869},[175],"links = crowd_group.links\nlinks.new(group_in.outputs",[263,5872,5718],{},[263,5874,5722],{},[263,5876,5726],{},[263,5878,5730],{},[263,5880,5734],{},[263,5882,5737],{},[263,5884,5730],{},[263,5886,5726],{},[263,5888,5722],{},[263,5890,5749],{},[263,5892,5753],{},[263,5894,5730],{},[263,5896,5730],{},[263,5898,5763],{},[48,5900,5901],{},"次に、このスクリプトをスクリプトワークスペースにコピー＆ペーストして実行すれば、ジオメトリノードのワークスペースからこのカスタムノードを追加できるようになります：",[72,5903,5905],{"className":5904},[34,75],[77,5906],{"src":5907,"className":5908,"alt":12,"loading":82,"width":5909,"height":5910,"srcSet":5911,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-d4ff8437-efb6-43b0-b45d-a54fce0b74b6.png",[81],1430,920,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-d4ff8437-efb6-43b0-b45d-a54fce0b74b6.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-d4ff8437-efb6-43b0-b45d-a54fce0b74b6.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-d4ff8437-efb6-43b0-b45d-a54fce0b74b6.png 1430w",[48,5913,5914],{},"それが中で何をしているのか確認するには、それをダブルクリックしてノードグループを開きます：",[72,5916,5918],{"className":5917},[34,75],[77,5919],{"src":5920,"className":5921,"alt":12,"loading":82,"width":5909,"height":5910,"srcSet":5922,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-679df6c4-2877-4419-8b79-4758df98290a.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-679df6c4-2877-4419-8b79-4758df98290a.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-679df6c4-2877-4419-8b79-4758df98290a.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-679df6c4-2877-4419-8b79-4758df98290a.png 1430w",[61,5924],{},[64,5926,5927],{"id":507},[120,5928,2530],{},[48,5930,5931],{},"数十行のコードだけで、手作業で組み立てるのにずっと時間がかかるようなGeometry Nodesのセットアップをスクリプト化できます。この記事では、Geometry Nodeツリーの作成、ノードの追加と接続をプログラム的に行うこと、パラメータを制御してノードツリーをオブジェクトに割り当てること、そして完全な手続き的システムを構築する方法を学びました。",[48,5933,5934,5935,3101],{},"例を自分で試すには、",[94,5936,5937],{"href":5332},"Githubのコードリポジトリ",[72,5939,5941],{"className":5940},[34,75],[77,5942],{"src":5943,"className":5944,"alt":12,"loading":82,"width":5429,"height":5430,"srcSet":5945,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-db488d5a-7ab5-4471-a904-0926b1fa7d11.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-db488d5a-7ab5-4471-a904-0926b1fa7d11.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-db488d5a-7ab5-4471-a904-0926b1fa7d11.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-db488d5a-7ab5-4471-a904-0926b1fa7d11.png 1314w",[48,5947,5948],{},"このアプローチにより、ツール開発からジェネレーティブアートまで、無限の自動化の可能性が開かれます。 ",[31,5950,5952,5955],{"className":5951},[34,35,36],[31,5953,524],{"className":5954},[40],[31,5956,5958,5959,5962],{"className":5957},[45],"アニメーションのプロセスについてもっと学ぶには ",[94,5960,961],{"href":531,"rel":5961},[533],"！私たちはベストプラクティスを共有する1,000人以上の専門家とつながっており、時には現地イベントも企画しています。ぜひようこそお迎えしたいです！😊",[31,5964,5966],{"className":5965},[34,539,540],[94,5967,546],{"href":531,"className":5968},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":5970},[5971,5972,5973,5974,5975,5984],{"id":5292,"depth":548,"text":5295},{"id":5338,"depth":548,"text":5341},{"id":5367,"depth":548,"text":5370},{"id":5436,"depth":548,"text":5439},{"id":5479,"depth":548,"text":5482,"children":5976},[5977,5978,5979,5980,5981,5982,5983],{"id":5491,"depth":1820,"text":5494},{"id":5513,"depth":1820,"text":5516},{"id":5548,"depth":1820,"text":5551},{"id":5577,"depth":1820,"text":5580},{"id":5630,"depth":1820,"text":5633},{"id":5681,"depth":1820,"text":5684},{"id":5703,"depth":1820,"text":5706},{"id":507,"depth":548,"text":2530},"https://images.unsplash.com/photo-1675044794037-9262cedb6d5d?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fGJsZW5kZXIlMjBnZW9tZXRyeSUyMG5vZGVzfGVufDB8fHx8MTc2MzM2OTc0N3ww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":5987,"featured_at":561,"visibility":562},"2026-02-20T06:04:04.000+01:00","/blog-i18n/ja/blender-scripting-geometry-nodes-2","2025-11-17T10:13:21.000+01:00",{"title":5257,"description":12},"blender-scripting-geometry-nodes-2","blog-i18n/ja/blender-scripting-geometry-nodes-2/index",[5994,5995],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1844,"name":1845,"slug":1846,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1847},"WVSnZV3jzjNitPY-mUio9-NjOp_lAoEg52z_Z9mAqoc",{"id":5998,"title":5999,"authors":6000,"body":6002,"description":12,"extension":557,"feature_image":6463,"html":7,"meta":6464,"navigation":13,"path":6465,"published_at":6466,"seo":6467,"slug":6468,"stem":6469,"tags":6470,"__hash__":6472,"updated_at":5987,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/blender-scripting-geometry-nodes/index.md","Blender 2026におけるジオメトリーノード入門ガイド",[6001],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":6003,"toc":6442},[6004,6014,6017,6020,6022,6028,6031,6040,6043,6045,6051,6058,6061,6085,6087,6093,6096,6104,6112,6115,6118,6150,6158,6161,6164,6167,6169,6175,6178,6181,6184,6190,6193,6196,6202,6205,6208,6214,6217,6220,6230,6236,6239,6242,6251,6257,6260,6263,6269,6272,6275,6281,6284,6287,6297,6303,6306,6309,6315,6318,6321,6327,6330,6336,6339,6342,6348,6351,6354,6360,6363,6366,6372,6375,6378,6399,6401,6405,6408,6411,6422,6436],[31,6005,6007,6010],{"className":6006},[34,35,36],[31,6008,1862],{"className":6009},[40],[31,6011,6013],{"className":6012},[45],"手作業でシーンを作り直すのは、もう2010年のやり方です。ジオメトリーノードなら、精度高くBlenderプロジェクトを自動化し、ランダム化し、制御できます——数時間の手作業によるモデリングを、手続き型マジックの数分へと変えてくれるのです。",[48,6015,6016],{},"Blenderでジオメトリを何度も手作業で複製したり、形を作り替えたり、繰り返しの動きをアニメーションしたりするために何時間も費やすのは楽しくありません。そんな作業は、たとえば「同じことを何度も繰り返す必要があるが、違いはほんの少しだけ」というタイプのワークフローです。",[48,6018,6019],{},"しかし、手続き的な効果を作るための、より賢く速い方法があります。それがジオメトリーノードです。最初は難しそうで習得に時間がかかるように見えるかもしれませんが、この記事の最後まで読めば、ジオメトリーノードが何か、なぜ重要なのか、そして自分のBlenderプロジェクトでどう使い始めるかが分かるようになります。",[61,6021],{},[64,6023,6025],{"id":6024},"what-are-geometry-nodes",[120,6026,6027],{},"ジオメトリーノードとは？",[48,6029,6030],{},"ジオメトリーノードは、Blenderの「手続き的にモデルを作成・操作するための方法」です。メッシュオブジェクトを直接編集する代わりに、インスタンス化、変換、オブジェクトのばらまき（散布）などの処理を定義する、見た目のノードをつなぎ合わせます。これは非破壊で、モジュールとして構築できます。",[72,6032,6034],{"className":6033},[34,75],[77,6035],{"src":6036,"className":6037,"alt":12,"loading":82,"width":83,"height":6038,"srcSet":6039,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-b4252feb-7713-4df1-98ca-cc453b53d4ee.png",[81],830,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-b4252feb-7713-4df1-98ca-cc453b53d4ee.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-b4252feb-7713-4df1-98ca-cc453b53d4ee.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-b4252feb-7713-4df1-98ca-cc453b53d4ee.png 1600w",[48,6041,6042],{},"各ノードは小さな作業を行いますが、つなぎ合わせることで、非常に細かな結果を生み出せます。たとえば、ランダム化された何千本もの木で構成された森、アニメーションするパーティクルトレイル、あるいは建築的なパターンなどです。ジオメトリーノードなら一度作って、調整可能なパラメータで全てをコントロールできます。",[61,6044],{},[64,6046,6048],{"id":6047},"why-geometry-nodes-are-important",[120,6049,6050],{},"なぜジオメトリーノードが重要なのか",[48,6052,6053,6057],{},[94,6054,6056],{"href":6055},"https://blog.cg-wire.com/3d-modeling-animation/","従来のモデリング／アニメーションのワークフロー","は、多くの場合、時間のかかる手作業による調整に依存しており、変更やバリエーションのたびにモデルへ直接編集を行う必要があります。ジオメトリーノードは、このプロセスに「手続き的な制御」を導入することで革命を起こします。入力値、ランダム性、または数学的な関係性を通じて、モデルを動的に生成・変更できる仕組みです。",[48,6059,6060],{},"このアプローチには、いくつかの大きな利点があります。複雑なシーンをゼロから作り直さなくても、すぐに更新したりランダム化したりできるため、作業効率が上がります。また、パラメータは制作のどの段階でも調整できるので、パイプラインへの柔軟性も高まります。ジオメトリーノードは、大きな芝生のパッチを生成するような、手作業では難しい、あるいは不可能な複雑な形状、パターン、効果を生み出すための実験への扉を開きます。この機能は、群衆シミュレーションやリアルな自然環境のような大規模なモデリングに最適です。",[31,6062,6064,6067],{"className":6063},[34,35,4487],[31,6065,112],{"className":6066},[40],[31,6068,6070,6074,6076,6078,6079,6081,134,6083],{"className":6069},[45],[117,6071,6072],{},[120,6073,2651],{"style":122},[125,6075],{},[125,6077],{},"このガイドで紹介しているBlender–Kitsu連携のサンプルについて、完全なソースコードはGitHubで確認できます：",[125,6080],{},[125,6082],{},[94,6084,5333],{"href":5332},[61,6086],{},[64,6088,6090],{"id":6089},"adding-a-geometry-node",[120,6091,6092],{},"ジオメトリーノードを追加する",[48,6094,6095],{},"その概念は難しそうに見えるかもしれませんが、5分だけください。あなたの最初のジオメトリーノード設定を作ります。",[1710,6097,6098,6101],{},[215,6099,6100],{},"デフォルトのキューブがある新しいBlenderプロジェクトを開きます。",[215,6102,6103],{},"ジオメトリーノードのタブで、Newをクリックして新しいジオメトリーノードグループを作成します。",[72,6105,6107],{"className":6106},[34,75],[77,6108],{"src":6109,"className":6110,"alt":12,"loading":82,"width":5429,"height":5430,"srcSet":6111,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-6cd7bfd9-e7fd-4220-834e-c6260fa00949.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-6cd7bfd9-e7fd-4220-834e-c6260fa00949.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-6cd7bfd9-e7fd-4220-834e-c6260fa00949.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-6cd7bfd9-e7fd-4220-834e-c6260fa00949.png 1314w",[48,6113,6114],{},"これで、ジオメトリーノードエディタの作業領域に空のノードツリーが表示されます。デフォルトノードとして、Group Input と Group Output の2つが用意されているはずです。これはデータフローの「開始」と「終了」を表します：ジオメトリが入ってきて、修正されて、外へ出るのです。",[48,6116,6117],{},"設定を動かして見るには、最初のノードを追加するだけです：",[1710,6119,6120,6136,6147],{},[215,6121,6122,6125,6126,6125,6129,6125,6132,6135],{},[120,6123,6124],{},"Add"," → ",[120,6127,6128],{},"Geometry",[120,6130,6131],{},"Operations",[120,6133,6134],{},"Transform Geometry"," をクリックします。",[215,6137,6138,6125,6141,6125,6143,6146],{},[120,6139,6140],{},"Group Input",[120,6142,6134],{},[120,6144,6145],{},"Group Output"," を接続します。",[215,6148,6149],{},"Transformノード内で、移動（translation）やスケールの値を調整します。",[72,6151,6153],{"className":6152},[34,75],[77,6154],{"src":6155,"className":6156,"alt":12,"loading":82,"width":5429,"height":5430,"srcSet":6157,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-ea4b9476-8d89-4d56-bd6a-62dd751ba84d.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-ea4b9476-8d89-4d56-bd6a-62dd751ba84d.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-ea4b9476-8d89-4d56-bd6a-62dd751ba84d.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-ea4b9476-8d89-4d56-bd6a-62dd751ba84d.png 1314w",[48,6159,6160],{},"すぐに、ビューポート上でオブジェクトが移動したりリサイズされたりするのが見えるはずです。おめでとうございます。これであなたは、最初の手続き型モディファイアを作ったことになります！",[48,6162,6163],{},"ジオメトリーノードは、いくつかの大きなカテゴリに分かれています。各カテゴリはシーンの異なる側面を担当します。これらのカテゴリをツールボックスだと思ってください。形状の生成から、裏側のデータや数学の制御まで、作業の種類ごとに分かれているのです。",[48,6165,6166],{},"新しいワークフローで使うべきノードを見つけるために、さまざまなノードタイプを簡単に見ていきましょう：",[61,6168],{},[64,6170,6172],{"id":6171},"_1-input-nodes",[120,6173,6174],{},"1. Input Nodes（入力ノード）",[48,6176,6177],{},"入力ノードは、ノードツリーの出発点となる情報を提供します。ほかのノードがジオメトリを計算したり変換したりするために使える、位置、法線、インデックス、オブジェクト情報など、オブジェクトやシーンから既存のデータを取り込みます。",[48,6179,6180],{},"たとえば Input → Scene → Object info ノードを使うと、計算を行うために必要な、オブジェクトインスタンスに関するあらゆる情報が手に入ります。",[48,6182,6183],{},"新しいノードツリーを作ると、Blenderは常に、現在のシーン内のモデルのグループを表す新しい Input Group ノードを追加します。",[64,6185,6187],{"id":6186},"_2-output-nodes",[120,6188,6189],{},"2. Output Nodes（出力ノード）",[48,6191,6192],{},"出力ノードは、ノードシステムから何が「外へ出るか」を定義します。Blenderがレンダーしたり表示したりする最終的なジオメトリです。Group Output ノードが最も一般的で、ノードネットワーク全体の結果をビューポート上のオブジェクトへ戻して接続します。",[48,6194,6195],{},"ほかの専用の出力（シェーダセットアップのMaterial Outputなど）は、Blenderシステムの別の部分へデータを渡します。ジオメトリーノードでは、Output段階が「結果として表示されるジオメトリ、インスタンス、または属性」を決定します。",[64,6197,6199],{"id":6198},"_3-geometry-nodes",[120,6200,6201],{},"3. Geometry Nodes（ジオメトリーノード）",[48,6203,6204],{},"ジオメトリーノードは、ジオメトリ（つまりシーン内の実際の形状）を直接変更したり、組み合わせたり、生成したりします。",[48,6206,6207],{},"それらは手続き型モデリングの中核です。手で彫刻する代わりに、ジオメトリを自動生成するシステムを作れます。そして、基となるメッシュを壊さずに、後から調整もできます。",[64,6209,6211],{"id":6210},"_4-mesh-nodes",[120,6212,6213],{},"4. Mesh Nodes（メッシュノード）",[48,6215,6216],{},"メッシュノードは、メッシュ構造に対する細かな制御に焦点を当てます。つまり、ジオメトリを構成する頂点、エッジ、面です。特定のメッシュ構成要素へアクセスして変更したり、ジオメトリの種類を変換したりできます。",[48,6218,6219],{},"トポロジーを厳密に制御する必要があるときはメッシュノードを使いましょう。グリッドを作る、エッジループを操作する、既存メッシュから新しいトポロジーを生成する、といった手続き型モデリングのタスクに最適です。",[72,6221,6223],{"className":6222},[34,75],[77,6224],{"src":6225,"className":6226,"alt":12,"loading":82,"width":6227,"height":6228,"srcSet":6229,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-da4fe358-ac3b-482a-8641-6b0540c9d792.png",[81],947,897,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-da4fe358-ac3b-482a-8641-6b0540c9d792.png 600w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-da4fe358-ac3b-482a-8641-6b0540c9d792.png 947w",[64,6231,6233],{"id":6232},"_5-instance-nodes",[120,6234,6235],{},"5. Instance Nodes（インスタンスノード）",[48,6237,6238],{},"インスタンスノードは、オブジェクトのコピー（インスタンス）を作成し、サーフェス上やポイント上に散らします。Instance on Points や Realize Instances などのノードがこれを扱います。",[48,6240,6241],{},"インスタンシングはジオメトリーノードの中でも非常に強力な機能です。実際には1つのコピーだけをレンダーし、それを複数回参照することで、木・岩・パーティクルなど何千ものオブジェクトを複製してもシーンを重くしにくいからです。",[72,6243,6245],{"className":6244},[34,75],[77,6246],{"src":6247,"className":6248,"alt":12,"loading":82,"width":83,"height":6249,"srcSet":6250,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-1049c5fc-a3de-480a-b494-ed49a488af0c.png",[81],1085,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-1049c5fc-a3de-480a-b494-ed49a488af0c.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-1049c5fc-a3de-480a-b494-ed49a488af0c.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-1049c5fc-a3de-480a-b494-ed49a488af0c.png 1600w",[64,6252,6254],{"id":6253},"_6-attribute-nodes",[120,6255,6256],{},"6. Attribute Nodes（属性ノード）",[48,6258,6259],{},"属性ノードは、色、スケール、ポイントごとのランダム値のように、ジオメトリに取り付けられたカスタムプロパティを制御したり受け渡したりします。これらの属性は、変換、マテリアル、または効果の駆動に使えます。",[48,6261,6262],{},"属性によって、手続き型システムに「ばらつき」と「制御」を追加できます。散布されたオブジェクトの大きさをランダム化したり、パーティクルの色を別々にしたり、マテリアルの効果をジオメトリデータに結び付けたりできます。",[64,6264,6266],{"id":6265},"_7-utilities-and-fields",[120,6267,6268],{},"7. Utilities and Fields（ユーティリティとフィールド）",[48,6270,6271],{},"ユーティリティノードは、ジオメトリーネットワークの背後にあるロジックや計算を担当します。Math、Vector Math、Compare、Map Rangeのような処理が含まれ、プログラミング言語のように、ほかのノードの入力を処理・制御する用途で使われることが多いです。",[48,6273,6274],{},"これらはセットアップの「頭脳」として働き、関係性を作ったり、グラデーションを作ったり、値をランダム化したりします。",[64,6276,6278],{"id":6277},"_8-curve-nodes",[120,6279,6280],{},"8. Curve Nodes（カーブノード）",[48,6282,6283],{},"カーブノードは、ライン、スプライン、パスといったカーブベースのジオメトリで動作します。ケーブル、つる、道路、あるいは抽象的なモーションの軌跡を生成するのに役立ちます。Resample Curve、Curve to Mesh、Set Curve Radius のようなノードを使うと、カーブの形状、解像度、厚みを手続き的に調整できます。",[48,6285,6286],{},"カーブはインスタンシングを駆動することもでき、パスに沿ってオブジェクトを配置したり、時間経過に合わせて動きをアニメーションさせたりできます。",[72,6288,6290],{"className":6289},[34,75],[77,6291],{"src":6292,"className":6293,"alt":12,"loading":82,"width":6294,"height":6295,"srcSet":6296,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-6409cf07-26e7-4eb6-8e76-85e9a33a1581.png",[81],1142,936,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-6409cf07-26e7-4eb6-8e76-85e9a33a1581.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-6409cf07-26e7-4eb6-8e76-85e9a33a1581.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-6409cf07-26e7-4eb6-8e76-85e9a33a1581.png 1142w",[64,6298,6300],{"id":6299},"_9-grease-pencil-nodes",[120,6301,6302],{},"9. Grease Pencil Nodes（グリースペンシルノード）",[48,6304,6305],{},"グリースペンシルノードは、Blenderの2D描画システムをジオメトリーノードのワークフローに統合します。ストロークを手続き的に修正したり、描画をジオメトリに変換したり、ノイズ、押し出し、変形などの効果を2Dラインに適用したりできます。",[48,6307,6308],{},"これらのノードは、2Dアニメーションと手続き的なデザインの間のギャップを埋め、アーティストにモーション・グラフィックスをスタイライズする新しい方法や、2D/3Dのハイブリッドシーンを作る方法を提供します。",[64,6310,6312],{"id":6311},"_10-point-nodes",[120,6313,6314],{},"10. Point Nodes（ポイントノード）",[48,6316,6317],{},"ポイントノードは、ジオメトリ内の個々のポイントを操作します。散布、配置、インスタンスの変換に使われる、基本となる構成要素です。ポイントの追加、移動、回転ができるほか、各ポイントに色やスケールといった属性を割り当てることも可能です。",[48,6319,6320],{},"たとえば Distribute Points on Faces は、サーフェス上に均等またはランダムに配置されたポイントを生成し、それらを芝生やパーティクルといったインスタンスの配置位置として利用できます。",[64,6322,6324],{"id":6323},"_11-volume-nodes",[120,6325,6326],{},"11. Volume Nodes（ボリュームノード）",[48,6328,6329],{},"ボリュームノードは、霧、煙、または手続き的な密度フィールドのような体積データを作成・操作できるようにします。これらを使って3Dテクスチャを生成したり、雲の形を作ったり、密度に基づく効果でジオメトリを満たしたりできます。表面モデリングをはるかに超えた、空気感のある、または有機的な効果への道が開けます。",[64,6331,6333],{"id":6332},"_12-material-nodes",[120,6334,6335],{},"12. Material Nodes（マテリアルノード）",[48,6337,6338],{},"マテリアルノードは、マテリアルやシェーディングデータを割り当てたり、変更したりします。Set Material や Material Index ノードを使うと、属性、ランダムシード、またはモデルの領域に基づいて、異なるマテリアルを動的に適用できます。",[48,6340,6341],{},"たとえば、構造の一部を色分けしたり、散布されたオブジェクトに対してマテリアルを手続き的に割り当てたりするのが簡単になります。",[64,6343,6345],{"id":6344},"_13-texture-nodes",[120,6346,6347],{},"13. Texture Nodes（テクスチャノード）",[48,6349,6350],{},"テクスチャノードは、ジオメトリの変換や見た目のバリエーションを駆動できる手続き的なテクスチャをサンプル、あるいは生成します。グレースケールのマスク、ノイズパターン、グラデーションなどを提供でき、それらがスケール、ディスプレイスメント、色に影響します。",[48,6352,6353],{},"テクスチャデータと数学ノードや属性ノードを組み合わせることで、不均一な地形、波打つサーフェス、パターン化された分布に対して自然なランダム性を作れます。",[64,6355,6357],{"id":6356},"_14-group-nodes",[120,6358,6359],{},"14. Group Nodes（グループノード）",[48,6361,6362],{},"グループノードは、複数のノードをひとまとめにして、再利用できる単位としてまとめます。複雑なセットアップを整理し、ノードツリーをきれいに保つために重要です。グループの入出力でパラメータを公開すれば、それを調整可能にでき、結果として自分のカスタムセットアップを「新しいスーパー・ノード」に変えるようなものです。",[48,6364,6365],{},"自分のグループを作り始めると、あなたはただジオメトリーノードを使っているだけではありません。自分の手続き型ツールを作っているのです。",[64,6367,6369],{"id":6368},"_15-hair-nodes",[120,6370,6371],{},"15. Hair Nodes（ヘアノード）",[48,6373,6374],{},"ヘアノードは、手続き的なヘアやファーのシステムを生成、スタイリング、制御するために設計されています。ストランドの長さ、密度、グルーミング属性にアクセスできるため、草原のようなものからキャラクターの髪まで、あらゆるものをシミュレートできます。",[48,6376,6377],{},"これらのノードは、古いパーティクルベースのワークフローを置き換えるものであり、Blenderの新しいヘアシステムとシームレスに統合される、現代的な手続き型アプローチです。",[72,6379,6382,6388],{"className":6380},[34,75,6381],"kg-card-hascaption",[77,6383],{"src":6384,"className":6385,"alt":12,"loading":82,"width":83,"height":6386,"srcSet":6387,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-64d8cc68-468d-4294-8abb-2fafc2ac9d87.png",[81],916,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-64d8cc68-468d-4294-8abb-2fafc2ac9d87.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-64d8cc68-468d-4294-8abb-2fafc2ac9d87.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-64d8cc68-468d-4294-8abb-2fafc2ac9d87.png 1600w",[6389,6390,6391],"figcaption",{},[6392,6393,6394],"i",{},[655,6395,6398],{"className":6396,"style":122},[6397],"italic","Source: Blender Stack Exchange",[61,6400],{},[64,6402,6403],{"id":507},[120,6404,508],{},[48,6406,6407],{},"ジオメトリーノードは最初、抽象的で難しそうに見えるかもしれませんが、Blenderの中でもとてもワクワクする機能の1つです。ノードの組み合わせ方が分かってくると、手作業の編集ではなく、手続き的なロジックによって駆動されるアニメーション全体、環境、あるいはビジュアルエフェクトを生成できます。",[48,6409,6410],{},"ただし、全部を暗記する必要はありません。多くのジオメトリーノードのセットアップは、いくつかの主要ノードに依存しており、試しながら自然に使い慣れていきます。",[48,6412,6413,6417,6418,6421],{},[94,6414,6416],{"href":6415},"https://blog.cg-wire.com/","次の記事","では、さらに一歩進みます。",[94,6419,6420],{"href":1015},"スクリプトを使って自分専用のカスタム・ノードグループを作り","、制作ワークフローの複雑さを抑えつつ、ユニークなアニメーションパイプラインでエフェクトを自動化する方法を学びます。",[31,6423,6425,6428],{"className":6424},[34,35,36],[31,6426,524],{"className":6427},[40],[31,6429,6431,6432,6435],{"className":6430},[45],"アニメーション制作プロセスについてもっと知るには ",[94,6433,2559],{"href":531,"rel":6434},[533],"！私たちは、ベストプラクティスを共有する1,000人以上の専門家とつながっていて、ときどき対面イベントも企画しています。ぜひ私たちの仲間になってくださいね！ 😊",[31,6437,6439],{"className":6438},[34,539,540],[94,6440,546],{"href":531,"className":6441},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":6443},[6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,6455,6456,6457,6458,6459,6460,6461,6462],{"id":6024,"depth":548,"text":6027},{"id":6047,"depth":548,"text":6050},{"id":6089,"depth":548,"text":6092},{"id":6171,"depth":548,"text":6174},{"id":6186,"depth":548,"text":6189},{"id":6198,"depth":548,"text":6201},{"id":6210,"depth":548,"text":6213},{"id":6232,"depth":548,"text":6235},{"id":6253,"depth":548,"text":6256},{"id":6265,"depth":548,"text":6268},{"id":6277,"depth":548,"text":6280},{"id":6299,"depth":548,"text":6302},{"id":6311,"depth":548,"text":6314},{"id":6323,"depth":548,"text":6326},{"id":6332,"depth":548,"text":6335},{"id":6344,"depth":548,"text":6347},{"id":6356,"depth":548,"text":6359},{"id":6368,"depth":548,"text":6371},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1639322537504-6427a16b0a28?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDd8fGJsZW5kZXIlMjBnZW9tZXRyeSUyMG5vZGVzfGVufDB8fHx8MTc2Mjc1NzU1NXww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":5987,"featured_at":561,"visibility":562},"/blog-i18n/ja/blender-scripting-geometry-nodes","2025-11-10T10:00:00.000+01:00",{"title":5999,"description":12},"blender-scripting-geometry-nodes","blog-i18n/ja/blender-scripting-geometry-nodes/index",[6471],{"id":1844,"name":1845,"slug":1846,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1847},"iw_kyYtbQh5w4pFIFmq3NTGpzhQwGh5tzHYtgC3bvVg",{"id":6474,"title":6475,"authors":6476,"body":6478,"description":12,"extension":557,"feature_image":7225,"html":7,"meta":7226,"navigation":13,"path":7228,"published_at":7229,"seo":7230,"slug":7231,"stem":7232,"tags":7233,"__hash__":7236,"updated_at":7227,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/blender-shaders-explained/index.md","Blenderシェーダーの扱い方（2026）：ノード＆スクリプト",[6477],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":6479,"toc":7208},[6480,6491,6497,6500,6503,6509,6511,6517,6520,6529,6534,6551,6554,6568,6577,6579,6585,6588,6591,6594,6601,6614,6621,6624,6626,6632,6639,6647,6652,6655,6693,6698,6701,6709,6715,6718,6756,6762,6765,6785,6791,6794,6820,6826,6829,6855,6861,6864,6890,6896,6899,6907,6913,6916,6930,6932,6938,6944,6947,6950,6977,6984,6987,7007,7010,7033,7036,7069,7073,7076,7120,7123,7133,7139,7147,7150,7152,7156,7163,7174,7188,7202],[31,6481,6483,6487],{"className":6482},[34,35,36],[31,6484,6486],{"className":6485},[40],"🎨",[31,6488,6490],{"className":6489},[45],"シェーダーは魔法ではありません。制御でき、自動化もできる「視覚的なレシピ」です。",[48,6492,787,6493,6496],{},[655,6494,6495],{},"shader","（シェーダー）」という言葉を初めて聞いたとき、不安になるのは簡単です。誰かがGLSLの話をし始め、GPUが汗をかき始めるように感じて、気づけば読めないコードの壁を想像し、PCファンが助けを求めて叫んでいる――そんな気分になるでしょう。",[48,6498,6499],{},"o早い段階で誰も教えてくれないのはここです。シェーダーを扱うのに数学者やグラフィックスプログラマーである必要はありません。低レベルのGPUコードを書くことも、光の物理の裏にあるすべての式を理解することも求められていません。Blenderは、あなたにそれを期待していません。代わりに、ノードをくれます。コードというよりレゴのように振る舞う「視覚的な組み立て部品」です。つなげていくだけで結果がすぐ見えて、納得できる感触になるまで調整できます。",[48,6501,6502],{},"シェーダーをコードというより「レシピ」と考えてください。値、テクスチャ、ロジックを混ぜ合わせて、サーフェスが光にどう反応すべきかを記述します。時には既知のレシピに従い、時には即興で試し、時には何が起きるか見るためにあえて壊してみます。それが、あなたが学ぶ方法です。",[48,6504,6505,6508],{},[120,6506,6507],{},"この記事では、シェーディングが実際に何であるかを解き明かし、そこにまとわりつく恐怖心を取り払い、Blenderのノードシステムを使って（あるいは少しのスクリプトで）アニメーション制作パイプラインのためにシェーダーをプロシージャルに操作する方法を探ります。"," そして最後には、シェーディングが「立ち入ってはいけない部屋」のように感じることはなくなっているはずです。",[61,6510],{},[64,6512,6514],{"id":6513},"whats-a-shader",[120,6515,6516],{},"シェーダーとは？",[48,6518,6519],{},"シェーダーを理解するには、「色」について考えるのをやめて「物理」について考え始める必要があります。",[48,6521,6522,6528],{},[94,6523,6525],{"href":6524},"https://blog.cg-wire.com/hard-surface-modeling/",[1936,6526,6527],{},"現実世界で木の椅子を赤く塗る","とき、あなたが変えているのは単なる色ではありません。光と相互作用する「マテリアルの層」を追加しているのです。その赤いペイントには、特定のラフネス（どれだけ光を散乱させるか）、特定のスペキュラリティ（どれだけツヤがあるか）、そして特定の屈折率があります。",[48,6530,6531],{},[120,6532,6533],{},"シェーダーとは、その光の相互作用をコンピューターがどうシミュレートするかを指示する一連の命令です。",[72,6535,6537,6543],{"className":6536},[34,75,6381],[77,6538],{"src":6539,"className":6540,"alt":12,"loading":82,"width":83,"height":6541,"srcSet":6542,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-296bf085-924e-40f9-92fc-346c5dc31de0.png",[81],1067,"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-296bf085-924e-40f9-92fc-346c5dc31de0.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-296bf085-924e-40f9-92fc-346c5dc31de0.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-296bf085-924e-40f9-92fc-346c5dc31de0.png 1600w",[6389,6544,6545],{},[6392,6546,6547],{},[655,6548,6550],{"className":6549,"style":122},[6397],"出典: TurboSquid",[48,6552,6553],{},"デジタルの太陽からの光の1本のレイが、あなたのオブジェクト表面に当たると、シェーダーが介入して次のように問いかけます。",[212,6555,6556,6559,6562,6565],{},[215,6557,6558],{},"「跳ね返りますか？」（反射）",[215,6560,6561],{},"「通り抜けますか？」（透過／ガラス）",[215,6563,6564],{},"「中に閉じ込められますか？」（吸収）",[215,6566,6567],{},"「皮膚の下へ散っていきますか？」（サブサーフェス・スキャタリング）",[48,6569,6570,6571],{},"濡れた石畳の通りをモデリングしているなら、単純な画像テクスチャだけで平坦な写真のように見せられます。しかしシェーダーは、ひび割れの中の水が完璧に反射して滑らかである一方、石はラフで鈍いことをレンダラーに伝えます。光は、濡れている部分と乾いている部分で別々に跳ね返るよう指示されます。",[94,6572,1934,6574],{"href":6573},"https://blog.cg-wire.com/how-light-shapes-emotion-in-animation/",[1936,6575,6576],{},"光は現実の形を変える。",[61,6578],{},[64,6580,6582],{"id":6581},"why-you-must-master-shader-nodes",[120,6583,6584],{},"シェーダーノードを習得しなければならない理由",[48,6586,6587],{},"「じゃあ、ただテクスチャをダウンロードすればいいのでは？」と聞きたくなるかもしれません。",[48,6589,6590],{},"フォトスキャンは素晴らしいですが、プロシージャルシェーディングには、静止画像ではかなわない3つの“超能力”があります。",[48,6592,6593],{},"画像テクスチャ（JPGやPNG）を使う場合、あなたはピクセルに制限されます。壁に近づきすぎてズームすると、ぼやけます。",[48,6595,6596,6597,6600],{},"シェーダーは数学を使います。",[120,6598,6599],{},"数学には解像度の上限がありません。","金属のプロシージャルな傷にズームして、微細な溝が見えるところまで行っても、輪郭はシャープなままです。あなたが誇りを持てるモデルで、きれいなトポロジーや良いプロポーションがあっても、シェーダーなしだと平面的に見えてしまいます。",[48,6602,6603,6604,6607,6608,5671,6611,6613],{},"Blenderのシェーダーノードは、",[120,6605,6606],{},"一貫したやり方でテクスチャを簡単に微調整できる","ようにします。たとえば宇宙船をテクスチャリングしているとしましょう。テクスチャマップで船体に錆を描きます。アートディレクターがやって来て「いいね。でも船が古すぎる。錆を50%減らして。」と言います。もし手で描いていたなら、最初からやり直すか、何時間も消す作業に追われます。シェーダーノードなら、あなたが作った「Rust Amount（錆の量）」の値を見つけて、",[155,6609,6610],{},"1.0",[155,6612,5674],{},"へスライドさせるだけです。以上です。",[48,6615,6616,6617,6620],{},"静止テクスチャは固まって見えますが、",[120,6618,6619],{},"シェーダーはアニメーションもできます","。フレーム番号に応じて岩の上に苔が時間とともに生えていくようにセットアップできますし、あるいは当たるほどシールドが明るく発光するようにもできます。シェーダーは、マテリアルが環境に反応することを可能にします。",[48,6622,6623],{},"これらすべての理由から、シェーダーノードを“使いこなせるようになること”は、厳しい納期のある制作現場で働くプロのアーティストにとって、非常に大きな解放（アンロック）になります。",[61,6625],{},[64,6627,6629],{"id":6628},"the-different-types-of-shader-nodes",[120,6630,6631],{},"シェーダーノードの種類",[48,6633,6634,6635,6638],{},"Blenderのノードシステムはフローチャートのように動きます。ノードを追加するには",[155,6636,6637],{},"Add（追加）","をクリックし、それらを接続します。データは左から右へ流れます。各機能をどう活かすかを理解するには、用意されているさまざまなノードの種類を理解する必要があります。",[72,6640,6642],{"className":6641},[34,75],[77,6643],{"src":6644,"className":6645,"alt":12,"loading":82,"width":83,"height":84,"srcSet":6646,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-2573386d-adc9-4979-a848-89d1cae3645e.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-2573386d-adc9-4979-a848-89d1cae3645e.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-2573386d-adc9-4979-a848-89d1cae3645e.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-2573386d-adc9-4979-a848-89d1cae3645e.png 1600w",[1098,6648,6649],{"id":6171},[120,6650,6651],{},"1. 入力ノード",[48,6653,6654],{},"入力ノードは、シーン・オブジェクト・ジオメトリ、またはユーザー定義の値から、シェーダーネットワークへデータを供給します。",[212,6656,6657,6663,6669,6675,6681,6687],{},[215,6658,6659,6662],{},[120,6660,6661],{},"Texture Coordinate（テクスチャ座標）"," - UV、オブジェクト、生成、カメラ座標を提供 + UV出力を使って、UV展開モデルに画像テクスチャを正しくマッピングする",[215,6664,6665,6668],{},[120,6666,6667],{},"Geometry（ジオメトリ）"," - 法線や“とがり具合”などの幾何情報を出力 + “Pointiness（とがり）”を使って窪みに汚れが溜まるようにする",[215,6670,6671,6674],{},[120,6672,6673],{},"Fresnel（フレネル）"," - 視線角に基づく反射率を計算 + ガラスのエッジでより強い反射を作る",[215,6676,6677,6680],{},[120,6678,6679],{},"Object Info（オブジェクト情報）"," - ランダム値やオブジェクトカラーなど、オブジェクトごとのデータを提供 + Random出力を使って各オブジェクトを少しずつ違う色にする",[215,6682,6683,6686],{},[120,6684,6685],{},"Value（値）"," - 定数の数値を出力 + 単一のスライダーでラフネスを制御する",[215,6688,6689,6692],{},[120,6690,6691],{},"Color（カラー）"," - 定数の色を出力 + スタイル化されたマテリアルのベースカラーとして使う",[1098,6694,6695],{"id":6186},[120,6696,6697],{},"2. 出力ノード",[48,6699,6700],{},"出力ノードはシェーダーの最終結果を定義し、ノードネットワークをBlenderのレンダリングシステムへ接続します。",[212,6702,6703],{},[215,6704,6705,6708],{},[120,6706,6707],{},"Material Output（マテリアル出力）"," - 最終的な表面、ボリューム、ディスプレースメント情報を出力 + Surface入力にPrincipled BSDFを接続する",[1098,6710,6712],{"id":6711},"_3-shader-nodes",[120,6713,6714],{},"3. シェーダーノード",[48,6716,6717],{},"シェーダーノードは、反射・屈折・発光など、光がサーフェスとどう相互作用するかを定義します。",[212,6719,6720,6726,6732,6738,6744,6750],{},[215,6721,6722,6725],{},[120,6723,6724],{},"Principled BSDF（プリンシプルBSDF）"," - 物理ベースのオールインワン表面シェーダー + 現実的な金属、プラスチック、肌などのマテリアルを作る",[215,6727,6728,6731],{},[120,6729,6730],{},"Diffuse BSDF（ディフューズBSDF）"," - マットで反射しないサーフェスを生成 + チョーク、粘土、研磨していない石に使う",[215,6733,6734,6737],{},[120,6735,6736],{},"Glossy BSDF（グロッシーBSDF）"," - 鏡のような反射を生成 + 磨かれた金属や鏡に使う",[215,6739,6740,6743],{},[120,6741,6742],{},"Glass BSDF（ガラスBSDF）"," - 屈折と反射を組み合わせる + 窓やガラスボトルに使う",[215,6745,6746,6749],{},[120,6747,6748],{},"Emission（エミッション）"," - サーフェスから光を放出 + スクリーン、LED、ネオンサインに使う",[215,6751,6752,6755],{},[120,6753,6754],{},"Mix Shader（ミックスシェーダー）"," - 2つのシェーダー出力をブレンド + 摩耗した金属にはディフューズとグロッシーを混ぜる",[1098,6757,6759],{"id":6758},"_4-displacement-nodes",[120,6760,6761],{},"4. ディスプレースメントノード",[48,6763,6764],{},"ディスプレースメントノードは、ジオメトリまたはシェーディングの法線を変更して、サーフェスのディテールを変えます。",[212,6766,6767,6773,6779],{},[215,6768,6769,6772],{},[120,6770,6771],{},"Displacement（ディスプレースメント）"," - 本当のジオメトリのディスプレースメントを実行 + 高さマップを使ってレンガ壁に実在の奥行きを作る（Cycles）",[215,6774,6775,6778],{},[120,6776,6777],{},"Bump（バンプ）"," - 法線の微調整で表面ディテールをシミュレート + ジオメトリを増やさずに微細な傷を追加する",[215,6780,6781,6784],{},[120,6782,6783],{},"Normal Map（法線マップ）"," - 法線テクスチャを使える法線データへ変換 + ゲームアセットからベイクした法線マップを適用する",[1098,6786,6788],{"id":6787},"_5-color-nodes",[120,6789,6790],{},"5. カラーノード",[48,6792,6793],{},"カラーノードは、シェーダーネットワーク内で色情報を調整したり、ブレンドしたり、変換したりします。",[212,6795,6796,6802,6808,6814],{},[215,6797,6798,6801],{},[120,6799,6800],{},"Mix Color（ミックスカラー）"," - 2つの色またはテクスチャをブレンド + 清いベースカラーに汚れテクスチャを混ぜる",[215,6803,6804,6807],{},[120,6805,6806],{},"RGB Curves（RGBカーブ）"," - コントラストとカラーバランスを調整 + 画像を再編集せずにテクスチャのコントラストを高める",[215,6809,6810,6813],{},[120,6811,6812],{},"Hue/Saturation（色相/彩度）"," - 色相、彩度、値を変更 + テクスチャを塗り直さずにマテリアルを青く色付けする",[215,6815,6816,6819],{},[120,6817,6818],{},"Invert（反転）"," - 色の値を逆にする + ラフネスマップを反転してツヤ感のマップを作る",[1098,6821,6823],{"id":6822},"_6-texture-nodes",[120,6824,6825],{},"6. テクスチャノード",[48,6827,6828],{},"テクスチャノードは、マテリアル用の画像またはプロシージャルなテクスチャを生成／読み込みします。",[212,6830,6831,6837,6843,6849],{},[215,6832,6833,6836],{},[120,6834,6835],{},"Image Texture（画像テクスチャ）"," - 外部の画像ファイルを読み込む + PBRマテリアルのためにアルベドマップを使う",[215,6838,6839,6842],{},[120,6840,6841],{},"Noise Texture（ノイズテクスチャ）"," - 滑らかなプロシージャルノイズを生成 + プラスチックに微妙なラフネスの変化を加える",[215,6844,6845,6848],{},[120,6846,6847],{},"Voronoi Texture（ボロノイテクスチャ）"," - セル状のパターンを生成 + ひび割れ、スケール、石タイルを作る",[215,6850,6851,6854],{},[120,6852,6853],{},"Gradient Texture（グラデーションテクスチャ）"," - 滑らかなグラデーションを出力 + マテリアルのブレンド用マスクとして使う",[1098,6856,6858],{"id":6857},"_7-utility-nodes",[120,6859,6860],{},"7. ユーティリティノード",[48,6862,6863],{},"ユーティリティノードは、数学的演算やデータ変換を行います。",[212,6865,6866,6872,6878,6884],{},[215,6867,6868,6871],{},[120,6869,6870],{},"Mapping（マッピング）"," - テクスチャ座標を変換 + テクスチャパターンをスケール／回転する",[215,6873,6874,6877],{},[120,6875,6876],{},"Math（数学）"," - 数値演算を実行 + 極端になりすぎないようラフネス値をクランプする",[215,6879,6880,6883],{},[120,6881,6882],{},"Vector Math（ベクターマス）"," - ベクターに基づく計算を実行 + 法線や方向ベクターを変更する",[215,6885,6886,6889],{},[120,6887,6888],{},"Clamp（クランプ）"," - 指定した範囲に値を制限 + 過剰に明るいエミッション値を防ぐ",[1098,6891,6893],{"id":6892},"_8-group-nodes",[120,6894,6895],{},"8. グループノード",[48,6897,6898],{},"グループノードは複数のノードを、再利用できる整理されたコンポーネントとしてまとめます。",[212,6900,6901],{},[215,6902,6903,6906],{},[120,6904,6905],{},"Node Group（ノードグループ）"," - 複雑なノードセットアップをカプセル化 + 複数のアセットで使い回せる「Rust Shader（錆シェーダー）」を作る",[1098,6908,6910],{"id":6909},"_9-layout-nodes",[120,6911,6912],{},"9. レイアウトノード",[48,6914,6915],{},"レイアウトノードはノードグラフを見やすく整理するためのもので、レンダリング結果には影響しません。",[212,6917,6918,6924],{},[215,6919,6920,6923],{},[120,6921,6922],{},"Frame（フレーム）"," - 関連するノードを見た目でグループ化 + テクスチャ関連ノードをまとめて囲う",[215,6925,6926,6929],{},[120,6927,6928],{},"Reroute（リルート）"," - 読みやすさのためにノード接続を迂回させる + 重なり合ったノードのノード（見た目の配線）を整理する",[61,6931],{},[64,6933,6935],{"id":6934},"the-next-level-scripting-your-shaders",[120,6936,6937],{},"次のレベル：シェーダーをスクリプトで扱う",[48,6939,6940,6941],{},"手でノードをつなげるのに慣れてくると、木、プラスチック、ゴールド、あらゆる種類のマテリアルを作れます。ですが、",[120,6942,6943],{},"500個ものユニークなオブジェクトがあるシーンで、それぞれに“少しの調整”を加えつつ、摩耗した金属マテリアルのランダムなバリエーションを生成する必要があるとしたら？",[48,6945,6946],{},"そこで重要になるのがPythonスクリプトです。プロジェクト内のすべてのマテリアルが、同じノード構造に従うことを保証できます。「このマテリアルを赤にして、ただしオブジェクトごとにランダムな数値で色相を少しずつ変える」といったスクリプトを書くことができます。",[48,6948,6949],{},"さっそく手を動かしましょう。このガイドでは、新しいマテリアルを作り、Principled BSDFを追加し、色を制御するためのノイズテクスチャを生成して、それらを一つにつなげるPythonスクリプトを書きます。",[31,6951,6953,6956],{"className":6952},[34,35,108],[31,6954,112],{"className":6955},[40],[31,6957,6959,6964,6966,6968,6969,6971,134,6973],{"className":6958},[45],[117,6960,6961],{},[120,6962,6963],{"style":122},"動くサンプルを探していますか？",[125,6965],{},[125,6967],{},"このガイドで紹介しているサンプル統合の完全なソースコードは、GitHubで確認できます：",[125,6970],{},[125,6972],{},[94,6974,6976],{"href":6975},"https://github.com/cgwire/blog-tutorials/tree/main/blender-shaders?ref=blog.cg-wire.com","https://github.com/cgwire/blog-tutorials/tree/main/blender-shaders",[48,6978,6979,6980,6983],{},"Blenderで",[655,6981,6982],{},"Scripting","タブを開き、新しいテキストブロックを作成して、手順に沿って進めてください。",[48,6985,6986],{},"まずはライブラリをインポートして、Blenderに新しいマテリアルを作りたいことを伝える必要があります。",[152,6988,6989,7001],{},[155,6990,6992,6993,6995,6998],{"className":6991},[175],"import random\n",[48,6994,1680],{},[48,6996,6997],{},"def create_procedural_material(mat_name):\n    mat = bpy.data.materials.new(name=mat_name)",[48,6999,7000],{},"    mat.use_nodes = True\n    nodes = mat.node_tree.nodes\n    links = mat.node_tree.links",[48,7002,7003],{},[155,7004,7006],{"className":7005},[175],"    nodes.clear()",[48,7008,7009],{},"次に、ノードを追加します。「Add」メニューからアイテムを引っ張り出すのと同じだと思ってください。プログラムで：",[152,7011,7012,7019],{},[155,7013,7015,7016],{"className":7014},[175],"    node_output = nodes.new(type='ShaderNodeOutputMaterial')\n    node_output.location = (400, 0)",[48,7017,7018],{},"    node_principled = nodes.new(type='ShaderNodeBsdfPrincipled')\n    node_principled.location = (0, 0)",[48,7020,7021],{},[155,7022,7024,7025,7028,7029,7032],{"className":7023},[175],"    node_principled.inputs",[263,7026,7027],{},"'Roughness'",".default_value = 0.2\n    node_principled.inputs",[263,7030,7031],{},"'Metallic'",".default_value = 1.0",[48,7034,7035],{},"では、面白くしていきます。ノイズテクスチャとColorRamp（カラ―ランプ）を追加して、ランダムな色のパターンを生成します。",[152,7037,7038,7059],{},[155,7039,7041,7042,7045,7046,7049,7050,7053],{"className":7040},[175],"node_noise = nodes.new(type='ShaderNodeTexNoise')\n    node_noise.location = (-600, 0)\n    node_noise.inputs",[263,7043,7044],{},"'Scale'",".default_value = 15.0\n    node_noise.inputs",[263,7047,7048],{},"'Detail'",".default_value = 10.0",[48,7051,7052],{},"    node_ramp = nodes.new(type='ShaderNodeValToRGB')\n    node_ramp.location = (-300, 0)",[48,7054,7055,7056,7058],{},"    node_ramp.color_ramp.elements",[263,7057,265],{},".color = (0.1, 0.1, 0.1, 1)",[48,7060,7061],{},[155,7062,7064,7065,7068],{"className":7063},[175],"    rand_r = random.random()\n    rand_g = random.random()\n    rand_b = random.random()\n    node_ramp.color_ramp.elements",[263,7066,7067],{},"1",".color = (rand_r, rand_g, rand_b, 1)",[48,7070,7071],{},[125,7072],{},[48,7074,7075],{},"最後に、それらを配線して、この新しいシェーダーを現在のコンテキスト（デフォルトのキューブ）に適用します。",[152,7077,7078,7114],{},[155,7079,7081,7082,7085,7086,2098,7088,7098,7108,7111],{"className":7080},[175],"    links.new(node_noise.outputs",[263,7083,7084],{},"'Fac'",", node_ramp.inputs",[263,7087,7084],{},[48,7089,7090,7091,7094,7095,2098],{},"    links.new(node_ramp.outputs",[263,7092,7093],{},"'Color'",", node_principled.inputs",[263,7096,7097],{},"'Base Color'",[48,7099,7100,7101,7104,7105,2098],{},"    links.new(node_principled.outputs",[263,7102,7103],{},"'BSDF'",", node_output.inputs",[263,7106,7107],{},"'Surface'",[48,7109,7110],{},"    return mat",[48,7112,7113],{},"my_new_mat = create_procedural_material(\"SciFi_Metal_Random\")",[48,7115,7116],{},[155,7117,7119],{"className":7118},[175],"bpy.context.object.data.materials.append(my_new_mat)",[48,7121,7122],{},"このコードをテキストエディタにコピーして、「Run Script（スクリプトを実行）」を押します（再生ボタン）。アクティブなオブジェクトを見てください。ランダムな色のノイズパターンを持つメタリックな表面になっています。もう一度実行して（関数呼び出し内の名前を変更します）、別の色が得られます。",[72,7124,7126],{"className":7125},[34,75],[77,7127],{"src":7128,"className":7129,"alt":12,"loading":82,"width":7130,"height":7131,"srcSet":7132,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-99dc12fe-068b-40f7-9f10-ef0c5e000ba0.png",[81],1268,827,"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-99dc12fe-068b-40f7-9f10-ef0c5e000ba0.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-99dc12fe-068b-40f7-9f10-ef0c5e000ba0.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-99dc12fe-068b-40f7-9f10-ef0c5e000ba0.png 1268w",[48,7134,7135,7136],{},"おめでとうございます、",[120,7137,7138],{},"あなたはプロシージャルなマテリアルジェネレーターを作りました！",[48,7140,7141],{},[94,7142,1934,7144],{"href":6975,"rel":7143},[533],[1936,7145,7146],{},"対応するGithubリポジトリ",[48,7148,7149],{},"コードをいじってみるために、ぜひ見てください！",[61,7151],{},[64,7153,7154],{"id":507},[120,7155,2530],{},[48,7157,7158,7159,7162],{},"シェーダーは、ただ線の中に色を塗る以上のものです。シェーダーは、あなたのデジタル世界の「皮膚」です。",[120,7160,7161],{},"シェーダーは、そのオブジェクトの物語を伝えます","。どれくらい古いのか、どこを通ってきたのか、そして何でできているのか。",[48,7164,7165,7166,7169,7170,7173],{},"シェーダーノードのロジックを理解すれば、",[120,7167,7168],{},"フォトリアルな肌から、スタイル化したカートゥーンの炎まで","何でも作れます。さらにPythonスクリプトへ一歩踏み出せば、制作を",[120,7171,7172],{},"より速く、より賢く","進める力が手に入ります。面倒な部分を自動化して、アートに集中できるようになるのです。",[48,7175,7176,7177,7180,7181,7187],{},"ただし、これはパズルのほんの一部です。表面は変えられます。でも形はどうでしょう？旅の次の論理的なステップは",[655,7178,7179],{},"ジオメトリノード","です。シェーダーノードが色や光をプロシージャルに制御するのと同じように、ジオメトリノードはメッシュや構造をプログラム的に制御します。",[94,7182,1934,7184],{"href":7183},"https://blog.cg-wire.com/blender-scripting-geometry-nodes-2/",[1936,7185,7186],{},"こちらの専用記事をご覧ください","。コードからシーン全体を作る方法を学べます！",[31,7189,7191,7194],{"className":7190},[34,35,36],[31,7192,524],{"className":7193},[40],[31,7195,7197,7198,7201],{"className":7196},[45],"アニメーション制作のプロセスをもっと学ぶには",[94,7199,3875],{"href":531,"rel":7200},[533],"！私たちはベストプラクティスを共有する1,000人以上の専門家とつながっており、ときどき対面イベントも企画しています。ぜひ歓迎します！😊",[31,7203,7205],{"className":7204},[34,539,540],[94,7206,546],{"href":531,"className":7207},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":7209},[7210,7211,7212,7223,7224],{"id":6513,"depth":548,"text":6516},{"id":6581,"depth":548,"text":6584},{"id":6628,"depth":548,"text":6631,"children":7213},[7214,7215,7216,7217,7218,7219,7220,7221,7222],{"id":6171,"depth":1820,"text":6651},{"id":6186,"depth":1820,"text":6697},{"id":6711,"depth":1820,"text":6714},{"id":6758,"depth":1820,"text":6761},{"id":6787,"depth":1820,"text":6790},{"id":6822,"depth":1820,"text":6825},{"id":6857,"depth":1820,"text":6860},{"id":6892,"depth":1820,"text":6895},{"id":6909,"depth":1820,"text":6912},{"id":6934,"depth":548,"text":6937},{"id":507,"depth":548,"text":2530},"https://images.unsplash.com/photo-1664526936810-ec0856d31b92?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDd8fHNoYWRlciUyMG5vZGVzfGVufDB8fHx8MTc2NzYwMzU4M3ww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":7227,"featured_at":561,"visibility":562},"2026-03-26T09:56:11.000+01:00","/blog-i18n/ja/blender-shaders-explained","2026-01-05T10:35:18.000+01:00",{"title":6475,"description":12},"blender-shaders-explained","blog-i18n/ja/blender-shaders-explained/index",[7234,7235],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1844,"name":1845,"slug":1846,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1847},"mwJOX_0DF3S0rwJvRPJMDjtmu5Raia5FdwYOZWSUm7Q",{"id":7238,"title":7239,"authors":7240,"body":7242,"description":12,"extension":557,"feature_image":7797,"html":7,"meta":7798,"navigation":13,"path":7800,"published_at":7801,"seo":7802,"slug":7803,"stem":7804,"tags":7805,"__hash__":7808,"updated_at":7799,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/dcc-integration-blender-kitsu/index.md","BlenderからKitsuへ：カスタムDCCブリッジの作り方（2026）",[7241],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":7243,"toc":7788},[7244,7254,7266,7269,7272,7275,7277,7283,7290,7300,7309,7319,7321,7327,7330,7336,7343,7350,7353,7356,7358,7364,7390,7393,7396,7402,7405,7412,7426,7429,7432,7440,7449,7459,7464,7472,7477,7487,7490,7496,7499,7524,7535,7537,7543,7546,7549,7569,7603,7606,7614,7617,7623,7633,7635,7641,7644,7647,7667,7670,7673,7682,7685,7691,7694,7704,7706,7712,7715,7737,7747,7749,7753,7756,7759,7768,7782],[31,7245,7247,7250],{"className":7246},[34,35,36],[31,7248,4408],{"className":7249},[40],[31,7251,7253],{"className":7252},[45],"制作ツール同士が制作管理トラッカーと会話できたらいいのに…と思ったことはありませんか？カスタムDCC連携があれば、ようやくそれが可能になります。BlenderとKitsuの間で起きがちな手作業のアップロード、バージョンの不一致、そして時間のロス—もうそんな手間とはおさらばです。",[48,7255,7256,7257,658,7259,658,7262,7265],{},"アーティストは物語を形にするために、",[120,7258,1845],{},[120,7260,7261],{},"Maya",[120,7263,7264],{},"Houdini"," のようなデジタル・コンテンツ・クリエイション（DCC）ツールに頼っています。",[48,7267,7268],{},"しかし、クリエイティブ作業はこれらのツールの中で行われる一方で、制作のトラッキングは別の場所で行われます。この断絶は、バージョン不一致、繰り返し作業になる手動アップロードで失われる時間、そして結果的に「作る時間」が減ることにつながり得ます。DCCソフトと制作トラッカーの間にスムーズな接続がないと、パイプラインが損なわれてしまいます。",[48,7270,7271],{},"そこで役立つのが、カスタム連携です。",[48,7273,7274],{},"この記事では、Kitsu Publisherと同様の考え方で、BlenderからKitsuへ3Dモデルのプレビュ―を公開するためのKitsuにおけるBlender連携の基本を解説します。",[61,7276],{},[64,7278,7280],{"id":7279},"what%E2%80%99s-a-dcc-integration",[120,7281,7282],{},"DCC連携とは？",[48,7284,7285,7286,7289],{},"DCC連携とは、",[120,7287,7288],{},"クリエイティブ用ソフトと、別のソフトウェアツールの間をつなぐ「ブリッジ」","のことです。たとえば制作トラッカーのようなものです。",[48,7291,7292,7293,7299],{},"例えば、ファイルを書き出し、ウェブブラウザを開いて、バージョンを手作業でアップロードする代わりに、連携によって",[94,7294,1934,7296],{"href":7295},"https://blog.cg-wire.com/working-with-multiple-digital-content-creation-tools/",[1936,7297,7298],{},"選んだツールから直接公開できるようにする","ことが可能になります。",[48,7301,7302,7303],{},"連携は、",[94,7304,1934,7306],{"href":7305},"https://blog.cg-wire.com/rendering-explained/",[1936,7307,7308],{},"複雑なレンダリングパイプラインの管理",[48,7310,7311,7312,7318],{},",",[94,7313,1934,7315],{"href":7314},"https://blog.cg-wire.com/animation-asset-storage/",[1936,7316,7317],{},"アセットの保存とバージョン管理","、あるいはプレビュー画像の生成など、さまざまな作業を担えます。面倒な制作工程を自動化することで、アーティストが「物語を伝える」ことに集中できるようになります。",[61,7320],{},[64,7322,7324],{"id":7323},"why-dcc-integration",[120,7325,7326],{},"なぜDCC連携なのか？",[48,7328,7329],{},"どのスタジオも、いずれは同じボトルネックに突き当たります。プロジェクトが成長するほど、手作業のプロセスは破綻しやすくなるのです。",[48,7331,7332,7335],{},[120,7333,7334],{},"連携は時間を節約します","。ソフト間で文脈を切り替える必要がなくなるためです。",[48,7337,7338,7339,7342],{},"また、命名規則、フォーマット、メタデータの整合性を強制することで、",[120,7340,7341],{},"繰り返し作業によるエラーを減らす","ことにもつながります。",[48,7344,7345,7346,7349],{},"最後に、監督者やプロデューサーへリアルタイムの更新を届けることで、",[120,7347,7348],{},"プロジェクト管理とコミュニケーションを改善する","ことができます。",[48,7351,7352],{},"すべてのプロのアニメーションスタジオはパイプラインに依存しており、DCC連携は不可欠です。",[48,7354,7355],{},"具体例として、BlenderからKitsuへプレビューをアップロードするスクリプト連携を作って、チームでの作業レビューを簡単にしてみましょう。",[61,7357],{},[64,7359,7361],{"id":7360},"_1-getting-started",[120,7362,7363],{},"1. はじめに",[31,7365,7367,7370],{"className":7366},[34,35,4487],[31,7368,112],{"className":7369},[40],[31,7371,7373,7377,7379,7381,7382,7384,134,7386],{"className":7372},[45],[117,7374,7375],{},[120,7376,123],{"style":122},[125,7378],{},[125,7380],{},"このガイドで紹介している、Blender–Kitsu連携の完全なソースコードは、GitHubで確認できます：",[125,7383],{},[125,7385],{},[94,7387,7389],{"href":7388},"https://github.com/cgwire/blender-kitsu-dcc-integration-example?ref=blog.cg-wire.com","github.com/cgwire/blender-kitsu-dcc-integration-example",[48,7391,7392],{},"スクリプトに取りかかる前に、安全に連携をテストできるローカルのKitsuインスタンスを用意しましょう。",[48,7394,7395],{},"Kitsuをローカルで最も簡単に動かす方法は、kitsu-dockerリポジトリを使うことです。リポジトリをマシンにクローンし、手順に従ってください：",[152,7397,7398],{},[155,7399,7401],{"className":7400},[158],"git clone \u003Chttps://github.com/cgwire/kitsu-docker.git>\ncd kitsu-docker\ndocker build -t cgwire/cgwire .\ndocker run --init -ti --rm -p 80:80 -p 1080:1080 --name cgwire cgwire/cgwire",[48,7403,7404],{},"これで、Kitsu、postgresデータベース、そしてそれを支えるコンポーネントがすべて起動します。",[48,7406,7407,7408,7411],{},"コンテナが動き出したら、ブラウザで ",[155,7409,7410],{},"http://localhost:80"," を開いてください。デフォルトの認証情報は以下です：",[212,7413,7414,7420],{},[215,7415,7416,7419],{},[120,7417,7418],{},"Email",": admin@example.com",[215,7421,7422,7425],{},[120,7423,7424],{},"Password:"," mysecretpassword",[48,7427,7428],{},"Kitsuのダッシュボードに移動します。",[48,7430,7431],{},"プレビューをアップロードする前に、アップロード先が必要です。Kitsuでは：",[1710,7433,7434],{},[215,7435,7436,7437,7439],{},"サイドバーの \"",[120,7438,3348],{},"\" ページからアクセスして、新しい制作（例：Blender Test Project）を作成します。",[72,7441,7443],{"className":7442},[34,75],[77,7444],{"src":7445,"className":7446,"alt":12,"loading":82,"width":7447,"height":7448},"https://blog.cg-wire.com/content/images/2025/10/CleanShot-2025-10-13-at-9---.26.46-1.png",[81],206,479,[72,7450,7452],{"className":7451},[34,75],[77,7453],{"src":7454,"className":7455,"alt":12,"loading":82,"width":7456,"height":7457,"srcSet":7458,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-0e43401b-afb6-4345-b773-db3d9b03bed3.png",[81],946,914,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-0e43401b-afb6-4345-b773-db3d9b03bed3.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-0e43401b-afb6-4345-b773-db3d9b03bed3.png 946w",[1710,7460,7461],{"start":548},[215,7462,7463],{},"制作の中でアセットを作成します。",[72,7465,7467],{"className":7466},[34,75],[77,7468],{"src":7469,"className":7470,"alt":12,"loading":82,"width":7456,"height":7457,"srcSet":7471,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-83cce3b0-70a0-486d-87e7-4914a5304262.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-83cce3b0-70a0-486d-87e7-4914a5304262.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-83cce3b0-70a0-486d-87e7-4914a5304262.png 946w",[1710,7473,7474],{"start":1820},[215,7475,7476],{},"アセットを作成すると、制作作成時に選択したタスクカテゴリに応じて、自動的に新しいタスクが追加されます。これらを使ってプレビューをアップロードできます。",[48,7478,7479,7480,7486],{},"Kitsuをプログラム的に操作するには、",[94,7481,1934,7483],{"href":7482},"https://github.com/cgwire/gazu?ref=blog.cg-wire.com",[1936,7484,7485],{},"gazu（Kitsu API向けの公式Pythonクライアント）を使用します","。認証、エンティティの作成、そしてスクリプトからのプレビューの直接アップロードが可能になります。",[48,7488,7489],{},"インストールは：",[152,7491,7492],{},[155,7493,7495],{"className":7494},[158],"pip install gazu",[48,7497,7498],{},"次に、ユーザー名とパスワードでKitsuインスタンスに認証します：",[152,7500,7501,7515],{},[155,7502,176,7504,7510],{"className":7503},[175],[48,7505,2032,7506,7509],{},[94,7507,185],{"href":185,"rel":7508},[187],">\")",[48,7511,7512,7513,869],{},"user = gazu.log_in(\"",[94,7514,192],{"href":191},[48,7516,7517],{},[155,7518,7520,7521,2098],{"className":7519},[175],"print(\"Logged in as:\", user['user']",[263,7522,7523],{},"'full_name'",[48,7525,7526,7528,7529,600],{},[125,7527],{},"ログインできたら、",[94,7530,1934,7532],{"href":7531},"https://gazu.cg-wire.com/?ref=blog.cg-wire.com",[1936,7533,7534],{},"gazuを使って制作、アセット、タスクを取得し、それらにメディアファイルを紐づけます",[61,7536],{},[64,7538,7540],{"id":7539},"_2-creating-a-preview-from-blender",[120,7541,7542],{},"2. Blenderからプレビューを作成する",[48,7544,7545],{},"プレビュ―レンダ―を制作することは、アニメーターにとってよくある用途です。制作段階を通して定期的なフィードバックを得る必要があり、プレビューは、プロジェクト全体を読み込むよりも判断しやすいからです。",[48,7547,7548],{},"これは、BlenderのPython APIで自動化できます。ビューポートのキャプチャを設定して1フレームだけレンダリングし、出力を一時フォルダに保存し、さらにスタジオ全体のレンダリング設定（解像度、フォーマット、水印）を適用します：",[152,7550,7551,7563],{},[155,7552,1680,7554,7557,7560],{"className":7553},[175],[48,7555,7556],{},"bpy.ops.wm.open_mainfile(filepath=\"./project.blend\")",[48,7558,7559],{},"bpy.context.scene.render.resolution_x = 256\nbpy.context.scene.render.resolution_y = 256\nbpy.context.scene.render.resolution_percentage = 100",[48,7561,7562],{},"bpy.context.scene.render.image_settings.file_format = 'PNG'\nbpy.context.scene.render.filepath = \"./preview.png\"",[48,7564,7565],{},[155,7566,7568],{"className":7567},[175],"bpy.ops.render.render(write_still=True)",[212,7570,7571,7576,7585,7593],{},[215,7572,7573,7575],{},[155,7574,1680],{},": BlenderのPython APIを読み込みます",[215,7577,117,7578,4768,7581,7584],{},[155,7579,7580],{},"py.ops.wm.open_mainfile(filepath=\"./project.blend\")",[155,7582,7583],{},"project.blend"," という既存のBlenderプロジェクトファイルを開きます",[215,7586,7587,7592],{},[155,7588,7589,7590],{},"bpy.context.scene.render.resolution_x = 256 ",[263,7591,375],{},"We configure the render resolution to 256 pixels by 256 pixels with no downscale.",[215,7594,7595,7598,7599,7602],{},[155,7596,7597],{},"bpy.context.scene.render.image_settings.file_format = 'PNG'",": 出力フォーマットをPNGに設定し、シーンのスティルレンダ―を実行する前に、出力先を ",[155,7600,7601],{},"preview.png"," に定義します。",[48,7604,7605],{},"このスクリプトにより、軽量なプレビュー用ファイルが生成されます。Kitsuに保存するのが簡単で、監督者が素早く確認できるようになります。",[72,7607,7609],{"className":7608},[34,75],[77,7610],{"src":7611,"className":7612,"alt":12,"loading":82,"width":7456,"height":7457,"srcSet":7613,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-e936efc9-2c3b-43ea-86f7-8845bdc6c50f.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-e936efc9-2c3b-43ea-86f7-8845bdc6c50f.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-e936efc9-2c3b-43ea-86f7-8845bdc6c50f.png 946w",[48,7615,7616],{},"実行するには、bpyパッケージをインストールして、他のPythonスクリプトと同様にプログラムを起動するだけです：",[152,7618,7619],{},[155,7620,7622],{"className":7621},[158],"python3 preview.py",[72,7624,7626],{"className":7625},[34,75],[77,7627],{"src":7628,"className":7629,"alt":12,"loading":82,"width":7630,"height":7631,"srcSet":7632},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-8fc4a1a4-01c7-4fcb-a8a6-b5d50588d6b8.png",[81],687,768,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-8fc4a1a4-01c7-4fcb-a8a6-b5d50588d6b8.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-8fc4a1a4-01c7-4fcb-a8a6-b5d50588d6b8.png 687w",[61,7634],{},[64,7636,7638],{"id":7637},"_3-uploading-a-preview-to-kitsu",[120,7639,7640],{},"3. プレビューをKitsuへアップロードする",[48,7642,7643],{},"プレビュー用ファイルの準備ができたら、最後のステップはgazuを使ってデータをKitsuに送り込むことです。",[48,7645,7646],{},"まず、先ほど作成したタスクを取得します：",[152,7648,7649,7658],{},[155,7650,7652,7653],{"className":7651},[175],"projects = gazu.project.all_projects()",[48,7654,7655,7656,2098],{},"assets = gazu.asset.all_assets_for_project(projects",[263,7657,265],{},[48,7659,7660],{},[155,7661,7663,7664,7666],{"className":7662},[175],"tasks = gazu.task.all_tasks_for_asset(assets",[263,7665,265],{},")\ntask_status = gazu.task.get_task_status_by_short_name(\"todo\")",[48,7668,7669],{},"このために、まず利用可能な制作の一覧を取得し、次に新しく作成した制作のアセットを取得し、最後にこのアセットに割り当てられたタスクを取得します。",[48,7671,7672],{},"プレビュー用ファイルをタスクに紐づけながら、タスクに対するコメントを公開します：",[152,7674,7675],{},[155,7676,7678,7679,7681],{"className":7677},[175],"(comment, preview_file) = gazu.task.publish_preview(\n tasks",[263,7680,265],{},",\n task_status,\n    comment=\"upload preview\",\n    preview_file_path=\"./preview.png\"\n)",[48,7683,7684],{},"そしてスクリプトを実行します：",[152,7686,7687],{},[155,7688,7690],{"className":7689},[158],"python3 upload.py",[48,7692,7693],{},"アップロード後、ファイルはすぐにKitsuのWebインターフェースで利用可能になります。監督者はそれを確認し、フィードバックを残し、ステータスをマークできます。アーティスト側での手作業によるファイルのやりくりは一切不要です。",[72,7695,7697],{"className":7696},[34,75],[77,7698],{"src":7699,"className":7700,"alt":12,"loading":82,"width":7701,"height":7702,"srcSet":7703,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-e9710dd1-d727-4e9f-85f8-9db075a159f4.png",[81],955,931,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-e9710dd1-d727-4e9f-85f8-9db075a159f4.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-e9710dd1-d727-4e9f-85f8-9db075a159f4.png 955w",[61,7705],{},[64,7707,7709],{"id":7708},"_4-distribution",[120,7710,7711],{},"4. 配布",[48,7713,7714],{},"スクリプトが動くようになったら、使ったり共有したりする方法はいくつかあります：",[212,7716,7717,7725,7731],{},[215,7718,7719,1490,7722,7724],{},[120,7720,7721],{},"Blender内で直接実行する",[655,7723,6982],{}," ワークスペースを開き、そこからスクリプトを実行します。",[215,7726,7727,7730],{},[120,7728,7729],{},"コマンドラインから実行する"," - 先ほどと同様に、任意のPythonプログラムと同じようにターミナルからスクリプトを起動できます。",[215,7732,7733,7736],{},[120,7734,7735],{},"アドオンとしてパッケージ化する"," - Blenderの環境設定から有効化でき、さらに使いやすいように独自のユーザーインターフェースを設計することも可能です。",[48,7738,7739,7740,7746],{},"UI付きの完全なアドオンを作り、アーティストに対して連携を共有できるようにするのが理想ですが、これはかなり大きなテーマであり、ここでは扱いません。さらに詳しく知りたい場合は、",[94,7741,1934,7743],{"href":7742},"https://docs.blender.org/manual/en/latest/advanced/scripting/addon_tutorial.html?ref=blog.cg-wire.com",[1936,7744,7745],{},"公式のBlenderアドオンチュートリアル","をご覧ください。そして続報もお待ちください。将来の投稿で、これをさらに詳しく取り上げます！",[61,7748],{},[64,7750,7751],{"id":507},[120,7752,2530],{},[48,7754,7755],{},"DCCパイプラインの連携は、効率的なアニメーションスタジオにとって基盤です。BlenderのようなツールをKitsuへ直接つなぐことで、摩擦を減らし、コミュニケーションを改善し、アーティストと制作管理者の双方にとって仕事を楽にできます。",[48,7757,7758],{},"連携の恩恵を見るために、大規模なパイプラインチームは必要ありません。小さなスタジオでも、まずはシンプルに始め、いくつかのつらいポイントを自動化し、必要に応じて時間とともに段階的に拡張していくことができます。",[48,7760,7761,7767],{},[94,7762,7764],{"href":7763},"https://github.com/cgwire/kitsu-publisher-next?ref=blog.cg-wire.com#readme",[1936,7765,7766],{},"Kitsu Publisherのドキュメントを確認する","ことで、Blender、Toon Boom Harmony、Unreal Engine向けの本番環境対応のDCC連携ソリューションを見つけられます。",[31,7769,7771,7774],{"className":7770},[34,35,36],[31,7772,524],{"className":7773},[40],[31,7775,7777,7778,7781],{"className":7776},[45],"アニメーション制作プロセスについてもっと知りたいなら ",[94,7779,961],{"href":531,"rel":7780},[533],"！ベストプラクティスを共有する1,000人以上の専門家とつながっており、時には現地でのイベントも企画しています。ぜひ歓迎します！ 😊",[31,7783,7785],{"className":7784},[34,539,540],[94,7786,546],{"href":531,"className":7787},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":7789},[7790,7791,7792,7793,7794,7795,7796],{"id":7279,"depth":548,"text":7282},{"id":7323,"depth":548,"text":7326},{"id":7360,"depth":548,"text":7363},{"id":7539,"depth":548,"text":7542},{"id":7637,"depth":548,"text":7640},{"id":7708,"depth":548,"text":7711},{"id":507,"depth":548,"text":2530},"https://images.unsplash.com/photo-1580894894513-541e068a3e2b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fFNvZnR3YXJlJTIwaW50ZWdyYXRpb258ZW58MHx8fHwxNzYwMzE0NjM1fDA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":7799,"featured_at":561,"visibility":562},"2026-02-20T06:04:22.000+01:00","/blog-i18n/ja/dcc-integration-blender-kitsu","2025-10-14T11:23:34.000+02:00",{"title":7239,"description":12},"dcc-integration-blender-kitsu","blog-i18n/ja/dcc-integration-blender-kitsu/index",[7806,7807],{"id":1844,"name":1845,"slug":1846,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1847},{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"20bHK19sNC42GI-j8-y1JO3g9anGfJzJmaosj59Mmds",{"id":7810,"title":7811,"authors":7812,"body":7814,"description":12,"extension":557,"feature_image":8175,"html":7,"meta":8176,"navigation":13,"path":8178,"published_at":8177,"seo":8179,"slug":8180,"stem":8181,"tags":8182,"__hash__":8184,"updated_at":8177,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/estimating-render-costs-animation/index.md","アニメーション制作会社がレンダーファームの容量を見積もる方法",[7813],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":7815,"toc":8166},[7816,7827,7830,7833,7836,7842,7844,7848,7853,7859,7866,7873,7875,7879,7884,7887,7890,7928,7931,7933,7937,7942,7945,7951,7954,7957,7959,7963,7968,7974,7977,7980,7986,7992,7994,7998,8003,8006,8044,8051,8053,8057,8062,8065,8108,8115,8122,8124,8126,8131,8137,8146,8160],[31,7817,7819,7823],{"className":7818},[34,35,36],[31,7820,7822],{"className":7821},[40],"😀",[31,7824,7826],{"className":7825},[45],"レンダリングコストは当てずっぽうではありません。適切なフレームワークがあれば、予測可能になります。",[48,7828,7829],{},"誰もが、午後4時にレンダーファームがじわじわ動き出すのを見たことがあるはずです。10分経っても動かない進捗バーを見つめながら、「今日中にこのショットは終わるのか？」と考える。その瞬間、キューが満杯でアーティストが止まり、上長がETA（見込み時間）を求める――それは見積もりの問題です。",[48,7831,7832],{},"レンダリングは、予測できないように感じがちです。照明を少し調整しただけでフレーム時間が2倍になる。昨日はうまくいった設定が、今日はメモリを爆発させる。コスト見積もりのフレームワークがなければ、飽和したファーム、遅れる納期、そしてパイプラインへの信頼の低下が待っています。",[48,7834,7835],{},"朗報です。レンダリングコストは魔法ではありません。測定でき、分解でき、そして直感ではなくフレームワークを使って推定に取り組めば予測できます。",[48,7837,7838,7841],{},[120,7839,7840],{},"このガイドでは、今すぐ適用できる明確で実践的な見積もりモデルを提示します。"," 会議で主張できる数字を必要とするパイプライン開発者向けに設計されています。",[61,7843],{},[64,7845,7847],{"id":7846},"why-estimating-rendering-costs","なぜレンダリングコストを見積もるのか",[48,7849,7850],{},[94,7851],{"href":7852},"https://github.com/cgwire/blog/blob/main/drafts/render-cost-estimation/index.md?ref=blog.cg-wire.com#why-estimating-rendering-costs",[48,7854,7855,7858],{},[120,7856,7857],{},"正確なレンダリングコストの見積もりはスケジュールを守る","――危機に陥る前に。1フレームあたり2時間で見積もったシーケンスが、静かに6時間でレンダリングされてしまうと、ファームの占有率は3倍になり、下流の部門は宙に置かれます。",[48,7860,7861,7862,7865],{},"コストの可視化はまた、",[120,7863,7864],{},"創造的な意思決定にも直接影響します","。アーティストが、高品質ボリューメトリを有効にするとレンダリング時間が35%増えると知れば、代替案を探ろうとする可能性が高くなります。そうしたフィードバックがなければ、選択は見た目の好みだけに寄り、影響は後でファーム側が吸収することになります。",[48,7867,7868,7869,7872],{},"信頼できる見積もりは",[120,7870,7871],{},"インフラと予算管理に不可欠","です。ファーム容量、クラウドのバースト運用、納品計画はいずれも、予測可能な数字に依存します。1フレーム3時間の120フレームシーケンスと、1フレーム9時間のそれでは挙動が大きく変わります。特に複数の同時進行ショーにまたがる場合は顕著です。見積もりが一貫して許容範囲に収まれば、制作はパイプラインを信頼し、その信頼がより賢い技術判断の余地を生みます。",[61,7874],{},[64,7876,7878],{"id":7877},"_1-what-actually-affects-rendering-costs","1. レンダリングコストに実際に影響するのは何か？",[48,7880,7881],{},[94,7882],{"href":7883},"https://github.com/cgwire/blog/blob/main/drafts/render-cost-estimation/index.md?ref=blog.cg-wire.com#1-what-actually-affects-rendering-costs",[48,7885,7886],{},"レンダリングコストは、単発のボタン操作だけで決まることはありません。積み重なる倍率（マルチプライヤー）の結果です。",[48,7888,7889],{},"1フレームのコストが高すぎると、下流すべてがつらくなるため、議論は常に「1フレームあたりのコストに影響する要素」から始めるべきです。",[212,7891,7892,7898,7904,7910,7916,7922],{},[215,7893,7894,7897],{},[120,7895,7896],{},"解像度"," - 1080pから4Kへ移行するのは、軽微な増加ではありません。ピクセル数が4倍です。1080pで5分かかるなら、同じ設定で4Kは20分というのは十分に現実的です。",[215,7899,7900,7903],{},[120,7901,7902],{},"フレームレート"," - 24fpsで10秒は240フレーム。60fpsで同じ10秒なら600フレームです。1フレームが8分かかるなら、シェーダーやライトを一切触らずに、レンダリング時間を32時間から80時間へ変えてしまっています。",[215,7905,7906,7909],{},[120,7907,7908],{},"レンダリングエンジンの選択"," - CPUかGPUかは、速度というよりもメモリ上限の問題です。GPUは1フレームあたり劇的に速くなり得ますが、VRAMによって制約されます。12GBのテクスチャと重いジオメトリを含むシーンは、システムRAMなら快適に収まっていても、加速構造やオーバーヘッドを含めると24GBのGPUを超えてしまう可能性があります。",[215,7911,7912,7915],{},[120,7913,7914],{},"サンプリング"," - サンプル数を2倍にすると、レンダリング時間はほぼ2倍になります。ノイズが192サンプルで許容できる程度に収まるとしても、念のため512まで押し上げると、見た目の改善がわずかでもレンダリング時間がほぼ3倍近くになることがあります。",[215,7917,7918,7921],{},[120,7919,7920],{},"シーンの複雑さ"," - 現代のレンダラーは数百万ポリゴンを扱えますが、加速構造のビルド時間やメモリ使用量はスケールします。500万ポリのヒーローアセットは単体なら問題ないかもしれません。しかし、正しくインスタンス化されていない重複が50個あると、シーンメモリが2倍になり、レンダリング準備時間も大幅に増える可能性があります。テクスチャ、ボリューメトリックなフォグ、ヘアやファー、群衆、シミュレーションなどにも同様のことが当てはまります。",[215,7923,7924,7927],{},[120,7925,7926],{},"アニメーションの長さ"," - 総フレーム数は、持続時間にフレームレートを掛けたものです。24fpsで30秒なら720フレーム。1フレームが12分なら、レンダリング時間は144時間です。",[48,7929,7930],{},"考慮すべきパラメータは多く、圧倒されがちです。だからこそ「1フレームあたりのコスト」だけが重要な指標になります。目標が1フレーム8分で、初期のライティングテストで14分だとしたら、たとえほんの数フレームしかレンダリングしていなくても、プロジェクトはすでに大きなオーバーランに向かっています。",[61,7932],{},[64,7934,7936],{"id":7935},"_2-understanding-the-core-formula","2. コアとなる計算式を理解する",[48,7938,7939],{},[94,7940],{"href":7941},"https://github.com/cgwire/blog/blob/main/drafts/render-cost-estimation/index.md?ref=blog.cg-wire.com#2-understanding-the-core-formula",[48,7943,7944],{},"レンダリングコストについて真面目な議論をするなら、まずはコアとなる計算式から始める必要があります。",[7946,7947,7948],"blockquote",{},[120,7949,7950],{},"総レンダリングコスト = ((1フレームあたりの平均レンダリング時間 * 総フレーム数) / レンダリング速度) * 時間あたりの計算コスト",[48,7952,7953],{},"シーケンスが1,200フレームあり、各フレームが単一GPUで平均18分、さらにファームがGPUあたり$2.50で40フレームを並列処理するとします。この計算をすると、照明の微調整がたったで数千ドル（あるいは予算の額）を増やしたのかどうかがすぐに分かります。すべての意思決定に数字を与えてくれます。",[48,7955,7956],{},"1フレームあたりのレンダリング時間を見積もるには、楽観ではなく制作の現実に基づく必要があります。",[61,7958],{},[64,7960,7962],{"id":7961},"_3-local-rendering-vs-cloud","3. ローカルレンダリングとクラウド",[48,7964,7965],{},[94,7966],{"href":7967},"https://github.com/cgwire/blog/blob/main/drafts/render-cost-estimation/index.md?ref=blog.cg-wire.com#3-local-rendering-vs-cloud",[48,7969,7970,7973],{},[120,7971,7972],{},"自社でレンダーファームを構築するか、クラウドレンダリングにするか","を選ぶ際、「総保有コスト（TCO）」と「実行コスト（総コスト）」の比較評価は難しくなることがあります。",[48,7975,7976],{},"ローカルのワークステーションでレンダリングする場合、ハードウェアがすでにそこにあるため、安く見えます。しかし、そのGPUやCPUは無料ではありません。3年間で償却する6,000ドルのワークステーションは、フレームを1枚もレンダリングする前から、月あたり約166ドルです。さらに電気代を加えましょう。たとえば700Wのマシンを1日10時間使い、kWhあたり$0.20だとすると、稼働維持だけで月あたり約42ドルになります。ここに保守も乗ります。SSDの故障、ドライバの競合、OSアップデートがプラグインを壊すなどです。IT作業を月4時間、1時間あたり$75と保守的に見積もるだけでも、$300です。「無料」に見えるレンダーノードは、制作影響を考慮する前でも月500ドル超のコストになってしまいます。さらに機会費用も、もう一つの見えにくい予算破壊要因です。10人チームで、1人のアーティストが1日$600で請求するなら、1台のワークステーションがブロックされるだけで、1週間のクランチにおける間接的な遅延として数千ドル規模になり得ます。",[48,7978,7979],{},"クラウドレンダリングはモデルを「資本的支出（CapEx）」から「運用費（OpEx）」へと反転させます。マシンを買うのではなく、GPU時間として計算資源を借りるのです。たとえば1フレームに2GPU時間かかり、提供側がGPU時間あたり$1.20を請求すると、1フレームあたり$2.40です。これを500フレームに掛ければ、生の計算コストは$1,200になります。この金額は透明で、ワークロードに対して線形にスケールするため、見積もりがより予測可能になります。クラウドの強みが「スケーラビリティ」です。500フレームを24時間で納品し、各フレームに2時間かかるなら、ローカルでは1,000GPU時間です。単一ワークステーションでは40日以上のレンダリング時間になります。5台でも1週間以上かかります。クラウドなら、100台のGPUを立ち上げることで約10時間で終えられます。この差は、クライアントを獲得できるか、期限を完全に逃すかに直結し得ます。ただし、クラウドには隠れたコストがあり、多くの見積もりがそこで崩れます。",[48,7981,7982,7985],{},[120,7983,7984],{},"実務的なアプローチはハイブリッド思考です。"," たとえば小さなローカルファームで日次のレンダリングを夜間に回し、最終成果物（finals）、急なピーク（spikes）、そして社内容量を超えるシミュレーションなどはクラウドレンダリングで対応します。必要に応じて切り替えましょう。",[48,7987,7988,7991],{},[120,7989,7990],{},"レンダリングコストを見積もることは、「マシン」だけでなく「挙動」をモデル化することです。"," 改めて重要なのは、1フレームあたりの平均レンダリング時間を把握し、それをローカル／クラウド双方のコスト見積もりに投入することです。",[61,7993],{},[64,7995,7997],{"id":7996},"_4-hidden-costs-animators-forget","4. アニメーターが忘れがちな隠れたコスト",[48,7999,8000],{},[94,8001],{"href":8002},"https://github.com/cgwire/blog/blob/main/drafts/render-cost-estimation/index.md?ref=blog.cg-wire.com#4-hidden-costs-animators-forget",[48,8004,8005],{},"誰もがレンダリング時間は予算化しますが、隠れたコストはショットをまたぐと増幅します。予測可能な納品を目指すなら、それらのコストを可視化し、積極的に管理する必要があります。",[212,8007,8008,8014,8020,8026],{},[215,8009,8010,8013],{},[120,8011,8012],{},"リビジョン（修正）","は一目で分かる代表例ですが、真の費用は単に追加のCPU時間だけではありません。問題は波及（カスケード）です。ヒーローショットの遅れたアニメーション微調整は、照明の再キューイングを強制し、コンプでキャッシュを無効化し、モデリングではテクスチャを再書き出しします。重いボリュームのある300フレームの4Kショットでは、「小さな」タイミング変更が、数万のコア時間に加えてアーティスト待ち時間まで意味することがあります。バージョン承認をクリアにすることで、大きな節約になります。",[215,8015,8016,8019],{},[120,8017,8018],{},"ストレージ","も、特にEXRシーケンスでは、静かな予算破壊要因です。4Kの16-bitマルチレイヤーEXRは、1フレームあたり80〜150MBに簡単に到達します。1,000フレームなら、1つのバージョンの1ショットに対して80〜150GBです。",[215,8021,8022,8025],{},[120,8023,8024],{},"帯域幅","は、アーティストがリモートで作業する、あるいは拠点をまたいで作業する瞬間に一気に見えてきます。120GBのパブリッシュを1Gbpsの回線で同期するのは理論上約15分ですが、実際には輻輳やオーバーヘッドのため、はるかに長くかかることがあります。さらに月曜の朝に同じプレートを10人のアーティストが引き始めれば、その分を10倍です。すると、コンプが転送待ちの間、ファームがアイドルになります。現実的な対策はキャッシュとローカリティで、たとえばNASとローカルのきめ細かな同期を用意することです。",[215,8027,8028,8031,8032,8035,8036,8039,8040,8043],{},[120,8029,8030],{},"バックアップと保管ポリシー","も、同じ理由で実コストが発生します。",[120,8033,8034],{},"ソフトウェアのライセンス","は固定費として扱われがちですが、レンダー専用ライセンスのように、予測できずにスケールすることもあります。",[120,8037,8038],{},"ITの時間とパイプラインのセットアップ","は、ショーの予算に入らないことも多いですが、入れるべきです。新しいショーの構成、カスタムUSDスキーマ、ファーム統合などは、サポートやR&Dと競合するエンジニアリング時間です。そして最後に重要な点：納品が圧縮されると、すべてが高くなります。クラウドのバーストレンダリングはコア時間あたりの費用が高く、ベンダーは",[120,8041,8042],{},"エクスペダイト（急ぎ）料金","を請求し、残業は給与の燃焼を増やします。",[48,8045,8046,8047,8050],{},"これらのコストは、どれも謎ではありません。制作の主眼がクリエイティブ出力にあると、ただ無視しやすいだけです。",[120,8048,8049],{},"強力なパイプラインの役割は、こうした見えない倍率を測定可能にし、管理可能にすることです。"," チームが「小さな変更」の実コストを見るようになれば、より良い判断ができ、制作全体がサプライズの少ない運用になります。",[61,8052],{},[64,8054,8056],{"id":8055},"_5-a-simple-estimation-framework","5. シンプルな見積もりフレームワーク",[48,8058,8059],{},[94,8060],{"href":8061},"https://github.com/cgwire/blog/blob/main/drafts/render-cost-estimation/index.md?ref=blog.cg-wire.com#5-a-simple-estimation-framework",[48,8063,8064],{},"レンダリングコストの見積もりは現実に根ざす必要があります。これで必要な要素が揃ったので、以下は見積もりを作るためのシンプルな手順です。ただし、それを単純化しすぎず、スタジオのワークフローに合わせて調整してください。",[1710,8066,8067,8074,8080,8087,8094,8101],{},[215,8068,8069,8070,8073],{},"最も信頼できる出発点は",[120,8071,8072],{},"現在の制作における最も重いシーン","です。見つけられる範囲で最も複雑なショットを引っ張りましょう。最高のキャラクター数、フルFX、ボリューメトリ、モーションブラーなど、全部入りです。",[215,8075,8076,8079],{},[120,8077,8078],{},"実運用の設定で、最終品質のフレームを5〜10枚レンダリング","します。たとえばヒーローバトルのショットに6人のキャラクター、雨のFX、4K出力があるなら、実際に出荷するのと同じようにフレーム101〜110をレンダリングします。これより少ないテストは、自分を騙すことになります。",[215,8081,8082,8083,8086],{},"これらのフレームが終わったら、",[120,8084,8085],{},"バッチ内でのフレームあたり平均レンダリング時間を計算","します。10フレームが18〜26分の範囲で、平均してフレームあたり22分になるなら、その22分がベースラインです。",[215,8088,8089,8090,8093],{},"そのベースラインを得たら、",[120,8091,8092],{},"誰かに「バッファは？」と聞かれる前にバッファを追加","します。制作の現実はノイズを保証します。15〜30%のバッファは、作品の変動性によって健康的です。たとえば22分の平均が、25%のバッファ後に28分になるなら、避けられないルックデベロップのズレに対する余地を組み込めています。ライティングがロックされたスタイライズドなコマーシャルなら15%で十分かもしれません。一方で、まだ進化している最中の長編シーケンスなら30%のほうが安全で、それでも擁護可能です。",[215,8095,8096,8097,8100],{},"次に、ショー全体にスケールさせます。",[120,8098,8099],{},"バッファ込みの1フレーム時間に、総フレーム数を掛ける","のです。24fpsで90秒のシーケンスは2,160フレームです。1フレーム28分なら、60,480レンダリング分、つまり1,008時間あまりになります。200ノードのファームで各ノードが1フレームずつ処理するなら、理想的な分配と競合ゼロの前提で、壁時計（実時間）としては約5時間です。この前提は現実には成り立ちませんが、制作が議論するための具体的な材料になります。",[215,8102,8103,8104,8107],{},"次は",[120,8105,8106],{},"リビジョンのマージン","です。シーケンスのライフサイクル中に再レンダリングされる追加フレームは、10〜25%見込むべきです。過去の傾向が、クライアントの指示が典型的に2回の再レンダリングを引き起こすなら、20〜25%寄りにします。20%のリビジョンマージンは432フレームです。1フレーム28分なら、さらに201レンダリング時間分を予算化する必要があります。",[48,8109,8110,8111,8114],{},"そして先ほど触れたように、",[120,8112,8113],{},"ストレージや帯域幅といった隠れたコストを忘れないでください！"," 事前に計算し、その持続的なスループットにネットワークとディスクが実際に耐えられるか確認します。",[48,8116,8117,8118,8121],{},"これらすべてを組み合わせると、精査に耐える数字が得られます。",[120,8119,8120],{},"その数字は、コスト見積もりであると同時に制作上の制約でもあります","。シェーダーを最適化するか、ボリューメトリックを減らすか、ファーム容量を増やすか、あるいはスコープを再交渉するかを判断する材料になります。",[61,8123],{},[64,8125,508],{"id":507},[48,8127,8128],{},[94,8129],{"href":8130},"https://github.com/cgwire/blog/blob/main/drafts/render-cost-estimation/index.md?ref=blog.cg-wire.com#conclusion",[48,8132,8133,8136],{},[120,8134,8135],{},"レンダリングコストの見積もりは、結局のところ「不確実性を管理すること」だといえます。"," どんな見積もりも、遅れて入るクリエイティブ変更や予期せぬ技術的制約に触れると崩れます。実務的にはシンプルです。代表的なフレームで早期にテストし、直感ではなく測定データに基づいて投影し、リビジョンに対して現実的なバッファを追加し、実際のショットがファームに乗ったら継続的に再キャリブレーションします。すべてのプロジェクトはズレます。狙いは、そのズレを早期に検知し、パニックではなく計画で吸収することです。",[48,8138,8139,8140,8145],{},"その不確実性をさらに厳密に制御できるなら、",[94,8141,8144],{"href":8142,"rel":8143},"https://blog.cg-wire.com/flamenco-without-nas-kitsu/",[187],"レンダーファームのセルフホスティングを試すことを検討してみてください","。自社で運用すれば、クラウドの不透明な請求サマリーに頼るのではなく、パフォーマンス指標、障害率、キューの挙動、そして実際のショットごとのレンダリングコストを直接把握できます。数台のノードで短い社内プロジェクトを回すような小規模なパイロットでも、ボトルネックの発見、ベンチマークの検証、そして将来の見積もりに必要な履歴データの構築につながります。シーンの複雑さ、ハードウェアの性能、そしてスケジューリングの圧力の間にあるフィードバックループを自分の手で回せることは、レンダリングコスト見積もりを「当てずっぽう」から「運用上の強み」に変える最速の方法になり得ます。",[31,8147,8149,8152],{"className":8148},[34,35,36],[31,8150,524],{"className":8151},[40],[31,8153,8155,8156,8159],{"className":8154},[45],"アニメーション制作プロセスについてもっと知りたい方は",[94,8157,3875],{"href":531,"rel":8158},[533],"！ 私たちは、ベストプラクティスを共有する1,000人以上の専門家とつながっており、時には対面イベントを企画することもあります。ぜひ歓迎します！ 😊",[31,8161,8163],{"className":8162},[34,539,540],[94,8164,546],{"href":531,"className":8165},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":8167},[8168,8169,8170,8171,8172,8173,8174],{"id":7846,"depth":548,"text":7847},{"id":7877,"depth":548,"text":7878},{"id":7935,"depth":548,"text":7936},{"id":7961,"depth":548,"text":7962},{"id":7996,"depth":548,"text":7997},{"id":8055,"depth":548,"text":8056},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1719014745427-663137ae50f6?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fGFuaW1hdGlvbiUyMHJlbmRlcmluZ3xlbnwwfHx8fDE3NzMwMzg3NTR8MA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":8177,"featured_at":561,"visibility":562},"2026-03-09T07:51:00.000+01:00","/blog-i18n/ja/estimating-render-costs-animation",{"title":7811,"description":12},"estimating-render-costs-animation","blog-i18n/ja/estimating-render-costs-animation/index",[8183],{"id":987,"name":988,"slug":989,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":990},"93DfVcKPcKHZFECeD_RgJVdZWbZYbdsu1k9t-NxW_c4",{"id":8186,"title":8187,"authors":8188,"body":8190,"description":12,"extension":557,"feature_image":8859,"html":7,"meta":8860,"navigation":13,"path":8862,"published_at":8863,"seo":8864,"slug":8865,"stem":8866,"tags":8867,"__hash__":8869,"updated_at":8861,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/ffmpeg-commands-for-animators/index.md","アニメーターが2026年に知っておくべきFFmpegコマンド10選",[8189],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":8191,"toc":8845},[8192,8210,8213,8216,8219,8221,8227,8230,8253,8256,8258,8264,8270,8273,8279,8318,8320,8326,8334,8337,8343,8372,8374,8380,8383,8386,8392,8418,8428,8430,8436,8439,8442,8448,8476,8484,8487,8493,8495,8501,8504,8507,8513,8539,8541,8547,8550,8553,8559,8591,8593,8599,8602,8609,8615,8635,8637,8643,8646,8652,8658,8674,8682,8684,8690,8693,8703,8709,8726,8736,8742,8748,8756,8758,8764,8767,8770,8773,8779,8782,8788,8802,8804,8808,8811,8814,8825,8839],[31,8193,8195,8199],{"className":8194},[34,35,36],[31,8196,8198],{"className":8197},[40],"📼",[31,8200,8202,8203,8209],{"className":8201},[45],"動画変換ツールは編集者だけのものだと思っていませんか？その考えは改めましょう。FFmpegは、あらゆるアニメーションのパイプラインに隠れている“秘密兵器”です。YouTube、Blender、DaVinci Resolveのようなスタジオでも使われており、使い方が分かれば",[6392,8204,8205],{},[655,8206,8208],{"className":8207,"style":122},[6397],"手作業を何時間も","節約できます。",[48,8211,8212],{},"アニメーションや映像制作の仕事をしているなら、すでにFFmpegに出会っているはずです。",[48,8214,8215],{},"オープンソースで、YouTube、Blender、DaVinci Resolveのような巨大な存在によって使われているにもかかわらず、FFmpegは裏方に隠れがちで、その価値を知っているアーティストは多くありません。",[48,8217,8218],{},"このガイドでは、手作業の時間を何時間も節約するために、アニメーターやパイプライン担当者が知っておくべき実用的なFFmpegコマンド10個を順に紹介します。",[61,8220],{},[64,8222,8224],{"id":8223},"whats-ffmpeg",[120,8225,8226],{},"FFmpegとは？",[48,8228,8229],{},"FFmpegは、映像・音声・画像データを扱うための強力なオープンソースのコマンドラインツールキットです。これは単一のプログラムというより、想像できるほぼすべてのメディア処理タスクを扱う一連のツールです：",[212,8231,8232,8235,8238,8241,8244,8247,8250],{},[215,8233,8234],{},"ほぼあらゆる映像・音声・画像フォーマット間で変換。",[215,8236,8237],{},"画像シーケンスをムービーに組み立て（その逆も可能）。",[215,8239,8240],{},"レビューやアップロード用に大きなファイルを圧縮／トランスコード。",[215,8242,8243],{},"フィルター：トリミング、スケーリング、カラー調整、オーバーレイ、ぼかしなど。",[215,8245,8246],{},"複数の音声／映像ソースを同期または結合。",[215,8248,8249],{},"メディアのメタデータ解析（フレームレート、コーデック、ビット深度など）。",[215,8251,8252],{},"スクリプトによるパイプラインでのバッチ処理の自動化。",[48,8254,8255],{},"ここに搭載されている“便利機能”をすべて挙げることはできませんが、まずは実用的なFFmpegコマンド10個を、すぐにターミナルへ貼り付けられる例とともに始めましょう。",[61,8257],{},[64,8259,8261],{"id":8260},"_1-compile-an-image-sequence-into-a-video",[120,8262,8263],{},"1. 画像シーケンスを動画にまとめる",[48,8265,8266,8269],{},[94,8267,8268],{"href":2759},"Blenderのようなレンダラー","では、単一のムービーファイルではなく、画像シーケンス（例：何千ものEXRやPNG）を出力できます。レンダーがクラッシュしてもそこから再開できるので、これなら安全です。問題は、そうしたシーケンスは再生できなかったり、レビューしづらかったりすることです。",[48,8271,8272],{},"FFmpegは数秒で全フレームを1つの動画ファイルに“つなぎ”、ショットの軽量で共有しやすいバージョンを作れます：",[152,8274,8275],{},[155,8276,8278],{"className":8277},[158],"ffmpeg -framerate 24 -i frame_%04d.png -c:v libx264 -pix_fmt yuv420p output.mp4",[212,8280,8281,8287,8300,8306,8312],{},[215,8282,8283,8286],{},[155,8284,8285],{},"-framerate 24"," - 24フレーム毎秒でシーケンスを読み取るようFFmpegに指示します。",[215,8288,8289,8292,8293,658,8296,8299],{},[155,8290,8291],{},"-i frame_%04d.png - %04d","は、ゼロで埋めて4桁にすることを意味します（例：",[155,8294,8295],{},"0001",[155,8297,8298],{},"0002"," …）。シーケンスが1000フレームを超える場合は、より多くの桁が必要です。",[215,8301,8302,8305],{},[155,8303,8304],{},"-c:v libx264"," - H.264コーデックで動画をエンコードし、レビュー用途のよいデフォルトになります。",[215,8307,8308,8311],{},[155,8309,8310],{},"-pix_fmt yuv420p"," - 幅広い互換性を確保します（特にメディアプレーヤーやブラウザで）。",[215,8313,8314,8317],{},[155,8315,8316],{},"output.mp4"," - 最終的な動画ファイル名です。",[61,8319],{},[64,8321,8323],{"id":8322},"_2-create-a-quick-low-res-review",[120,8324,8325],{},"2. すぐに低解像度のレビュー用を作る",[48,8327,8328,8329,8333],{},"高解像度レンダー（4K、フル品質のEXR、またはProRes）が数GBもあると、",[94,8330,8332],{"href":8331},"https://blog.cg-wire.com/how-to-give-efficient-animation-feedback/","フィードバックのためにSlackに送るのには重すぎます","：日々のレビューには、より小さくて高速に読み込めるバージョンが必要です。",[48,8335,8336],{},"マスタービデオをスケール＆圧縮するだけで、再レンダーせずに再生可能な版を自動的に作れます：",[152,8338,8339],{},[155,8340,8342],{"className":8341},[158],"ffmpeg -i output.mp4 -vf scale=960:-1 -b:v 1M review.mp4",[212,8344,8345,8351,8360,8366],{},[215,8346,8347,8350],{},[155,8348,8349],{},"-i output.mp4"," - 入力ファイル（高品質レンダー）。",[215,8352,8353,8356,8357,1498],{},[155,8354,8355],{},"-vf scale=960:-1"," - 動画の幅を960ピクセルにリサイズし、アスペクト比を保つために高さは自動調整します（",[155,8358,8359],{},"-1",[215,8361,8362,8365],{},[155,8363,8364],{},"-b:v 1M"," - ビットレートを1メガビット毎秒に設定します。低サイズ／高スピードのよい妥協案です。",[215,8367,8368,8371],{},[155,8369,8370],{},"review.mp4"," - 出力ファイル。",[61,8373],{},[64,8375,8377],{"id":8376},"_3-overlay-a-logo-or-watermark",[120,8378,8379],{},"3. ロゴやウォーターマークをオーバーレイする",[48,8381,8382],{},"スタジオやフリーランスは、制作途中のファイルを共有することがよくあります。しかしウォーターマークがないと、プレビューが再配布されたり流出したり、最終版と混同されたりします。",[48,8384,8385],{},"単一のFFmpegコマンドで、スタジオのロゴ、ユーザー名、または「制作途中（Work In Progress）」のタグを、すべてのフレームに重ねられます。",[152,8387,8388],{},[155,8389,8391],{"className":8390},[158],"ffmpeg -i input.mp4 -i logo.png -filter_complex \"overlay=10:10\" branded.mp4",[212,8393,8394,8400,8406,8412],{},[215,8395,8396,8399],{},[155,8397,8398],{},"-i input.mp4"," - メイン動画。",[215,8401,8402,8405],{},[155,8403,8404],{},"-i logo.png"," - オーバーレイする画像（透過がある必要があります。ないと無地の四角になります）。",[215,8407,8408,8411],{},[155,8409,8410],{},"-filter_complex \"overlay=10:10\""," - オーバーレイフィルターを適用し、ロゴを左上から10pxの位置に配置します。",[215,8413,8414,8417],{},[155,8415,8416],{},"branded.mp4"," - ウォーターマークを適用した結果。",[72,8419,8421],{"className":8420},[34,75],[77,8422],{"src":8423,"className":8424,"alt":12,"loading":82,"width":8425,"height":8426,"srcSet":8427,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-44bab5d8-5532-4d0b-9347-12812a0e1271.png",[81],848,527,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-44bab5d8-5532-4d0b-9347-12812a0e1271.png 600w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-44bab5d8-5532-4d0b-9347-12812a0e1271.png 848w",[61,8429],{},[64,8431,8433],{"id":8432},"_4-burn-frame-numbers-or-timecode",[120,8434,8435],{},"4. フレーム番号またはタイムコードを焼き付ける",[48,8437,8438],{},"クライアントやチームのレビューでは、ノート用に誰もが正確なフレームを参照する必要があります。そのためラベルのない映像だと、フィードバックを揃えることができません。",[48,8440,8441],{},"FFmpegのdrawtextフィルターを使えば、フレーム番号や再生中のタイムコードを動画に焼き込んで、正確な参照システムを提供できます。これにより、レビュー中に進行管理者やアニメーターが同期しやすくなります。",[152,8443,8444],{},[155,8445,8447],{"className":8446},[158],"ffmpeg -i input.mp4 -vf \"drawtext=text='%{n}':x=10:y=H-th-10:fontsize=24:fontcolor=white\" numbered.mp4",[212,8449,8450,8455,8461,8467],{},[215,8451,8452,8454],{},[155,8453,2871],{},"フィルターが、各フレームにテキストを描画します。",[215,8456,8457,8460],{},[155,8458,8459],{},"text='%{n}'"," - フレーム番号を挿入します。",[215,8462,8463,8466],{},[155,8464,8465],{},"x=10:y=H-th-10"," - 左下から10pxの位置に配置します。",[215,8468,8469,658,8472,8475],{},[155,8470,8471],{},"fontsize",[155,8473,8474],{},"fontcolor"," - 見た目の制御。",[72,8477,8479],{"className":8478},[34,75],[77,8480],{"src":8481,"className":8482,"alt":12,"loading":82,"width":8425,"height":8426,"srcSet":8483,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-84b1c23e-6e65-493e-bf3c-96c254d28234.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-84b1c23e-6e65-493e-bf3c-96c254d28234.png 600w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-84b1c23e-6e65-493e-bf3c-96c254d28234.png 848w",[48,8485,8486],{},"また、提示タイムスタンプ（PTS）を時間：分：秒の形式で使ってタイムコードを表示することもできます：",[152,8488,8489],{},[155,8490,8492],{"className":8491},[158],"ffmpeg -i input.mp4 -vf \"drawtext=text='%{pts\\:hms}':x=10:y=H-th-10:fontsize=24:fontcolor=white\" timecode.mp4",[61,8494],{},[64,8496,8498],{"id":8497},"_5-create-looping-clips-turntables",[120,8499,8500],{},"5. ループするクリップ（回転台）を作る",[48,8502,8503],{},"3Dモデルやショットを提示するときは、ポートフォリオ、社内ライブラリ、デモリール向けに、ループする回転台が必要になることがよくあります。エディターでクリップを手作業で複製するのは面倒です。",[48,8505,8506],{},"FFmpegなら、-stream_loopで指定した回数だけ任意のクリップをループできます。再レンダーせずに、連続再生を即座に作成：",[152,8508,8509],{},[155,8510,8512],{"className":8511},[158],"ffmpeg -stream_loop 3 -i turntable.mp4 -c copy looped.mp4",[212,8514,8515,8521,8527,8533],{},[215,8516,8517,8520],{},[155,8518,8519],{},"-stream_loop 3"," - 入力をさらに3回分再生します。",[215,8522,8523,8526],{},[155,8524,8525],{},"-i turntable.mp4"," - 元のアニメーション。",[215,8528,8529,8532],{},[155,8530,8531],{},"-c copy"," - 再エンコードせずに音声／映像ストリームをコピーします（高速・ロスレス）。",[215,8534,8535,8538],{},[155,8536,8537],{},"looped.mp4"," - 最終出力。",[61,8540],{},[64,8542,8544],{"id":8543},"_6-add-sound-to-a-silent-render",[120,8545,8546],{},"6. 無音レンダーに音を追加する",[48,8548,8549],{},"3Dソフトからのレンダーには音声が含まれません。たとえアニメーションがセリフや音楽に同期していても、PremiereやAfter Effectsで手動に音を足す作業は、素早いプレビューのためには手間になりがちです。",[48,8551,8552],{},"FFmpegなら、無音レンダーに音声トラックを即座に結合でき、タイムラインベースのエディターなしで同期も取れます。",[152,8554,8555],{},[155,8556,8558],{"className":8557},[158],"ffmpeg -i render.mp4 -i music.wav -c:v copy -c:a aac -shortest final.mp4",[212,8560,8561,8567,8573,8579,8585],{},[215,8562,8563,8566],{},[155,8564,8565],{},"-i render.mp4"," - 動画入力。",[215,8568,8569,8572],{},[155,8570,8571],{},"-i music.wav"," - 音声入力。",[215,8574,8575,8578],{},[155,8576,8577],{},"-c:v copy"," - 既存の動画ストリームを維持します（再レンダーなし）。",[215,8580,8581,8584],{},[155,8582,8583],{},"-c:a aac"," - 音声をAACにエンコードします（広く対応）。",[215,8586,8587,8590],{},[155,8588,8589],{},"-shortest"," - 2つのトラックのうち短い方が終わった時点でエンコードを停止します。",[61,8592],{},[64,8594,8596],{"id":8595},"_7-extract-every-nth-frame",[120,8597,8598],{},"7. N番ごとのフレームを抽出する",[48,8600,8601],{},"長いショットのすべてのフレームを確認するのは遅いです。特にモーション分析、フリッカー検出、露出の変化チェックでは時間がかかります。そんなとき、10枚おきや20枚おきのように、サンプルとして取り出せれば十分なこともあります。",[48,8603,8604,8605,8608],{},"FFmpegの",[155,8606,8607],{},"select","フィルターで、n番ごとのフレームを自動的に抽出できます。素早いモーション診断、コンタクトシートの作成、サムネイルの生成に最適です：",[152,8610,8611],{},[155,8612,8614],{"className":8613},[158],"ffmpeg -i input.mp4 -vf \"select='not(mod(n,10))',setpts=N/FRAME_RATE/TB\" frames_%04d.png",[212,8616,8617,8623,8629],{},[215,8618,8619,8622],{},[155,8620,8621],{},"select='not(mod(n,10))'"," - フレーム番号nが10で割り切れるフレームだけを処理します（10枚ごと）。",[215,8624,8625,8628],{},[155,8626,8627],{},"setpts=N/FRAME_RATE/TB"," - 出力が速すぎて再生されないよう、タイムスタンプを補正します。",[215,8630,8631,8634],{},[155,8632,8633],{},"frames_%04d.png"," - 抽出画像の命名パターン。",[61,8636],{},[64,8638,8640],{"id":8639},"_8-compare-two-versions-ab-diff",[120,8641,8642],{},"8. 2つのバージョンを比較する（A/B Diff）",[48,8644,8645],{},"ライティングの微調整、カラー補正、ノイズ除去の更新をテストするとき、目視で2つのバージョンの小さな差を見分けるのは難しいです。",[48,8647,8604,8648,8651],{},[155,8649,8650],{},"blend=all_mode=difference","フィルターは、あるバージョンからもう一方を差し引いて、差分を明るいピクセルとして表示します。バージョン変更のQAを素早く行う方法として便利です。",[152,8653,8654],{},[155,8655,8657],{"className":8656},[158],"ffmpeg -i old.mp4 -i new.mp4 -filter_complex \"blend=all_mode=difference\" diff.mp4",[212,8659,8660,8663,8668],{},[215,8661,8662],{},"2つの入力ファイル：旧版と新版のレンダー。",[215,8664,8665,8667],{},[155,8666,8650],{}," - 片方のピクセル値をもう片方から引き算し、どこが違うかを示します。",[215,8669,8670,8673],{},[155,8671,8672],{},"diff.mp4"," - 明るいピクセル＝変更点、暗い＝差なし。",[72,8675,8677],{"className":8676},[34,75],[77,8678],{"src":8679,"className":8680,"alt":12,"loading":82,"width":8425,"height":8426,"srcSet":8681,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-57adc37e-d8c2-407a-9057-1739a959c61f.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-57adc37e-d8c2-407a-9057-1739a959c61f.png 600w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-57adc37e-d8c2-407a-9057-1739a959c61f.png 848w",[61,8683],{},[64,8685,8687],{"id":8686},"_9-combine-render-passes-side-by-side",[120,8688,8689],{},"9. レンダーパスを左右（上下）に並べる",[48,8691,8692],{},"アーティストはしばしば2つのパス（例：旧版 vs 新版）を比較する必要があります。比較のためだけにコンポジットソフトで開くのは過剰です。",[48,8694,8695,8698,8699,8702],{},[155,8696,8697],{},"hstack","（または",[155,8700,8701],{},"vstack","）フィルターは、動画を横並びまたは縦並びに配置して簡単に比較できるようにします。レビュー書き出しや、クライアント／進行管理者向けに変更点を示すビフォー／アフター動画に最適です。",[152,8704,8705],{},[155,8706,8708],{"className":8707},[158],"ffmpeg -i pass1.mp4 -i pass2.mp4 -filter_complex \"hstack\" side_by_side.mp4",[212,8710,8711,8714,8721],{},[215,8712,8713],{},"2つの入力動画。",[215,8715,8716,8718,8719,166],{},[155,8717,8697],{}," - 水平方向にスタックします。縦に並べたい場合は",[155,8720,8701],{},[215,8722,8723,8371],{},[155,8724,8725],{},"side_by_side.mp4",[72,8727,8729],{"className":8728},[34,75],[77,8730],{"src":8731,"className":8732,"alt":12,"loading":82,"width":8733,"height":8734,"srcSet":8735,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-77024499-0432-4930-97d8-c1aa0942c2e9.png",[81],1186,748,"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-77024499-0432-4930-97d8-c1aa0942c2e9.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-77024499-0432-4930-97d8-c1aa0942c2e9.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-77024499-0432-4930-97d8-c1aa0942c2e9.png 1186w",[48,8737,8738,8739,8741],{},"さらに、前の",[155,8740,8650],{},"コマンドで作った結果動画も含めて、フレーム間の差を素早く確認することもできます：",[152,8743,8744],{},[155,8745,8747],{"className":8746},[158],"ffmpeg -i pass1.mp4 -i diff.mp4 -i pass2.mp4 \\\n-filter_complex \"[0:v][1:v]hstack=inputs=2[top]; [top][2:v]hstack=inputs=2\" \\\nside_by_side2.mp4",[72,8749,8751],{"className":8750},[34,75],[77,8752],{"src":8753,"className":8754,"alt":12,"loading":82,"width":8733,"height":8734,"srcSet":8755,"sizes":86},"https://blog.cg-wire.com/content/images/2025/11/data-src-image-3179b0a2-949d-468c-ba70-153ae97f0d0c.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/11/data-src-image-3179b0a2-949d-468c-ba70-153ae97f0d0c.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/11/data-src-image-3179b0a2-949d-468c-ba70-153ae97f0d0c.png 1000w, https://blog.cg-wire.com/content/images/2025/11/data-src-image-3179b0a2-949d-468c-ba70-153ae97f0d0c.png 1186w",[61,8757],{},[64,8759,8761],{"id":8760},"_10-re-time-animation-slow-mo-or-speed-up",[120,8762,8763],{},"10. アニメーションの再タイミング（スローモーション／高速化）",[48,8765,8766],{},"プレビューで遅いカメラ移動を試したり、素早いモーションテストを確認したりするようなタイミング調整は、通常リレンダーやソフトでの編集が必要になります。それなのに、テンポを変える試行だけをするために非効率です。",[48,8768,8769],{},"FFmpegなら、フレームのタイムスタンプを調整して再生速度をその場で変更し、アニメーターが別の速度をすぐにプレビューできるようにできます。",[48,8771,8772],{},"半分の速度にする：",[152,8774,8775],{},[155,8776,8778],{"className":8777},[158],"ffmpeg -i input.mp4 -filter:v \"setpts=2.0*PTS\" slowmo.mp4",[48,8780,8781],{},"2倍の速度にする：",[152,8783,8784],{},[155,8785,8787],{"className":8786},[158],"ffmpeg -i input.mp4 -filter:v \"setpts=0.5*PTS\" fast.mp4",[212,8789,8790,8796,8799],{},[215,8791,8792,8795],{},[155,8793,8794],{},"setpts","フィルターは、各フレームの提示タイムスタンプ（PTS）を操作します。",[215,8797,8798],{},"2.0倍すると再生時間が2倍になり（遅くなる）、",[215,8800,8801],{},"0.5倍すると半分になり（速くなる）。",[61,8803],{},[64,8805,8806],{"id":507},[120,8807,508],{},[48,8809,8810],{},"FFmpegは単なる動画変換ツールではありません。テキストを数行書くだけで、従来のソフトで通常は数分〜数時間かかる作業を自動化できます：バッチレンダー、バージョン比較、レビュー用書き出し…お好みで。",[48,8812,8813],{},"構文に慣れたら、FFmpegはあなたのクリエイティブなワークフローの拡張になります。このリストから1つコマンドを選んで、次のレンダーパイプラインにそのまま投入し、日々の制作がどれだけスムーズになるか見てみてください！",[48,8815,8816,8817,8820,8821,8824],{},"でも、それだけではありません。ffmpegの力をDCCスクリプト（例：",[94,8818,8819],{"href":1015},"Blenderスクリプト","）と組み合わせれば、人間の理解を超えるほどの“スーパーパワー”（たとえば、シーンの作成全体を自動化するなど）を解放できます。",[94,8822,8823],{"href":6415},"ブログを購読","して、さらにどうぞ！",[31,8826,8828,8831],{"className":8827},[34,35,36],[31,8829,524],{"className":8830},[40],[31,8832,8834,8835,8838],{"className":8833},[45],"アニメーション制作プロセスについてもっと学ぶには ",[94,8836,3875],{"href":531,"rel":8837},[533],"！私たちは、ベストプラクティスを共有する1000人以上の専門家とつながっており、時には実際のイベントも企画しています。ぜひ皆さんを歓迎します！😊",[31,8840,8842],{"className":8841},[34,539,540],[94,8843,546],{"href":531,"className":8844},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":8846},[8847,8848,8849,8850,8851,8852,8853,8854,8855,8856,8857,8858],{"id":8223,"depth":548,"text":8226},{"id":8260,"depth":548,"text":8263},{"id":8322,"depth":548,"text":8325},{"id":8376,"depth":548,"text":8379},{"id":8432,"depth":548,"text":8435},{"id":8497,"depth":548,"text":8500},{"id":8543,"depth":548,"text":8546},{"id":8595,"depth":548,"text":8598},{"id":8639,"depth":548,"text":8642},{"id":8686,"depth":548,"text":8689},{"id":8760,"depth":548,"text":8763},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1727142073871-d40f5a7c76d8?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDMwfHx2aWRlbyUyMGVuY29kaW5nJTIwdGVybWluYWx8ZW58MHx8fHwxNzYyMjQ1NjQ3fDA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":8861,"featured_at":561,"visibility":562},"2026-02-20T06:04:25.000+01:00","/blog-i18n/ja/ffmpeg-commands-for-animators","2025-11-04T10:09:54.000+01:00",{"title":8187,"description":12},"ffmpeg-commands-for-animators","blog-i18n/ja/ffmpeg-commands-for-animators/index",[8868],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"CkKha0MNY6WKs8W5cm5W5Y91KfhF7jBSEExmzz1O9w8",{"id":8871,"title":8872,"authors":8873,"body":8875,"description":12,"extension":557,"feature_image":9362,"html":7,"meta":9363,"navigation":13,"path":9364,"published_at":9365,"seo":9366,"slug":9367,"stem":9368,"tags":9369,"__hash__":9371,"updated_at":8861,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/flamenco-without-nas-kitsu/index.md","Kitsu連携によるNAS不要のフラメンコレンダリング（2026）",[8874],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":8876,"toc":9352},[8877,8887,8890,8893,8900,8903,8906,8909,8935,8937,8941,8944,8949,8952,8955,8958,8961,8963,8967,8970,8973,8986,8993,8996,9002,9005,9012,9018,9021,9024,9030,9032,9036,9041,9048,9054,9057,9060,9062,9066,9069,9081,9103,9106,9172,9175,9177,9181,9189,9210,9213,9216,9218,9222,9230,9233,9239,9242,9244,9248,9251,9261,9290,9293,9301,9304,9307,9310,9312,9314,9317,9320,9323,9326,9333,9346],[31,8878,8880,8883],{"className":8879},[34,35,36],[31,8881,3916],{"className":8882},[40],[31,8884,8886],{"className":8885},[45],"Kitsuにレンダーコンテキストとファイルを担わせることで、共有ストレージなしにFlamencoを実行できます。",[48,8888,8889],{},"Flamencoを使いたいけれど、NASは買いたくないのですね。",[48,8891,8892],{},"ソロアーティストやマイクロなアニメーションスタジオであれば、それは完全に合理的な判断です。共有ストレージは高価になりがちで、メンテナンスの手間も増え、レンダーファームを実際に回してみないと気づかない問題を、たとえ解決できたとしてもそれが本当に必要だったかは別問題だからです。",[48,8894,8895,8899],{},[94,8896,8898],{"href":8897},"https://blog.cg-wire.com/self-hosted-blender-render-farm","Flamencoは従来型のスタジオ構成を前提にしています","：共有ファイル、共有パス、即時アクセス。NASがない状況では、その前提を回避するのが難しくなります。Flamencoには制作環境（production context）の概念がないため、「どのショットをレンダリングしたいのか」「どのバージョンが承認されているのか」「ジョブファイルがどこにあるのか」を理解できません。そして、その情報がないと、NASレス環境では安全に動作できないのです。",[48,8901,8902],{},"そこで登場するのがKitsuです。",[48,8904,8905],{},"Kitsuは、Flamencoが持っていない情報をすでに知っています。タスク、ショット、バージョン、承認状況です。Kitsuを非同期のネットワークストレージとして扱えば、必要なタイミングでデータをFlamencoマネージャーへ移し、レンダリングし、共有ストレージに依存せずに済みます。",[48,8907,8908],{},"ただし、Flamencoはこのワークフローを標準でサポートしていません。動かすには、Kitsuからコンテキストとファイルを取得し、それらをローカルに段階的に配置し、いつ・どのようにレンダリングを実行するかを制御するカスタムのFlamencoジョブタイプを作る必要があります。この記事では、そのための具体的な作り方を紹介します。",[31,8910,8912,8915],{"className":8911},[34,35,108],[31,8913,112],{"className":8914},[40],[31,8916,8918,8922,8924,8926,8927,8929,134,8931],{"className":8917},[45],[117,8919,8920],{},[120,8921,623],{"style":122},[125,8923],{},[125,8925],{},"このガイドで紹介している例の統合について、完全なソースコードはGitHubで確認できます。",[125,8928],{},[125,8930],{},[94,8932,8934],{"href":8933},"https://github.com/cgwire/blog-tutorials/tree/main/flamenco-kitsu-render-farm?ref=blog.cg-wire.com","https://github.com/cgwire/blog-tutorials/tree/main/flamenco-kitsu-render-farm",[61,8936],{},[64,8938,8940],{"id":8939},"high-level-architecture","全体アーキテクチャ",[48,8942,8943],{},"私たちの構成は、シンプルな考え方に基づいています。Flamencoがレンダリングを行い、Kitsuが真実（正）を提供する、ということです。",[152,8945,8946],{},[155,8947,8948],{},"Kitsu\n  ↑↓ (REST API)\nCustom Flamenco Job Type\n  ├── Pre-task Python (fetch task data & files)\n  ├── Blender render tasks (Flamenco-managed)\n  └── Post-task Python (upload renders back to Kitsu)\nFlamenco Manager\n  ↓\nFlamenco Worker(s)\n",[48,8950,8951],{},"Flamencoは意図どおりに動きます。マネージャーが作業をスケジューリングし、ワーカーがBlenderタスクを実行します。変わるのは、ジョブの定義方法です。Flamencoを共有フォルダへ向けて、すべてのマシンが同じファイルを見られることに賭けるのではなく、制作データを理解しKitsuと通信できるカスタムのFlamencoジョブタイプを導入します。",[48,8953,8954],{},"Kitsuはファームの外側にあり、REST APIを通じてすべてを公開します。ショット、タスク、バージョン、ファイルの場所です。レンダージョブが開始されると（手動でも自動でも）、カスタムのジョブタイプがKitsuへ問い合わせて、何をレンダリングすべきかを正確に特定します。たとえば「ショット020の最新の承認済みライティングバージョンをください」と尋ねるかもしれません。Kitsuが答え、その答えがレンダージョブになります。",[48,8956,8957],{},"Flamenco側では、マネージャーはKitsuをポーリングせず、制作の状態を追跡もしません。単に、渡されたジョブ定義を実行するだけです。カスタムジョブタイプは、小さなPythonのプリタスクを使ってKitsuからメタデータとファイルを取得し、ジョブフォルダにローカルで配置してから、Flamencoが効率よく管理できる標準のBlenderレンダータスクへ引き渡します。",[48,8959,8960],{},"レンダリングが完了すると、ポストタスクのPythonステップが結果をKitsuへ送り返し、レンダリングされたフレームをアップロードしたり、新しいバージョンを作ったり、タスクのステータスを更新したりします。作業員（ワーカー）が共有ストレージを必要としたり、同じファイルシステムへ恒久的にアクセスする必要は、一切ありません。各ワーカーが必要なものを取り出してローカルでレンダリングし、結果を非同期にプッシュします。",[61,8962],{},[64,8964,8966],{"id":8965},"_1-creating-a-new-job-type","1. 新しいジョブタイプを作成する",[48,8968,8969],{},"Flamencoのジョブタイプは、ジョブが実際の作業にどう変換されるかを定義します。「これをレンダリングしたい」という要求から、ファーム全体に対してFlamencoがスケジューリングする具体的なタスクへと変換する層です。概念的には、ジョブタイプは必要な情報と、その情報をタスクへ組み立てる方法を宣言します。",[48,8971,8972],{},"最も単純な形では、ジョブタイプはラベルと設定のセットを説明し、その設定を受け取ってジョブを組み立てる関数を提供します。コード上では、次のようなイメージです：",[152,8974,8975,8980],{},[155,8976,8979],{"className":8977},[8978],"language-js","const JOB_TYPE = {\n  label: \"Kitsu Render\",\n  settings: [\n    // { key: \"message\", type: \"string\", required: true },\n    // { key: \"sleep_duration_seconds\", type: \"int32\", default: 1 },\n  ],\n};\n",[48,8981,8982],{},[155,8983,8985],{"className":8984},[8978],"function compileJob(job) {\nconst settings = job.settings;\n}\n",[48,8987,8988,8989,8992],{},"このコードは、カスタムのFlamencoジョブタイプの骨組みを定義します。",[155,8990,8991],{},"JOB_TYPE","オブジェクトは、Flamenco上でのジョブの見え方を宣言します。つまり、人が読めるラベルと、ジョブ作成時に想定される設定です。",[48,8994,8995],{},"これらの設定は、型付きの入力として機能し、バリデーションはFlamencoが担当します。この例では、必須の文字列と、デフォルト値を持つ任意の整数です。",[48,8997,8998,9001],{},[155,8999,9000],{},"compileJob","関数は、ジョブを実行可能なタスクへ変換する場所です。送信されたジョブを受け取り、解決された設定を読み取り、通常はそれらを使ってレンダ、プリタスク、ポストタスクのステップを生成します。現状のままではまだ何も処理していませんが、制作ロジックが置かれる入口を確立しています。",[48,9003,9004],{},"実際の制作環境では、汎用のメッセージの代わりに、KitsuのタスクID、ショット名、希望する出力先、あるいは使用するべきBlenderバージョンなどを渡します。",[48,9006,9007,9008,9011],{},"このロジックがどこに置かれるかは重要です。カスタムのFlamencoジョブタイプは、ワーカーではなく",[120,9009,9010],{},"Flamenco Manager","上で動作します。ディスク上では、たとえば次のようにマネージャープログラムの隣に配置されます：",[152,9013,9014],{},[155,9015,9017],{"className":9016},[158],"$ flamenco\n└── flamenco-manager\n└── scripts/\n└── kitsu-render.js\n",[48,9019,9020],{},"実務では、スタジオはこれらのジョブタイプスクリプトをパイプラインのコードベースの一部として扱います。バージョン管理下に置かれ、時間とともに進化し、Flamencoのアップデートと一緒にデプロイされます。そうすれば、ファーム上のすべてのワーカーマシンを再デプロイや再設定せずに、ジョブの組み立て方法やKitsuへの問い合わせ方法を変更できます。",[48,9022,9023],{},"カスタムのジョブタイプからコマンドとして呼び出されるワーカースクリプトは、flamenco-workerプログラムの隣に配置します：",[152,9025,9026],{},[155,9027,9029],{"className":9028},[158],"$ flamenco\n└── flamenco-worker\n└── kitsu-render.py\n",[61,9031],{},[64,9033,9035],{"id":9034},"_2-adding-tasks","2. タスクを追加する",[48,9037,9038,9040],{},[155,9039,9000],{},"の内部では、ジョブを構成するタスクを明示的に定義します。ここが、「このショットをレンダリングしてほしい」という高レベルな要求が、Flamencoがワーカーへ引き渡せる具体的でスケジュール可能な作業へ変換される場所です。",[48,9042,9043,9044,9047],{},"下の例は、最もシンプルなタスクです。",[155,9045,9046],{},"echo","タスクをFlamencoのタスク作成APIで作成し、カテゴリを与えたうえで、単一のコマンドを割り当てます。このコマンドは、解決されたジョブ設定をタスクへ渡し、タスクが実行されるとメッセージを表示します。最後に、そのタスクをジョブへ追加して、マネージャーがスケジュールできるようにします。",[152,9049,9050],{},[155,9051,9053],{"className":9052},[8978],"const echoTask = author.Task(\"echo\", \"misc\");\nechoTask.addCommand(\nauthor.Command(\"echo\", {\nmessage: settings.message,\n}),\n);\njob.addTask(echoTask);\n",[48,9055,9056],{},"このタスク自体は有用なことはしませんが、重要なのはこのパターンです。同じ仕組みを使ってPythonスクリプトを実行したり、レンダリングのためにBlenderをバックグラウンドモードで起動したり、タスクが完了とみなされる前にバリデーションチェックを行ったりできます。各タスクは原子的で再起動可能な設計になっており、つまり、ワーカーがクラッシュしたり、午前3時にレンダが失敗したとしても、Flamencoはジョブ全体を崩さずにそのタスクだけを再試行できます。この信頼性こそが、このアプローチが夜通しで何百ものショットを回す際にスケールする理由です。",[48,9058,9059],{},"それでは、チュートリアルの本題に入りましょう。Kitsuからアセットをダウンロードし、Blenderでレンダリングし、結果をKitsuへ再アップロードするタスクをコード化します。",[61,9061],{},[64,9063,9065],{"id":9064},"_3-subcommand-1-downloading-assets-from-kitsu","3. サブコマンド1：Kitsuからアセットをダウンロードする",[48,9067,9068],{},"Kitsu主導のジョブで最初に行う本格的なタスクは、必要な正確なデータをKitsuから取り出し、ワーカー上にクリーンなローカルワークスペースを用意することです。Blenderが起動される前に、ワーカーは「どのタスクをレンダリングするのか」と「ジョブファイルがどこにあるのか」を把握している必要があります。",[48,9070,9071,9072,9075,9076,9080],{},"ロジックをJavaScriptで書く代わりに、よりシンプルなgazur Python SDKを使って",[155,9073,9074],{},"kitsu-render","スクリプトを作成し、それをJavaScriptから呼び出します。ワーカー環境にPythonがインストールされていない場合は、",[94,9077,9079],{"href":9078},"https://blog.cg-wire.com/kitsu-cli-single-binary/","Pythonスクリプトからバイナリ実行ファイルを作る","ことを検討してください。",[152,9082,9083,9097],{},[155,9084,9086,9087,9090],{"className":9085},[8978],"function compileJob(job) {\nconst settings = job.settings;",[48,9088,9089],{},"const task = author.Task(\"kitsu-render\", \"misc\");",[48,9091,9092,9093,9096],{},"task.addCommand(\nauthor.Command(\"exec\", { exe: \"python3\", args: ",[263,9094,9095],{},"\"kitsu-render.py\""," }),\n);",[48,9098,9099],{},[155,9100,9102],{"className":9101},[8978],"job.addTask(task);\n}\n",[48,9104,9105],{},"PythonスクリプトはKitsu APIへ認証し、TODOレンダリングタスクを探し、レンダリングするための.blendプロジェクトを含む関連するプレビュー・ファイルをダウンロードします。",[152,9107,9108,9166],{},[155,9109,9111,9112,9119,9123,9125,9128,9145,9148,9154,9157],{"className":9110},[175],"import os\nimport gazu",[48,9113,182,9114,188,9117,869],{},[94,9115,185],{"href":185,"rel":9116},[187],[94,9118,192],{"href":191},[48,9120,261,9121],{},[263,9122,265],{},[48,9124,268],{},[48,9126,9127],{},"rendering = gazu.task.get_task_type_by_name(\"Rendering\")\ntodo = gazu.task.get_task_status_by_name(\"todo\")",[48,9129,9130,9131],{},"render_tasks = ",[263,9132,9133,9134,9136,9137,9139,9140,9142,9143],{},"\nt\nfor t in tasks\nif t",[263,9135,2966],{}," == rendering",[263,9138,2346],{}," and t",[263,9141,2962],{}," == todo",[263,9144,2346],{},[48,9146,9147],{},"for task in render_tasks:\nfiles = gazu.files.get_all_preview_files_for_task(task)\nif not files:\ncontinue",[152,9149,9152],{"className":9150,"code":9151,"language":292},[290],"latest = files[-1]\nif latest[\"extension\"] == \"blend\":\n    task_to_render = task\n    latest_blend = latest\n    break\n",[155,9153,9151],{"__ignoreMap":12},[48,9155,9156],{},"if task_to_render is None:\nraise RuntimeError(\"No render task with a .blend preview found\")",[48,9158,9159,9160,9162,9163,9165],{},"target_path = os.path.join(\n\"/tmp\", latest_blend",[263,9161,2112],{}," + \".\" + latest_blend",[263,9164,2116],{},"\n)",[48,9167,9168],{},[155,9169,9171],{"className":9170},[175],"gazu.files.download_preview_file(latest_blend, target_path)\n",[48,9173,9174],{},"このステップが、NASレスのワークフローを成立させます。各ワーカーは、制作ツリー全体をマウントしたり同期したりするのではなく、実行中の特定タスクに必要なファイルだけを取り出します。ダウンロードに失敗した場合も、人の介入なしにFlamencoがタスクを自動的に再試行できます。",[61,9176],{},[64,9178,9180],{"id":9179},"_4-subcommand-2-blender-render","4. サブコマンド2：Blenderでレンダリングする",[48,9182,9183,9184,9188],{},"レンダリングするblendファイルがワーカー上にローカルで段階配置できたら、",[94,9185,9187],{"href":9186},"https://blog.cg-wire.com/blender-programmatic-rendering/","bpyライブラリでプログラム的にレンダリング","できます：",[152,9190,9191,9204],{},[155,9192,9194,9195,9201],{"className":9193},[728],"bpy.ops.wm.open_mainfile(filepath=target_path)",[48,9196,9197,9198,9200],{},"output_path = os.path.join(\n\"/tmp\", latest_blend",[263,9199,2350],{}," + \".mp4\"\n)",[48,9202,9203],{},"bpy.context.scene.render.image_settings.file_format = \"FFMPEG\"\nbpy.context.scene.render.ffmpeg.format = \"MPEG4\"\nbpy.context.scene.render.ffmpeg.codec = \"H264\"\nbpy.context.scene.render.ffmpeg.constant_rate_factor = \"HIGH\"\nbpy.context.scene.render.ffmpeg.gopsize = 12\nbpy.context.scene.render.ffmpeg.audio_codec = \"AAC\"\nbpy.context.scene.render.filepath = output_path",[48,9205,9206],{},[155,9207,9209],{"className":9208},[728],"bpy.ops.render.render(animation=True)\n",[48,9211,9212],{},"より高度なパイプラインでは、Flamencoのネイティブな「blender-render」コマンドを活用し、フレーム範囲を小さな作業単位に自動で分割して、利用可能なワーカーへ分散できます。マシンが脱落したり、フレームが失敗したりしても、そのフレームだけが再試行されるため、ショット全体を最初からやり直したり、並列性を扱うための独自キューのロジックを作ったりする必要がありません。",[48,9214,9215],{},"しかし、この例をシンプルに保つため、ワーカー1台で動画全体をレンダリングします。",[61,9217],{},[64,9219,9221],{"id":9220},"_5-subcommand-3-uploading-results-back-to-kitsu","5. サブコマンド3：結果をKitsuへアップロードする",[48,9223,9224,9225,9229],{},"ジョブの最後のステップは、",[94,9226,9228],{"href":9227},"https://blog.cg-wire.com/blender-kitsu-low-res-preview/","レンダリング後のサブコマンドでレンダリング結果をKitsuへ戻す","ことです。この時点で、ワーカーは自分のフレーム範囲のレンダリングをローカルで完了しており、ファームの責務は計算からパブリッシングへ移ります。ここで、レンダリングされた出力が制作の他の部分から見えるようになります。",[48,9231,9232],{},"下の例は、生成された動画ファイルを元のタスクに対するアタッチメントとしてKitsuへアップロードする、最小限のPython命令を示しています。",[152,9234,9235],{},[155,9236,9238],{"className":9237},[175],"result = gazu.task.publish_preview(\ntask_to_render,\ntodo,\ncomment=\"rendered\",\npreview_file_path=output_path,\n)\n",[48,9240,9241],{},"実際の制作パイプラインでは、このステップは通常、単にファイルをアップロードするだけではありません。Kitsuで新しいバージョンを作成し、タスクのステータスをDoneのような状態へ更新し、レビューや通知のワークフローをトリガーして、監督者が新しい出力の準備ができたことを把握できるようにします。このロジックはFlamencoタスク内で動くPythonなので、レンダーファーム自体を触らずに、制作ニーズが変わったときに簡単に進化させられます。",[61,9243],{},[64,9245,9247],{"id":9246},"_6-triggering-the-workflow","6. ワークフローを起動する",[48,9249,9250],{},"カスタムジョブタイプが用意できたら、Flamencoマネージャーへジョブリクエストを送信することでワークフローがトリガーされます。開発中は、マネージャーのREST APIを直接呼び出すことで手動で行うことがよくあります。これにより、ジョブのコンパイルが動作すること、設定が正しく配線されていること、そして自動化を積み重ねる前にタスクが期待どおり挙動することを素早く検証できます。",[48,9252,9253,9254,9256,9257,9260],{},"下の例では、",[155,9255,9074],{},"タイプのジョブをマネージャーへ送信します。追跡や帰属のための基本メタデータに加えて、リクエストには優先度の値と、通常はKitsuの制作IDのような制作固有の入力を含むはずの空の",[155,9258,9259],{},"settings","オブジェクトが含まれています。ジョブが受理されると、マネージャーはカスタムジョブタイプを呼び出し、タスクをコンパイルして、利用可能なワーカー全体へスケジュールします。",[152,9262,9263],{},[155,9264,9267,9268,9270,9271,9275,9276,9278,9279,9281,9282,9284,9285,9289],{"className":9265},[9266],"language-sh","curl -X 'POST' ",[125,9269],{},"\n'",[94,9272,9273],{"href":9273,"rel":9274},"http://172.17.0.1:8080/api/v3/jobs",[187],"' ",[125,9277],{},"\n-H 'accept: application/json' ",[125,9280],{},"\n-H 'Content-Type: application/json' ",[125,9283],{},"\n-d '{\n\"metadata\": {\n\"project\": \"kitsu\",\n\"user.email\": \"",[94,9286,9288],{"href":9287},"mailto:basunako@gmail.com","basunako@gmail.com","\",\n\"user.name\": \"kitsu\"\n},\n\"name\": \"Kitsu Render\",\n\"priority\": 50,\n\"settings\": {},\n\"submitter_platform\": \"linux\",\n\"type\": \"kitsu-render\"\n}'\n",[48,9291,9292],{},"マネージャーがジョブリクエストを受け取り、それをワーカーに割り当てたことが確認できます：",[72,9294,9296],{"className":9295},[34,75],[77,9297],{"src":9298,"className":9299,"alt":12,"loading":82,"width":83,"height":84,"srcSet":9300,"sizes":86},"https://blog.cg-wire.com/content/images/2026/02/data-src-image-8815284e-9d0e-49a0-bdd8-ff4ada8a8961.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/02/data-src-image-8815284e-9d0e-49a0-bdd8-ff4ada8a8961.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/02/data-src-image-8815284e-9d0e-49a0-bdd8-ff4ada8a8961.png 1000w, https://blog.cg-wire.com/content/images/2026/02/data-src-image-8815284e-9d0e-49a0-bdd8-ff4ada8a8961.png 1600w",[48,9302,9303],{},"この手動トリガーは主に開発用のツールです。ジョブロジックを反復し、想定外のケースをテストし、制作側の人や制作ツールを巻き込まずにジョブを再実行できます。",[48,9305,9306],{},"本番では、スタジオは常にこのステップを自動化します。小さなサービス（多くの場合cronジョブや軽量なWebhookリスナー）は定期的にKitsuへ問い合わせ、「ちょうど承認されたショット」や「パブリッシュされたもの」のようにレンダリングできる状態のタスクを探します。見つかったら、同じAPI呼び出しを使ってFlamencoマネージャーへ対応するジョブを送信します。",[48,9308,9309],{},"これができると、Flamencoは人がボタンを押すのを待つのではなく、Kitsuの変化に自動的に反応し、ファームを制作の状態と同期したまま保つ、制作を理解したレンダーバックエンドになります。",[61,9311],{},[64,9313,508],{"id":507},[48,9315,9316],{},"この記事であなたが作り上げたのは、小規模スタジオにおけるレンダリングの考え方としては根本的に異なるアプローチです。",[48,9318,9319],{},"Kitsuからコンテキストとデータを引き出し、作業をローカルに段階配置し、Flamencoのネイティブなスケジューラでレンダリングし、結果を非同期に送り返すために、カスタムのFlamencoジョブタイプを使ったことで、信頼性やスケールを犠牲にせずに共有ストレージの必要をなくせました。",[48,9321,9322],{},"各パーツの責務は明確です。Kitsuが制作上の正しさを定義し、Flamencoが作業の実行方法を決め、そしてカスタムジョブタイプが両者を同期させる“接着剤”になります。この分離があるからこそ、このシステムは堅牢で、デバッグ可能で、制作パイプラインが成長しても適応できます。",[48,9324,9325],{},"このパターンを理解することは重要です。ソロのアーティストやマイクロスタジオの現実に合ったレンダリング基盤を構築できるからです。",[48,9327,9328,9329,9332],{},"ですが、ここで終わりにしないでください。",[94,9330,9331],{"href":8933},"この記事用のサンプルGitHubリポジトリをクローンする","ことで、今日からレンダリングを始めましょう！",[31,9334,9336,9339],{"className":9335},[34,35,36],[31,9337,524],{"className":9338},[40],[31,9340,5223,9342,9345],{"className":9341},[45],[94,9343,3875],{"href":531,"rel":9344},[533],"！私たちは、ベストプラクティスを共有する1,000人以上の専門家とつながっており、ときには対面イベントも企画しています。ぜひようこそお迎えしたいです！ 😊",[31,9347,9349],{"className":9348},[34,539,540],[94,9350,546],{"href":531,"className":9351},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":9353},[9354,9355,9356,9357,9358,9359,9360,9361],{"id":8939,"depth":548,"text":8940},{"id":8965,"depth":548,"text":8966},{"id":9034,"depth":548,"text":9035},{"id":9064,"depth":548,"text":9065},{"id":9179,"depth":548,"text":9180},{"id":9220,"depth":548,"text":9221},{"id":9246,"depth":548,"text":9247},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1666858452715-1399b952befb?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDR8fHJlbmRlcmluZ3xlbnwwfHx8fDE3NzAwNDMxNzB8MA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":8861,"featured_at":561,"visibility":562},"/blog-i18n/ja/flamenco-without-nas-kitsu","2026-02-09T10:00:32.000+01:00",{"title":8872,"description":12},"flamenco-without-nas-kitsu","blog-i18n/ja/flamenco-without-nas-kitsu/index",[9370],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"sl54jqJDaZ7ge2EyNzvM42diAYVt--aRcziKEpculRE",{"id":9373,"title":9374,"authors":9375,"body":9377,"description":12,"extension":557,"feature_image":9882,"html":7,"meta":9883,"navigation":13,"path":9885,"published_at":9886,"seo":9887,"slug":9888,"stem":9889,"tags":9890,"__hash__":9892,"updated_at":9884,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/forward-vs-inverse-kinematics-blender/index.md","Blender（2026）で順運動学と逆運動学を使う方法",[9376],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":9378,"toc":9874},[9379,9397,9400,9403,9405,9411,9418,9436,9439,9453,9456,9458,9464,9470,9477,9480,9505,9507,9513,9516,9528,9537,9546,9554,9562,9571,9577,9587,9592,9601,9614,9624,9630,9638,9647,9650,9653,9655,9661,9664,9672,9682,9694,9702,9717,9725,9752,9762,9770,9784,9794,9804,9807,9810,9812,9818,9834,9837,9840,9842,9846,9849,9852,9855,9868],[31,9380,9382,9386],{"className":9381},[34,35,36],[31,9383,9385],{"className":9384},[40],"🤖",[31,9387,9389,9390,9396],{"className":9388},[45],"3Dモデルは、",[94,9391,1934,9393],{"href":9392},"https://blog.cg-wire.com/rigging-in-animation/",[1936,9394,9395],{},"リギングを始める","まではただの無機質なマネキンです。本当の魔法が起きるのは、アニメーターがそれを動かすときで、そこで登場するのが運動学（キネマティクス）です。",[48,9398,9399],{},"とはいえ問題は、キャラクターの腕や脚をドラッグするだけのようにはいきません。限界まで押しすぎると、肘が突然逆方向に曲がったり、走りが壊れたゼンマイおもちゃのように見えたりします。逆に安全側に倒しすぎると、動きが硬くてロボットめいてしまいます。もっともらしい物理と表現力のバランスを見つけるのは難しいです。",[48,9401,9402],{},"この記事では、運動学とは何か、そしてBlenderでどのように機能するのかを解説します。最後には、アニメーション用の最初のリグを作れるようになります。",[61,9404],{},[64,9406,9408],{"id":9407},"what-are-kinematics",[120,9409,9410],{},"運動学とは",[48,9412,9413,9414,9417],{},"運動学とは、",[120,9415,9416],{},"力がどのように運動を引き起こすかを気にせずに、物事が空間でどのように動くかを研究すること","です。アニメーションでは、筋肉や重力で引っ張られることを考えるのではなく、キャラクターやオブジェクトの関節、手足、体の各パーツが、あるポーズから次のポーズへ移るときにどのように変形（変換）するかに注目します。",[72,9419,9421,9428],{"className":9420},[34,75,6381],[77,9422],{"src":9423,"className":9424,"alt":12,"loading":82,"width":9425,"height":9426,"srcSet":9427,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-1727ea30-70cc-42b6-a5e1-085ffa16eef4.png",[81],841,431,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-1727ea30-70cc-42b6-a5e1-085ffa16eef4.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-1727ea30-70cc-42b6-a5e1-085ffa16eef4.png 841w",[6389,9429,9430],{},[6392,9431,9432],{},[655,9433,9435],{"className":9434,"style":122},[6397],"Source: MathWorks",[48,9437,9438],{},"運動学は、3Dモデルを一貫性があり、説得力のある見た目で動かすためのルールとツールをアニメーターに提供します。重要なのは、順運動学と逆運動学の違いを区別することです：",[212,9440,9441,9447],{},[215,9442,9443,9446],{},[120,9444,9445],{},"順運動学（Forward Kinematics: FK）",": FKでは、動きは階層の上（ルート側）から始まります。手を動かしたいなら、まず肩を回し、次に肘、そして手首を回します。こうした方法は、弧を描く動きや、自然なスイング（手を振る、剣を振るなど）に直感的です。というのも、チェーン（リンク）を1つずつ制御できるからです。しかし手間もあります。たとえば指で空間上のある点に触れるアニメーションをしたい場合、すべての関節を手作業で調整して位置を揃える必要があります。",[215,9448,9449,9452],{},[120,9450,9451],{},"逆運動学（Inverse Kinematics: IK）",": IKは問題の考え方を反転させます。各関節を回すのではなく、チェーンの末端を、そこに置きたい位置（たとえばテーブル上のキャラクターの手）に置くと、コンピューターが、その地点に到達するために肩や肘がどのように曲がるべきかを計算します。IKは、体が動く一方で足を床に固定したままにするなど、接触が固定された動きに最適です。欠点は、注意深く制御しないと不自然な曲がり方を生むことがある点で、そのためには複雑な制約を定義する必要があります。",[48,9454,9455],{},"アニメーターは、どちらか一方だけを必ず選ぶわけではありません。必要な動きの種類に応じてFKとIKを切り替えます。流れるような弧の動きはFK、正確な配置はIK、そして多くの場合、この2つをブレンドして、最も自然な端から端までの動きを実現します。",[61,9457],{},[64,9459,9461],{"id":9460},"why-kinematics-are-important",[120,9462,9463],{},"なぜ運動学が重要なのか",[48,9465,9466,9469],{},[120,9467,9468],{},"運動学は、キャラクターの動きが解剖学的な筋道に従うことを保証します","：関節は正しい方向に曲がり、手足は適切な関係を保ち、動作は自然に流れます。これがなければ、どれほど優れた3Dモデルでも、アニメーション中に破綻して見えてしまいます。キャラクターがテーブル上のコップに手を伸ばすとき、肘は正しく曲がり、手首は自然に回転していなければなりません。運動学がなければ、腕が過度に伸びたり、手がありえない方法でねじれたりします。",[48,9471,9472,9473,9476],{},"順運動学と逆運動学を使うことで、",[120,9474,9475],{},"アニメーターははるかに少ない手順で複雑な身体パーツを制御できます","。1フレームごとに関節を細かくいじる代わりに、チェーン全体をまとめてポーズできるため、ポージングのミスも減らせます。毎フレーム足首・膝・腰を手作業で調整する代わりに、アニメーターは逆運動学で足をその場にロックし、ソフトウェアが残りを処理します。",[48,9478,9479],{},"では、仕組みをより掴むためにBlenderで簡単なモデルのリグを試してみましょう。",[31,9481,9483,9486],{"className":9482},[34,35,4487],[31,9484,112],{"className":9485},[40],[31,9487,9489,9493,9495,628,9497,9499,134,9501],{"className":9488},[45],[117,9490,9491],{},[120,9492,623],{"style":122},[125,9494],{},[125,9496],{},[125,9498],{},[125,9500],{},[94,9502,9504],{"href":9503},"https://github.com/cgwire/blender-ik-fk?ref=blog.cg-wire.com","https://github.com/cgwire/blender-ik-fk",[61,9506],{},[64,9508,9510],{"id":9509},"forward-kinematics-fk-in-blender",[120,9511,9512],{},"Blenderでの順運動学（FK）",[48,9514,9515],{},"FKはマリオネット人形を動かすのに似ています。肩から始めて指先へ向かうように、1本ずつ糸（＝各回転）を制御します。各回転が、その前の回転に積み重なる形になります。",[1710,9517,9518],{},[215,9519,9520,9521,9524,9525,1498],{},"キューブを追加し（",[155,9522,9523],{},"Add → Mesh → Cube","）、それを直方体にスケールします。ベベル用にスケールを1に正規化します（",[155,9526,9527],{},"Object → Apply → Scale",[72,9529,9531],{"className":9530},[34,75],[77,9532],{"src":9533,"className":9534,"alt":12,"loading":82,"width":83,"height":9535,"srcSet":9536,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-bbbf0c86-c1bb-4b7b-afd1-18cf0971aeab.png",[81],646,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-bbbf0c86-c1bb-4b7b-afd1-18cf0971aeab.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-bbbf0c86-c1bb-4b7b-afd1-18cf0971aeab.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-bbbf0c86-c1bb-4b7b-afd1-18cf0971aeab.png 1600w",[1710,9538,9539],{"start":548},[215,9540,9541,9542,9545],{},"編集モードでエッジにベベルをかけて、各面を丸めます。",[155,9543,9544],{},"Edge","モードを使い、必要な4つのエッジを選択します。表示されるBevelウィンドウで、セグメント数を増やして丸いエッジを作ります。",[72,9547,9549],{"className":9548},[34,75],[77,9550],{"src":9551,"className":9552,"alt":12,"loading":82,"width":83,"height":3029,"srcSet":9553,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-0c49b11d-3896-4035-a842-4eb98d661b33.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-0c49b11d-3896-4035-a842-4eb98d661b33.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-0c49b11d-3896-4035-a842-4eb98d661b33.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-0c49b11d-3896-4035-a842-4eb98d661b33.png 1600w",[1710,9555,9556],{"start":1820},[215,9557,9558,9559,9561],{},"機械的な腕を作るために、さらに2つのセグメントを作ります。",[155,9560,4999],{},"モードで直方体を選択し、複製します。もう一度繰り返して、3つのセグメントにします。",[72,9563,9565],{"className":9564},[34,75],[77,9566],{"src":9567,"className":9568,"alt":12,"loading":82,"width":9569,"height":9570},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-318d3ca9-6f1f-4afe-b602-ccff95474782.png",[81],315,171,[1710,9572,9574],{"start":9573},4,[215,9575,9576],{},"X軸に沿ってセグメントを配置し、チェーンを作ります。明確な関節位置がある状態で、端から端までつながるように位置決めしてみてください。",[72,9578,9580],{"className":9579},[34,75],[77,9581],{"src":9582,"className":9583,"alt":12,"loading":82,"width":9584,"height":9585,"srcSet":9586,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-82b2e2e0-c34c-46a2-9418-f313e5c0f788.png",[81],847,467,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-82b2e2e0-c34c-46a2-9418-f313e5c0f788.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-82b2e2e0-c34c-46a2-9418-f313e5c0f788.png 847w",[1710,9588,9589],{"start":1744},[215,9590,9591],{},"親階層（FKチェーン）をセットアップします。ベースから先端まで、チェーンを組み立てます。まず子オブジェクトを選択し、次にそれを意図した親（ベースに近い方のもの）に配置します。各セグメントが前のセグメントを親に持つように、これを繰り返します。",[72,9593,9595],{"className":9594},[34,75],[77,9596],{"src":9597,"className":9598,"alt":12,"loading":82,"width":9599,"height":9600},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-408d19e7-ccac-4706-90fa-1aa9ace327b7.png",[81],319,218,[1710,9602,9604],{"start":9603},6,[215,9605,9606,9607,9609,9610,9613],{},"各オブジェクトの原点を関節に置きます。正しい回転のためには、原点は各セグメントの関節の端にある必要があります。カーソルツールを使って原点を配置します。次に",[155,9608,4999],{},"モードで、",[155,9611,9612],{},"Object → Set Origin → Origin to 3D Cursor","を実行します。これをすべてのセグメントに対して行います。",[72,9615,9617],{"className":9616},[34,75],[77,9618],{"src":9619,"className":9620,"alt":12,"loading":82,"width":9621,"height":9622,"srcSet":9623,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-7a11ca12-b043-4f94-b663-b87271e51597.png",[81],817,416,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-7a11ca12-b043-4f94-b663-b87271e51597.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-7a11ca12-b043-4f94-b663-b87271e51597.png 817w",[1710,9625,9627],{"start":9626},7,[215,9628,9629],{},"前後運動学（forward kinematics）の挙動を観察するために、各セグメントに小さなデフォルト回転を与えます。ベース（親）オブジェクトを回転させると、親階層チェーンのおかげで子が追従します。",[72,9631,9633],{"className":9632},[34,75],[77,9634],{"src":9635,"className":9636,"alt":12,"loading":82,"width":9621,"height":9622,"srcSet":9637,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-50da86d0-88ec-4673-a55b-227f9df93c0b.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-50da86d0-88ec-4673-a55b-227f9df93c0b.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-50da86d0-88ec-4673-a55b-227f9df93c0b.png 817w",[48,9639,9640,9641,9646],{},"あとは、腕を好きなように回転させ、位置をキーフレーム化し、",[94,9642,1934,9643],{"href":2759},[1936,9644,9645],{},"最終結果をレンダーしてアニメーションにする","だけです！",[48,9648,9649],{},"見ての通り、FKは手を振る、バットをスイングする、踊るといったような、滑らかで弧を描く動きにとても向いています。",[48,9651,9652],{},"より高度なリグ（IK、コントロール、制約）では、Blenderのアニメーターはオブジェクトの親子付けではなく、Armature（アーマチュア）を使います。",[61,9654],{},[64,9656,9658],{"id":9657},"inverse-kinematics-ik-in-blender",[120,9659,9660],{},"Blenderでの逆運動学（IK）",[48,9662,9663],{},"IKは人形の手を動かすようなもので、腕のほうが、肘と肩がどう曲がるべきかを計算して追従します。",[1710,9665,9666],{},[215,9667,9668,9671],{},[120,9669,9670],{},"FKアームのメッシュを複製します。","3セグメントのFKアームを選び、比較用にFK版を残すため、複製して横にずらします。",[72,9673,9675],{"className":9674},[34,75],[77,9676],{"src":9677,"className":9678,"alt":12,"loading":82,"width":9679,"height":9680,"srcSet":9681,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-59cd3241-e8e1-4b3b-b60a-8457c017a553.png",[81],1349,526,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-59cd3241-e8e1-4b3b-b60a-8457c017a553.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-59cd3241-e8e1-4b3b-b60a-8457c017a553.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-59cd3241-e8e1-4b3b-b60a-8457c017a553.png 1349w",[1710,9683,9684],{"start":548},[215,9685,9686,9689,9690,9693],{},[120,9687,9688],{},"セグメントを1つのオブジェクトに統合します。","新しく複製した腕を選択し、各セグメントを1つのメッシュに結合します（",[155,9691,9692],{},"Select all → Object → Join","）。これで、腕全体を表す連続したオブジェクトが1つになります。",[72,9695,9697],{"className":9696},[34,75],[77,9698],{"src":9699,"className":9700,"alt":12,"loading":82,"width":9679,"height":9680,"srcSet":9701,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-4f6843c9-ce25-4aa4-b391-3637d7543c4b.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-4f6843c9-ce25-4aa4-b391-3637d7543c4b.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-4f6843c9-ce25-4aa4-b391-3637d7543c4b.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-4f6843c9-ce25-4aa4-b391-3637d7543c4b.png 1349w",[1710,9703,9704],{"start":1820},[215,9705,9706,9709,9712,9713,9716],{},[120,9707,9708],{},"アーマチュアのチェーンを作成します。",[155,9710,9711],{},"Add → Armature","でArmatureを追加します。Armatureの",[120,9714,9715],{},"編集モード","で、セグメントに合わせてボーンを押し出します。最初のボーンの先端を選んで押し出し、肘の位置に置きます。「手」に相当する部分も同様に、もう一度押し出します。",[72,9718,9720],{"className":9719},[34,75],[77,9721],{"src":9722,"className":9723,"alt":12,"loading":82,"width":9679,"height":9680,"srcSet":9724,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-f18a080f-af0d-44c9-a948-01b17e8d4ad7.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-f18a080f-af0d-44c9-a948-01b17e8d4ad7.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-f18a080f-af0d-44c9-a948-01b17e8d4ad7.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-f18a080f-af0d-44c9-a948-01b17e8d4ad7.png 1349w",[1710,9726,9727],{"start":9573},[215,9728,9729,9732,9735,9736,9739,9740,9747,9748,9751],{},[120,9730,9731],{},"IKコントローラーを追加します。",[120,9733,9734],{},"ポーズモード","に切り替えて、",[655,9737,9738],{},"hand","ボーンを選択します。",[155,9741,9742,9743,9746],{},"Shift+I → ",[655,9744,9745],{},"Add Inverse Kinematics"," → Without Targets","を押します。するとIKチェーンが腕を駆動するようになります。Bone Constraintsタブで",[655,9749,9750],{},"Chain Length"," = 3に設定します。",[72,9753,9755],{"className":9754},[34,75],[77,9756],{"src":9757,"className":9758,"alt":12,"loading":82,"width":9759,"height":9760,"srcSet":9761,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-9ffe89a0-6326-410d-9574-91798ce5dbc5.png",[81],1008,423,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-9ffe89a0-6326-410d-9574-91798ce5dbc5.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-9ffe89a0-6326-410d-9574-91798ce5dbc5.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-9ffe89a0-6326-410d-9574-91798ce5dbc5.png 1008w",[72,9763,9765],{"className":9764},[34,75],[77,9766],{"src":9767,"className":9768,"alt":12,"loading":82,"width":9759,"height":9760,"srcSet":9769,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-069281f6-1b06-4992-8a73-63b76c27f9eb.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-069281f6-1b06-4992-8a73-63b76c27f9eb.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2025/10/data-src-image-069281f6-1b06-4992-8a73-63b76c27f9eb.png 1000w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-069281f6-1b06-4992-8a73-63b76c27f9eb.png 1008w",[1710,9771,9772],{"start":1744},[215,9773,9774,9777,9779,9780,9783],{},[120,9775,9776],{},"メッシュをアーマチュアにバインドします（スキニング）。",[155,9778,4999],{},"モードでまずメッシュを選択し、その後Ctrl選択でアーマチュアを選択します。オブジェクトを右クリックして",[155,9781,9782],{},"Parent → Armature Deform → With Automatic Weights","を選びます。Blenderは各ボーンごとに頂点グループを割り当て、腕がリグに追従するようになります。",[72,9785,9787],{"className":9786},[34,75],[77,9788],{"src":9789,"className":9790,"alt":12,"loading":82,"width":9791,"height":9792,"srcSet":9793,"sizes":86},"https://blog.cg-wire.com/content/images/2025/10/data-src-image-0c7343c3-1d1b-4ad3-b68a-804bdf1e1ba4.png",[81],992,531,"https://blog.cg-wire.com/content/images/size/w600/2025/10/data-src-image-0c7343c3-1d1b-4ad3-b68a-804bdf1e1ba4.png 600w, https://blog.cg-wire.com/content/images/2025/10/data-src-image-0c7343c3-1d1b-4ad3-b68a-804bdf1e1ba4.png 992w",[1710,9795,9796],{"start":9603},[215,9797,9798,9801,9803],{},[120,9799,9800],{},"IKでアニメーションします。",[120,9802,9734],{},"に移動し、IKコントローラーボーンをつかんで動かします：すると腕全体が自然に追従します！",[48,9805,9806],{},"親チェーン上のボーンを動かすことで、FKも引き続き使えます。",[48,9808,9809],{},"なお、メッシュはデフォルトではこの方法で変形します。望む動きに合わせるには、Bone Constraints（ボーン制約）を追加する必要があります。たとえば、機械的な腕のように腕が単一の軸に沿って動くことだけを許可する、といった具合です。",[61,9811],{},[64,9813,9815],{"id":9814},"fkik-switch",[120,9816,9817],{},"FK/IKスイッチ",[48,9819,9820,9821,9824,9825,9833],{},"Blenderのほとんどのリグは、",[120,9822,9823],{},"ハイブリッドシステム","を使います。流れるような弧の動きにはFK、固定された接触にはIKです。一般的には、アニメーターは",[117,9826,9827],{},[94,9828,1934,9830],{"href":9829},"https://blog.cg-wire.com/staging-animation-principle/",[1936,9831,9832],{},"まずFKで大まかなジェスチャーによるポーズを作り、その後接触の瞬間や正確な位置合わせのためにIKへ切り替える","という流れで進めます。",[48,9835,9836],{},"さらに高度なリグでは、Blenderのアニメーターは、FKとIKを切り替えるために（通常は）カスタムプロパティ（Nパネルのスライダーやトグル、またはコントロール用ボーン上のスイッチ）を作成します。",[48,9838,9839],{},"この記事の範囲外ですが、念頭に置いておくことが重要です。",[61,9841],{},[64,9843,9844],{"id":507},[120,9845,508],{},[48,9847,9848],{},"運動学はリギングとスキニングの土台であり、硬い3Dマネキンと「生きている」と感じさせるキャラクターを分けるものです。",[48,9850,9851],{},"順運動学は滑らかな弧と自然な流れを作り、逆運動学は説得力のある接触によってキャラクターをワールドに固定します。",[48,9853,9854],{},"ただ、読んで終わりにしないでください。Blenderを開いてモデルを掴み、まずは触ってみましょう。きちんと作られたリグは、ボーンをつなぐだけではありません。それは、キャラクターがどのように動き、どのようにポーズし、3Dの世界とどのように相互作用するかを定義します。",[31,9856,9858,9861],{"className":9857},[34,35,36],[31,9859,524],{"className":9860},[40],[31,9862,5958,9864,9867],{"className":9863},[45],[94,9865,961],{"href":531,"rel":9866},[533],"！私たちはベストプラクティスを共有する1,000人以上の専門家とつながっており、時には対面イベントを企画することもあります。ぜひあなたをお迎えできたら嬉しいです！ 😊",[31,9869,9871],{"className":9870},[34,539,540],[94,9872,546],{"href":531,"className":9873},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":9875},[9876,9877,9878,9879,9880,9881],{"id":9407,"depth":548,"text":9410},{"id":9460,"depth":548,"text":9463},{"id":9509,"depth":548,"text":9512},{"id":9657,"depth":548,"text":9660},{"id":9814,"depth":548,"text":9817},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1590285381943-9fbf39f4f75d?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fDNEJTIwY2hhcmFjdGVyJTIwcmlnfGVufDB8fHx8MTc2MDkyMDExNnww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":9884,"featured_at":561,"visibility":562},"2026-02-20T06:04:27.000+01:00","/blog-i18n/ja/forward-vs-inverse-kinematics-blender","2025-10-28T10:00:04.000+01:00",{"title":9374,"description":12},"forward-vs-inverse-kinematics-blender","blog-i18n/ja/forward-vs-inverse-kinematics-blender/index",[9891],{"id":1844,"name":1845,"slug":1846,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1847},"hUMs8KDeKVg8k6VNJiwQFf8bQEgC7oQKu-vroV9BJBg",{"id":9894,"title":9895,"authors":9896,"body":9898,"description":12,"extension":557,"feature_image":10476,"html":7,"meta":10477,"navigation":13,"path":10479,"published_at":10480,"seo":10481,"slug":10482,"stem":10483,"tags":10484,"__hash__":10486,"updated_at":10478,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/kitsu-cli-single-binary/index.md","Python と Gazu でポータブルな Kitsu CLI をシングルバイナリ化する（2026）",[9897],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":9899,"toc":10467},[9900,9911,9918,9923,9930,9933,9936,9939,9945,9947,9951,9958,9968,9975,9982,10009,10011,10015,10025,10032,10038,10044,10050,10076,10083,10089,10095,10097,10101,10107,10110,10117,10132,10139,10145,10151,10153,10157,10167,10170,10176,10196,10199,10201,10205,10220,10231,10237,10244,10247,10253,10267,10281,10284,10290,10297,10307,10310,10312,10316,10319,10333,10336,10342,10345,10382,10420,10423,10430,10432,10434,10440,10445,10460],[31,9901,9903,9907],{"className":9902},[34,35,36],[31,9904,9906],{"className":9905},[40],"🧰",[31,9908,9910],{"className":9909},[45],"壊れやすい Python スクリプトを、ただ動くだけの 1 つの確実なツールに変える。",[48,9912,9913,9914,9917],{},"制作も終盤、スケジュールはタイト。新しいマシンに重要なパイプラインツールを導入する必要があります。撮影（ショット）のステータスを同期したり、プレイブラストを公開したり、あるいは ",[94,9915,9916],{"href":786},"Kitsu のワークフローを自動化"," したりするためのものです。ツール自体は大したことはありません。Python です。あなたはすでに書いています。",[48,9919,9920],{},[120,9921,9922],{},"問題は、その周りのすべて。",[48,9924,9925,9926,9929],{},"導入先のマシンには Python が入っていません。あるいは、間違ったバージョンです。スタジオの Linux サーバーはロックダウンされています。フリーランサーの Windows 環境では依存関係をコンパイルできません。誰かが「",[155,9927,9928],{},"pip"," が必要なのか、仮想環境が必要なのか、それとも Gazu SDK なのか」と聞いてきます。すると、あっという間に「シンプルなスクリプト」はドキュメント、トラブルシューティング、そして失われる時間へと変わってしまうのです。",[48,9931,9932],{},"パイプラインツールを作る代わりに、環境の管理をしている状態になります。",[48,9934,9935],{},"これは誰も楽しくない工程です。Python をインストールし、バージョンを固定し、足りないライブラリを追いかけて、OS の更新で何も壊れないことを祈ること。さらに、ツールをアーティストのワークステーション、レンダーノード、CI サーバーで動かす必要があるとき、その脆さは本当の制作上のリスクになります。",[48,9937,9938],{},"本当に欲しいのはシンプルです。1 つのツール、1 つのコマンド。あとはただ実行されること。",[48,9940,9941,9944],{},[120,9942,9943],{},"この記事では、Kitsu Python SDK（Gazu）を Command Line Interface（CLI）で包み込み、さらに単一のバイナリ実行ファイルにコンパイルすることで、Kitsu ワークフローをどのようにパッケージするかを学びます。"," Python のインストールは不要。依存関係の管理も不要。すぐにどんなマシンでも使える、信頼できる実行ファイルだけです。",[61,9946],{},[64,9948,9950],{"id":9949},"why-you-need-a-cli","なぜ CLI が必要なのか",[48,9952,9953,9954,9957],{},"GUI は創造的な作業に最適です。しかし ",[120,9955,9956],{},"パイプライン管理を扱う段階になると、Web UI はすぐに負担になります","。Kitsu の適切なタスクを CLI に移すことで、より速く、より拡張性があり、そして自動化しやすい形で作業できるようになります。",[48,9959,9960,9961,9964,9965],{},"5 つのショットのアニメーションを仕上げて、ステータスを更新し、プレビューをアップロードする必要があるとします。ブラウザだとコンテキスト切り替えが発生します。Alt-Tab、Chrome を開く、Kitsu に移動、プロジェクトに入る、エピソードを探す、ショットをクリック、ステータス変更、動画のアップロード。そして同じ作業を、すべてのショット分繰り返すのです。CLI なら、その場に留まれます。",[155,9962,9963],{},"kitsu publish --status Review"," と入力して Enter。あとは次へ。",[120,9966,9967],{},"キーボードから離れることはなく、集中が途切れず、メニューをクリックすることで発生する認知的コストも支払わずに済みます。",[48,9969,9970,9971,9974],{},"CLI は自然に「引数」「リスト」「自動化」の発想へと導き、そこで一気に積み上がっていきます。",[120,9972,9973],{},"1 つのショットを更新できるなら、同じコマンドで 10 も 100 も更新できます。"," シーケンスをループしたり、ショット名をパイプで渡したり、DCC やレンダー出力から直接操作したりできます。Web UI で 1 時間かかる反復クリック作業が、スクリプト化された数秒に変わるのです。そして一貫していて、繰り返せて、バージョン管理もしやすい。",[48,9976,9977,9978,9981],{},"最後に、",[120,9979,9980],{},"すべてのパイプライン処理が、モニター付きのワークステーション上で動くわけではありません。"," レンダーファームのノード、ビルドサーバー、あるいはディスク上のファイルに反応するバックグラウンドプロセスで実行する必要があることもあります。そうした環境では、ブラウザもなく、ボタンをクリックするユーザーもいません。CLI はシェルがある場所ならどこでも動きます。パブリッシュ、自動化によるステータス変更、バリデーション、同期処理まで行え、Kitsu はより深いレベルでパイプラインに組み込まれていきます。",[31,9983,9985,9988],{"className":9984},[34,35,108],[31,9986,112],{"className":9987},[40],[31,9989,9991,9996,9998,10000,10001,10003,134,10005],{"className":9990},[45],[117,9992,9993],{},[120,9994,9995],{"style":122},"動く具体例を探していますか？",[125,9997],{},[125,9999],{},"このガイドで紹介している例の統合について、完全なソースコードは GitHub で確認できます。",[125,10002],{},[125,10004],{},[94,10006,10008],{"href":10007},"https://github.com/cgwire/blog-tutorials/tree/main/kitsu-cli?ref=blog.cg-wire.com","https://github.com/cgwire/blog-tutorials/tree/main/kitsu-cli",[61,10010],{},[64,10012,10014],{"id":10013},"_1-designing-the-cli-interface","1. CLI インターフェースの設計",[48,10016,10017,10018,310,10021,10024],{},"Kitsu API に触れる前に、まずツールの骨組みが必要です。Python にはコマンドライン引数を解析する方法がいくつかありますが、プロ向けのパイプラインツールなら、",[155,10019,10020],{},"Click",[155,10022,10023],{},"Typer"," といったライブラリの利用を強くおすすめします。",[48,10026,10027,10028,10031],{},"このウォークスルーでは、",[155,10029,10030],{},"kitsu-cli"," というツールを想像してみましょう。",[48,10033,10034,10037],{},[120,10035,10036],{},"ツールを木（ツリー）だと思ってください。"," 主幹（幹）がメインの実行ファイルで、枝があなたのコマンドとサブコマンドです。",[152,10039,10040],{},[155,10041,10043],{"className":10042},[290],"kitsu-cli (root)\n└── production (production に関するコマンド)\n    └── list (すべての productions を一覧表示)\n",[48,10045,10046,10047,10049],{},"次は、",[155,10048,10020],{}," を使ってこのロジックを Python で構成する方法です。この構造は、ツールを拡張可能にするために重要です。今日あなたが production を管理しているとしても、明日には asset やプレイリストを管理しているかもしれません。",[152,10051,10052,10065],{},[155,10053,10055,10056,10059,10062],{"className":10054},[175],"import click\n",[48,10057,10058],{},"@click.group()\ndef cli():\n\"\"\"My Studio Kitsu Tool\"\"\"\npass",[48,10060,10061],{},"@cli.group()\ndef production():\n\"\"\"productions を管理するためのコマンド\"\"\"\npass",[48,10063,10064],{},"@production.command()\n@click.option('--name', help='名前でフィルタ')\ndef list(name):\n\"\"\"productions を一覧表示\"\"\"\nclick.echo(f\"productions を一覧表示中: {name}\")",[48,10066,10067],{},[155,10068,855,10070,10072,10073,10075],{"className":10069},[175],[120,10071,858],{}," == '",[120,10074,862],{},"':\ncli()\n",[48,10077,10078,10079,10082],{},"このスニペットだけでも、ヘルプメニューが自動で手に入ります。ユーザーが ",[155,10080,10081],{},"kit-cli --help"," と入力すれば、ドキュメントが表示されます。これは開発者の思いやりであり、ユーザーに使い方を教えるツールを作ることです。",[48,10084,10085,10088],{},[120,10086,10087],{},"CLI を実行するには","、通常の Python プログラムと同じように同じコマンドを使うだけです。",[152,10090,10091],{},[155,10092,10094],{"className":10093},[728],"python3 cli.py production list\n",[61,10096],{},[64,10098,10100],{"id":10099},"_2-adding-gazu-features","2. Gazu の機能を追加する",[48,10102,10103,10104,10106],{},"骨組みができたので、次は筋肉が必要です。Kitsu には ",[120,10105,1892],{}," という素晴らしい Python クライアントが用意されています。",[48,10108,10109],{},"もし Gazu を使ったことがないなら、Gazu はあなたのスクリプトと Kitsu サーバーの間をつなぐブリッジだと考えてください。",[48,10111,10112,10113,10116],{},"どのパイプラインツールでも最初のハードルは ",[120,10114,10115],{},"認証"," です。アーティストに、パスワードをスクリプトへ直書きさせたくはありません。堅牢な CLI は、すでにセッションが存在するかどうかを確認します。なければ、ユーザーに 1 回ログインしてもらい、トークンをローカルに保存します。簡単のため、認証ロジックは次のように固定しておきます。",[152,10118,10119,10122],{},[155,10120,2943],{"className":10121},[175],[48,10123,10124],{},[155,10125,182,10127,188,10130,193],{"className":10126},[175],[94,10128,185],{"href":185,"rel":10129},[187],[94,10131,192],{"href":191},[48,10133,10134,10135,10138],{},"認証が済んだら、先ほど書いた ",[155,10136,10137],{},"list"," コマンドを具体化できます。productions を一覧表示するには次のようにします。",[152,10140,10141],{},[155,10142,10144],{"className":10143},[175],"@production.command()\n@click.option('--name', help='名前でフィルタ')\ndef list(name):\n\"\"\"productions を一覧表示\"\"\"\nclick.echo(f\"productions を一覧表示中: {name}\")\n",[48,10146,10147,10148],{},"ブラウザを開いて Vue アプリの読み込みを待ったり、ビューをフィルタしたりする必要はありません。",[120,10149,10150],{},"このスクリプトは生データを即座に返します。",[61,10152],{},[64,10154,10156],{"id":10155},"_3-interactive-interface","3. インタラクティブなインターフェース",[48,10158,10159,10162,10163,10166],{},[155,10160,10161],{},"--name test"," のようなコマンドフラグも便利ですが、",[120,10164,10165],{},"production をインタラクティブな一覧から選べるようにする方が、はるかに良い体験","になります。",[48,10168,10169],{},"シーケンスの正確な名前をユーザーに入力させる代わりに（必ずスペルミスが起きます）、プロンプトを追加することで CLI を賢くできます。もしユーザーが引数を渡し忘れたら、その場で聞けばいいのです。",[48,10171,10172,10175],{},[155,10173,10174],{},"questionary"," のようなライブラリは、ターミナルに自己説明型のインタラクティブな選択リストを追加できるので最適です。",[152,10177,10178,10191],{},[155,10179,10181,10182,10185],{"className":10180},[175],"import questionary",[48,10183,10184],{},"@production.command()\ndef select():\n\"\"\"利用可能な productions を一覧表示\"\"\"\nproductions = gazu.project.all_projects()",[152,10186,10189],{"className":10187,"code":10188,"language":292},[290],"selected_project = questionary.select(\n    \"どのプロジェクトで作業していますか？\", choices=productions\n).ask()\n\nclick.echo(f\"{selected_project} を選択しました。assets を読み込み中...\")\n",[155,10190,10188],{"__ignoreMap":12},[48,10192,10193],{},[155,10194],{"className":10195},[175],[48,10197,10198],{},"この小さな追加によって、ユーザー体験は「怖いハッカー向けツール」から「頼りになるアシスタント」へと変わります。ユーザーが Kitsu から取得した有効な選択肢しか選べないため、エラー率はほぼゼロにまで下がります。",[61,10200],{},[64,10202,10204],{"id":10203},"_4-the-single-executable-binary","4. 単一の実行可能バイナリ",[48,10206,10207,10208,10211,10212,658,10214,658,10217,10219],{},"最後にもう一つ、",[120,10209,10210],{},"「自分のラップトップでは動かない」問題を解決する必要があります。","依存関係を含む Python スクリプトがあります：",[155,10213,165],{},[155,10215,10216],{},"click",[155,10218,10174],{}," など。",[48,10221,10222,10223,10226,10227,10230],{},"フリーランサーのマシンで動かすには、本来は Python をインストールしたり、仮想環境を作って ",[155,10224,10225],{},"pip install"," で要件を入れたりする必要があります。これらの手順をすべてなくすために ",[155,10228,10229],{},"PyInstaller"," を使います。",[152,10232,10233],{},[155,10234,10236],{"className":10235},[9266],"python3 -m pip install pyinstaller\n",[48,10238,10239,10240,10243],{},"PyInstaller はあなたの Python スクリプトを解析し、インポートされているすべてのライブラリを見つけ、Python インタプリタ自体もバンドルし、すべてを 1 つの ",[155,10241,10242],{},".exe"," ファイル（Windows）またはターゲットのバイナリ（Linux/Mac）に包み込みます。",[48,10245,10246],{},"ターミナルでスクリプトのフォルダに移動して、次を実行します。",[152,10248,10249],{},[155,10250,10252],{"className":10251},[158],"python3 -m PyInstaller --onefile --name kitsu-cli cli.py\n",[212,10254,10255,10261],{},[215,10256,10257,10260],{},[155,10258,10259],{},"--onefile",": このフラグは、バラバラの依存関係が入ったフォルダではなく、すべてを 1 つのファイルとしてバンドルするよう PyInstaller に指示します。",[215,10262,10263,10266],{},[155,10264,10265],{},"--name",": 最終的なバイナリファイルの名前。",[48,10268,10269,10270,10273,10274,10276,10277,10280],{},"処理が終わったら ",[155,10271,10272],{},"dist/"," フォルダを確認します。",[155,10275,10030],{},"（または ",[155,10278,10279],{},"kitsu-cli.exe","）というファイルが見つかるはずです。",[48,10282,10283],{},"これをそのまま使って、USB ドライブに入れたり、メールで送ったり、ネットワークドライブに置いたりできます。アーティストはデスクトップにドラッグして、同じ OS のアーキテクチャ（macOS、Windows など）でコンパイルされていればすぐに実行できます。Python をインストールする必要はありません。Gazu を手動でインストールする必要もありません。つまり、ただ動くだけです。",[152,10285,10286],{},[155,10287,10289],{"className":10288},[9266],"./kitsu-cli production list\n",[48,10291,10292,10293,10296],{},"とはいえ、私の言葉を信じるだけではなく、",[94,10294,10295],{},"GitHub リポジトリをクローンして","自分で試してみてください。",[72,10298,10300],{"className":10299},[34,75],[77,10301],{"src":10302,"className":10303,"alt":12,"loading":82,"width":10304,"height":10305,"srcSet":10306,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-f4c09502-e96e-4692-8fc7-d4dd59d6482c.png",[81],1319,913,"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-f4c09502-e96e-4692-8fc7-d4dd59d6482c.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-f4c09502-e96e-4692-8fc7-d4dd59d6482c.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-f4c09502-e96e-4692-8fc7-d4dd59d6482c.png 1319w",[48,10308,10309],{},"CLI を別の OS ターゲットへクロスコンパイルする必要がある場合は、Github Actions を使えます。",[61,10311],{},[64,10313,10315],{"id":10314},"cli-example-the-render-fetcher","CLI の例：「Render Fetcher」",[48,10317,10318],{},"よりパイプライン中心のシナリオに切り替えてみましょう。",[48,10320,10321,10322,10325,10326,10329,10330,10332],{},"複数のマシンにわたって ",[94,10323,10324],{"href":2759},"分散レンダリングを管理"," するワークフローを思い浮かべてください。それぞれのレンダーノードは、Kitsu から定期的に新しい作業を取得する必要があります。レンダリング待ち（",[655,10327,10328],{},"TODO","）としてマークされたショットと、その対応するプレビュー ",[155,10331,4865],{}," ファイルです。これらのマシンはヘッドレスで、ロックダウンされ、意図的にミニマム構成になっています。Python のインストールはなし。仮想環境もなし。依存関係のやりくりもなし。",[48,10334,10335],{},"そこで欲しいのは、どんなサーバーにも置いて、cron ジョブやサービスとして実行できる「単一の実行ファイル」です。",[152,10337,10338],{},[155,10339,10341],{"className":10340},[158],"./kitsu-cli pull MechaFight /home/user/flamenco/jobs\n",[48,10343,10344],{},"対応するコードは次のようになります。",[152,10346,10347,10372],{},[155,10348,10350,10351,10354,10361,10363,10366],{"className":10349},[175],"import os",[48,10352,10353],{},"import click\nimport gazu\nimport questionary",[48,10355,182,10356,188,10359,869],{},[94,10357,185],{"href":185,"rel":10358},[187],[94,10360,192],{"href":191},[48,10362,10058],{},[48,10364,10365],{},"@cli.command()\n@click.argument(\"project_name\", required=True)\n@click.argument(\"output_path\", required=True)\ndef pull(project_name, output_path):\nclick.echo(f\"Fetching TODO render tasks for project: {project_name}\")",[152,10367,10370],{"className":10368,"code":10369,"language":292},[290],"project = gazu.project.get_project_by_name(project_name)\n\ntasks = gazu.task.all_tasks_for_project(project)\n\nrendering = gazu.task.get_task_type_by_name(\"Rendering\")\ntodo = gazu.task.get_task_status_by_name(\"todo\")\n\nrender_tasks = [\n    t\n    for t in tasks\n    if t[\"task_type_id\"] == rendering[\"id\"] and t[\"task_status_id\"] == todo[\"id\"]\n]\n\nfor task in render_tasks:\n    files = gazu.files.get_all_preview_files_for_task(task)\n    size = len(files)\n\n    if size &gt; 0:\n        latest = files[size - 1]\n        if latest[\"extension\"] == \"blend\":\n            target_path = os.path.join(\n                output_path, latest[\"name\"] + \".\" + latest[\"extension\"]\n            )\n            gazu.files.download_preview_file(latest, target_path)\n",[155,10371,10369],{"__ignoreMap":12},[48,10373,10374],{},[155,10375,855,10377,859,10379,10381],{"className":10376},[175],[120,10378,858],{},[120,10380,862],{},"\":\ncli()\n",[1710,10383,10384,10393,10405,10414],{},[215,10385,10386,10389,10390,10392],{},[120,10387,10388],{},"Kitsu を照会する"," - CLI は Kitsu（Gazu 経由）に接続し、指定したプロジェクトに対して ",[655,10391,10328],{}," ステータスのレンダリングタスクをすべて取得します。",[215,10394,10395,1490,10398,10401,10402,10404],{},[120,10396,10397],{},"タスクをフィルタする",[155,10399,10400],{},"todo"," とマークされ、かつ対応するプレビュー ファイルが関連付いているタスクを抽出します（この場合は ",[155,10403,4865],{}," ファイルです）。",[215,10406,10407,10410,10411,10413],{},[120,10408,10409],{},"アセットをダウンロードする"," - 各タスクごとに、CLI は対応するプレビュー ",[155,10412,4865],{}," ファイルを、指定された出力パスへディスクへダウンロードします。",[215,10415,10416,10419],{},[120,10417,10418],{},"レンダリング"," - ダウンロードが完了すると、ファイルは Blender が取得できる状態になり、手動または Flamenco のような自動レンダーオーケストレータ経由でレンダリングできます。",[48,10421,10422],{},"この CLI を単一のバイナリにコンパイルしてしまえば、デプロイは簡単になります。Linux のレンダーノードにそのまま置いて、Python や依存関係をインストールせずに cron や systemd から起動できます。すべてのサーバーで同じ方法で作業を取得します。フォルダ構成は一貫します。タスクの状態はそのまま Kitsu から取得されます。そしてレンダーファームはレンダリングに集中できます。",[48,10424,10425,10426,10429],{},"繰り返しになりますが、",[94,10427,10428],{},"対応する Github リポジトリ","で実際に確認してください。",[61,10431],{},[64,10433,2530],{"id":507},[48,10435,10436,10439],{},[120,10437,10438],{},"自分で Kitsu CLI を作ることは、必ずしも複雑である必要はありません。","Gazu ライブラリを使いやすい CLI に包み、PyInstaller で固定化することで、パイプラインをスケールさせられます。環境管理に伴う技術的な摩擦を取り除き、アーティストが最も得意なこと、つまり美しいアニメーションを作ることに集中できるようになります。",[48,10441,10442,10444],{},[94,10443,8823],{"href":6415},"して、Kitsu と Blender のスクリプトを組み合わせる方法も学んでください！",[31,10446,10448,10451],{"className":10447},[34,35,36],[31,10449,524],{"className":10450},[40],[31,10452,10454,10455,10459],{"className":10453},[45],"アニメーションのプロセスについてもっと知りたいなら、",[94,10456,10458],{"href":531,"rel":10457},[533],"Discord のコミュニティに参加することを検討してください","！ 私たちはベストプラクティスを共有する1,000人以上の専門家とつながっており、時には対面イベントも企画します。ぜひ私たちもあなたを歓迎したいです！ 😊",[31,10461,10463],{"className":10462},[34,539,540],[94,10464,10466],{"href":531,"className":10465},[544,545],"Discord コミュニティに参加する",{"title":12,"searchDepth":548,"depth":548,"links":10468},[10469,10470,10471,10472,10473,10474,10475],{"id":9949,"depth":548,"text":9950},{"id":10013,"depth":548,"text":10014},{"id":10099,"depth":548,"text":10100},{"id":10155,"depth":548,"text":10156},{"id":10203,"depth":548,"text":10204},{"id":10314,"depth":548,"text":10315},{"id":507,"depth":548,"text":2530},"https://images.unsplash.com/photo-1484417894907-623942c8ee29?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDIxfHxzb2Z0d2FyZSUyMGRldmVsb3BtZW50fGVufDB8fHx8MTc2NzYwNzcwNHww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":10478,"featured_at":561,"visibility":562},"2026-02-20T06:04:43.000+01:00","/blog-i18n/ja/kitsu-cli-single-binary","2026-01-12T10:00:37.000+01:00",{"title":9895,"description":12},"kitsu-cli-single-binary","blog-i18n/ja/kitsu-cli-single-binary/index",[10485],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"GmASzRfG0IozXsnwCh_Hv7Wr27zFDtygFTV42CGl9Xs",{"id":10488,"title":10489,"authors":10490,"body":10492,"description":12,"extension":557,"feature_image":10971,"html":7,"meta":10972,"navigation":13,"path":10974,"published_at":10973,"seo":10975,"slug":10976,"stem":10977,"tags":10978,"__hash__":10980,"updated_at":10973,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/kitsu-telegram-bot-integration/index.md","メッセージングプラットフォームをKitsuの制作データと統合する",[10491],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":10493,"toc":10963},[10494,10505,10508,10511,10514,10516,10520,10523,10526,10529,10532,10534,10538,10541,10544,10555,10558,10568,10571,10574,10581,10587,10598,10601,10607,10610,10618,10621,10628,10630,10634,10637,10644,10647,10677,10688,10695,10705,10715,10717,10721,10727,10730,10759,10762,10765,10780,10783,10789,10791,10795,10798,10805,10808,10823,10826,10849,10856,10859,10867,10882,10885,10888,10894,10897,10914,10920,10929,10931,10933,10936,10939,10942,10957],[31,10495,10497,10501],{"className":10496},[34,35,36],[31,10498,10500],{"className":10499},[40],"💬",[31,10502,10504],{"className":10503},[45],"制作イベントを、Kitsuメッセージングボットで即時のチャット通知やコマンドに変えましょう。",[48,10506,10507],{},"チャットUIは現代の職場を席巻しています。制作チームはスレッドで連携し、承認はメールで行われ、LLM搭載のアシスタントが日々のオペレーションの一部になりつつあります。",[48,10509,10510],{},"本当の問題は、適切な統合です。たとえば「レビュー準備完了」のショットを知らせるメッセージは、理想的には、スーパーバイザーがそのショットを承認し、正しいユーザーのもとでKitsuのステータスを更新できるはずです。しかしそのためには、小さなバックエンドサービス、Kitsuへの安全なAPI接続、そしてチャットユーザーとKitsuユーザーを確実に対応付ける仕組みが必要になります。朗報として、あなたはすでにKitsuでそれを実現できます！",[48,10512,10513],{},"シンプルな出発点は、/hello のような1つのコマンドを持つTelegramボットです。ボットは最初にチャットユーザーをKitsuアカウントへ一度だけリンクし、その後はAPIを通じて返信し、チャット上に表示します。Kitsuで何かイベントが起きるたびに、ボットがあなたに通知します。この小さな統合がコンセプトを証明しており、この記事ではまさにそれを作っていきます。",[61,10515],{},[64,10517,10519],{"id":10518},"why-custom-messaging-integrations","カスタム・メッセージング統合が必要な理由",[48,10521,10522],{},"カスタム・メッセージング統合は、単一の真実の情報源（single source of truth）を中心にコミュニケーションを集約します。スーパーバイザーがタスクのステータス変更に関するメールを転送する代わりに、更新は自動的に該当するチームのチャネルへプッシュできます。たとえば、照明タスクがKitsuで「撮り直し（retake）」に切り替わると、照明のTelegramグループはショット名、担当者、締切を含む構造化されたメッセージを即座に受け取ります。制作トラッカーは先回りして動くようになります。",[48,10524,10525],{},"生のデータベースイベントを読みやすい要約に再構成すると、ユーザー体験は向上します。アーティストが、何が変わったのかを理解するためにアクティビティログを掘り下げる必要はありません。Telegramのチャンネルに送られる日次ダイジェストには、承認、新しい割り当て、今後の締切が平易な言葉でまとめられます。このダイジェストはKitsu APIから直接生成でき、毎晩自動で配信することで、制作データを“人が実際に読む”ものへ変えられます。",[48,10527,10528],{},"ただし、このアプローチの本当の効果が発揮されるのは、自動化の場面です。メッセージングプラットフォームは軽量なコマンドインターフェースとして機能します。たとえば、Telegramで「/late_shots」と入力するコーディネーターは、Kitsuへクエリを投げて、期限超過のタスク一覧を即座に受け取れます。「/assign SH010 alice」とタイプするリードは、バックエンド呼び出しをトリガーしてKitsuの割り当てを更新できます。チャットは、制作データベースのための運用上の“操作面”になります。",[48,10530,10531],{},"とはいえ、先ほど言ったとおり、まずはKitsuと連携するTelegramボットから始めましょう。",[61,10533],{},[64,10535,10537],{"id":10536},"_1-create-a-new-telegram-bot","1. 新しいTelegramボットを作成する",[48,10539,10540],{},"まず、Telegram上で専用のボットを作成します。ボットを分離しておくことで、資格情報（クレデンシャル）をきれいに保て、制作環境へ引き渡す際に将来のセキュリティ上の面倒が増えるのを避けられます。",[48,10542,10543],{},"Telegramを開き、他のボットを管理するための公式ボットであるBotFatherを検索します。",[48,10545,10546,10547,10550,10551,10554],{},"チャットを開始し、",[155,10548,10549],{},"/newbot"," を送信します。手順はシンプルです。「Kitsu Notifications」のような人が読める名前を入力し、その後に ",[155,10552,10553],{},"kitsu_pipeline_bot"," のような固有のユーザー名を設定します。ユーザー名は「bot」で終わる必要があり、かつグローバルに一意であるため、スタジオ環境ではいくつか試すことになるでしょう。",[48,10556,10557],{},"BotFatherはAPIトークンを返します。このトークンをSlackに貼り付けたり、Gitへコミットするための“便利な文字列”として扱わないでください。環境設定システムに保存します。このトークンが漏れると、誰でも制作ボットとしてメッセージを送れます。制作担当者がスパムを受け取り始めると、あっという間に“面白い”状態から“致命的”な状態へ変わります。",[72,10559,10561],{"className":10560},[34,75],[77,10562],{"src":10563,"className":10564,"alt":12,"loading":82,"width":10565,"height":10566,"srcSet":10567,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-10.png",[81],976,925,"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-10.png 600w, https://blog.cg-wire.com/content/images/2026/03/image-10.png 976w",[48,10569,10570],{},"これをKitsuのイベントシステムに接続する前に、トークンを手動で検証しましょう。",[48,10572,10573],{},"Telegram内で、作成したばかりのボットをユーザー名で検索し、そのボットとの会話を開始します。Telegramがチャットを登録できるように、シンプルに「/start」を送信してください。",[48,10575,10576,10577,10580],{},"クライアント（チャット）IDを取得するには、トークンを使ってcurlで ",[155,10578,10579],{},"getUpdates"," エンドポイントを呼び出します。例えば：",[152,10582,10583],{},[155,10584,10586],{"className":10585},[158],"curl https://api.telegram.org/bot\u003CTOKEN>/getUpdates\n",[48,10588,10589,10590,10593,10594,10597],{},"レスポンスには、",[155,10591,10592],{},"chat","オブジェクトと ",[155,10595,10596],{},"id","フィールドを含むJSONペイロードが入ります。この数値IDが、統合がターゲットにするものです。実際のパイプラインのシナリオでは、個人ユーザーというより、スーパーバイザーのグループのチャットIDであることもあります。",[48,10599,10600],{},"次に、アウトバウンドのメッセージ送信を直接テストします。curlで自分宛てにメッセージを送ってください：",[152,10602,10603],{},[155,10604,10606],{"className":10605},[158],"curl -X POST https://api.telegram.org/bot\u003CTOKEN>/sendMessage -d chat_id=\u003CCHAT_ID> -d text=\"Kitsu integration test\"\n",[48,10608,10609],{},"メッセージがTelegramに表示されれば、トークンとチャットIDは有効です。この手動検証のステップは、同じ呼び出しをKitsuのイベントフックに組み込んだときに、何かが静かに失敗するようなケースで、後からデバッグに数時間を費やすのを防いでくれます。",[72,10611,10613],{"className":10612},[34,75],[77,10614],{"src":10615,"className":10616,"alt":12,"loading":82,"width":10565,"height":10566,"srcSet":10617,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-11.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-11.png 600w, https://blog.cg-wire.com/content/images/2026/03/image-11.png 976w",[48,10619,10620],{},"ボットが検証できたら、次はKitsuのイベントシステムに接続します。たとえば、新しいアセットが作成されたら、スーパーバイザーのTelegramグループにメッセージが自動でプッシュされるようにします。",[48,10622,10623,10624,10627],{},"curlでテストしたのとまったく同じ ",[155,10625,10626],{},"sendMessage"," エンドポイントが、Kitsuによってトリガーされる小さなサービス、またはサーバーレス関数の一部になります。",[61,10629],{},[64,10631,10633],{"id":10632},"_2-set-a-kitsu-event-listener","2. Kitsuのイベントリスナーを設定する",[48,10635,10636],{},"次に、Kitsuからのリアルタイムイベントを購読する必要があります。目的はシンプルです。制作データが変わる瞬間に反応します。",[48,10638,10639,10640,10643],{},"Kitsuの ",[155,10641,10642],{},"zou"," Python SDKを使ってウェブソケット接続を開き、タスク更新イベントをリッスンできます。",[48,10645,10646],{},"たとえば、Kitsuのイベントストリームに接続し、アセット作成イベントをフィルタリングします：",[152,10648,10649,10671],{},[155,10650,10652,10653,10666],{"className":10651},[175],"import gazu \n",[48,10654,182,10655,10659,10660,10663,10664,869],{},[94,10656,10657],{"href":10657,"rel":10658},"http://localhost:80/api",[187],"\")\ngazu.set_event_host(\"",[94,10661,10657],{"href":10657,"rel":10662},[187],"\")\ngazu.log_in(\"",[94,10665,192],{"href":191},[48,10667,10668,10669,2098],{},"def my_callback(data):\nprint(\"Asset created %s\" % data",[263,10670,2093],{},[48,10672,10673],{},[155,10674,10676],{"className":10675},[175],"event_client = gazu.events.init()\ngazu.events.add_listener(event_client, \"asset:new\", my_callback)\ngazu.events.run_client(event_client)\n",[48,10678,10679,10681,10682,10687],{},[155,10680,165],{}," ライブラリを使って、",[155,10683,10684],{},[94,10685,10657],{"href":10657,"rel":10686},[187]," のローカルホスト上にあるKitsu APIサーバーへ接続し、指定された管理者認証情報で認証したうえで、リアルタイムイベントをリッスンします。",[48,10689,10690,10691,10694],{},"この抜粋では、イベントがトリガーされるたびに新しく作成されたアセットのIDを出力するコールバック関数 ",[155,10692,10693],{},"my_callback"," を定義しています。",[48,10696,10697,10700,10701,10704],{},[155,10698,10699],{},"gazu.events.init()"," でイベントクライアントを初期化した後、スクリプトは ",[155,10702,10703],{},"\"asset:new\""," イベントをリッスンするためにコールバックを登録します（このイベントは、システム内で新しいアセットが作成されるたびに発火します）。",[48,10706,10707,10710,10711,10714],{},[155,10708,10709],{},"gazu.events.run_client(event_client)"," はイベントループを開始し、Kitsuに新しいアセットが追加されるたびにコールバックが実行され、その ",[155,10712,10713],{},"asset_id"," が出力される状態を維持します。",[61,10716],{},[64,10718,10720],{"id":10719},"_3-use-the-telegram-api-to-send-a-message","3. メッセージを送るためにTelegram APIを使う",[48,10722,10723,10724,10726],{},"イベントが流れてくる状態になったら、先ほどのテストと同様に、Telegramの ",[155,10725,10626],{}," エンドポイントでメッセージを外へ押し出します。APIは、HTTP POSTで、ボットトークン、チャットID、テキストのペイロードを含めるだけです。",[48,10728,10729],{},"それを小さなユーティリティ関数にまとめます：",[152,10731,10732,10754],{},[155,10733,10735,10736,10739,10748],{"className":10734},[175],"import requests\nimport os",[48,10737,10738],{},"TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')\nTELEGRAM_CHAT_ID = os.getenv('TELEGRAM_CHAT_ID')",[48,10740,10741,10742,10747],{},"def send_telegram_message(text):\nurl = f\"",[94,10743,10746],{"href":10744,"rel":10745},"https://api.telegram.org/bot%7BTELEGRAM_BOT_TOKEN%7D/sendMessage",[187],"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage","\"\npayload = {\n\"chat_id\": TELEGRAM_CHAT_ID,\n\"text\": text,\n\"parse_mode\": \"Markdown\"\n}",[152,10749,10752],{"className":10750,"code":10751,"language":292},[290],"response = requests.post(url, json=payload, timeout=5)\n\nif not response.ok:\n    raise RuntimeError(\n        f\"Telegram API error {response.status_code}: {response.text}\"\n    )\n",[155,10753,10751],{"__ignoreMap":12},[48,10755,10756],{},[155,10757],{"className":10758},[175],[48,10760,10761],{},"Gitリポジトリに保存され続けるのを防ぐため、秘密の環境変数を定義している点に注意してください。",[48,10763,10764],{},"そしてイベントコールバックから呼び出します：",[152,10766,10767,10771],{},[155,10768,10770],{"className":10769},[175],"from your_telegram_module import send_telegram_message",[48,10772,10773],{},[155,10774,10776,10777,10779],{"className":10775},[175],"def my_callback(data):\nsend_telegram_message(\"Asset created %s\" % data",[263,10778,2093],{},")\n",[48,10781,10782],{},"イベントリスナーをテストするには：",[152,10784,10785],{},[155,10786,10788],{"className":10787},[158],"TELEGRAM_BOT_TOKEN=\u003CTELEGRAM_BOT_TOKEN> TELEGRAM_CHAT_ID=\u003CCHAT_ID> python server.py\n",[61,10790],{},[64,10792,10794],{"id":10793},"_4-receiving-messages-with-a-custom-kitsu-api-endpoint","4. カスタムKitsu APIエンドポイントでメッセージを受け取る",[48,10796,10797],{},"通知は便利ですが、双方向のコミュニケーションこそが、この統合を本当に価値あるものにします。",[48,10799,10800,10801,10804],{},"そのためには、Kitsuバックエンドを拡張して、",[155,10802,10803],{},"/plugins/telegram/webhook"," のような新しいルートを登録するカスタムプラグインを用意する必要があります。詳細な手順は、公式の「Kitsuプラグインを開発する」ガイドを参照してください。",[48,10806,10807],{},"マニフェストは次のようになります：",[152,10809,10810],{},[155,10811,10814,10815,10819,10820,10822],{"className":10812},[10813],"language-toml","id = \"telegram\"\nname = \"Telegram Bot\"\ndescription = \"Telegram Bot\"\nversion = \"0.1.0\"\nmaintainer = \"Frank Rousseau \u003C",[94,10816,10818],{"href":10817},"mailto:frank@cg-wire.com","frank@cg-wire.com",">\"\nwebsite = \"kitsu.cloud\"\nlicense = \"AGPL-3.0-only\"\nmaintainer_name = \"Frank Rousseau\"\nmaintainer_email = \"",[94,10821,10818],{"href":10817},"\"\nfrontend_project_enabled = true\nfrontend_studio_enabled = true\nicon = \"telegram\"\n",[48,10824,10825],{},"そしてカスタムルートは、受け取ったコマンドを解析して、それを明確なバックエンドのアクションへマッピングします：",[152,10827,10828,10844],{},[155,10829,10831,10832,10838],{"className":10830},[175],"from flask_restful import Resource",[48,10833,10834,10835,2098],{},"class WebhookResource(Resource):\ndef post(self):\nargs = self.get_args(",[263,10836,10837],{},"\n(\"message\", {}, True),\n(\"chat\", {}, True),\n",[152,10839,10842],{"className":10840,"code":10841,"language":292},[290],"    message = args['message']\n    chat_id = args['chat'].get(\"id\")\n    text = message.get(\"text\", \"\")\n\n    if text == \"/hello\":    \n        send_telegram_message(\"it works\")\n\n    return jsonify({\"status\": \"ok\"})\n",[155,10843,10841],{"__ignoreMap":12},[48,10845,10846],{},[155,10847],{"className":10848},[175],[48,10850,10851,10852,10855],{},"シンプルさのために ",[155,10853,10854],{},"/hello"," という単一のコマンドを定義していますが、さらにたくさん作って、Kitsuのサービスを使って制作データを問い合わせることもできます。",[48,10857,10858],{},"決定論的（deterministic）なコマンドは、テストしやすく、ログもしやすく、セキュアです。さらに一歩進めて、LLMに自然言語のリクエストをコマンドへマッピングさせることもできます。",[48,10860,10861,10862,10866],{},"必要なのは、主要なエントリポイント ",[155,10863,10864,1776],{},[120,10865,1775],{}," にルートを登録することだけです：",[152,10868,10869,10873],{},[155,10870,10872],{"className":10871},[728],"from . import resources",[48,10874,10875],{},[155,10876,10878,10879],{"className":10877},[728],"routes = ",[263,10880,10881],{},"(f\"/telegram/webhook\", resources.WebhookResource)",[48,10883,10884],{},"Kitsuサーバーインスタンスにプラグインをパッケージングしてインストールしたら、次はTelegramボットに「どうやってそこへ到達するか」を教えます。",[48,10886,10887],{},"ローカル開発環境を使う場合、トンネルでサーバーを公開できます。たとえばngrokで、サーバーがポート5000で動いているなら：",[152,10889,10890],{},[155,10891,10893],{"className":10892},[158],"ngrok http 5000\n",[48,10895,10896],{},"そして、TelegramボットのWebhookをそのURLへ向けるように設定します：",[152,10898,10899],{},[155,10900,10902,10903,10907,10908,10910,10911,10913],{"className":10901},[158],"curl -X POST \"",[94,10904,10905],{"href":10905,"rel":10906},"https://api.telegram.org/bot&lt;YOUR_BOT_TOKEN&gt;/setWebhook",[187],"\" ",[125,10909],{},"\n-H \"Content-Type: application/json\" ",[125,10912],{},"\n-d '{\"url\": \"https://\u003Crandom>.ngrok-free.app/plugin/telegram/webhook\"}'\n",[48,10915,10916,10917,10919],{},"これで、Telegramチャットでボットに ",[155,10918,10854],{}," を送って結果を確認します：",[72,10921,10923],{"className":10922},[34,75],[77,10924],{"src":10925,"className":10926,"alt":12,"loading":82,"width":10927,"height":10928},"https://blog.cg-wire.com/content/images/2026/03/image-12.png",[81],525,560,[61,10930],{},[64,10932,508],{"id":507},[48,10934,10935],{},"Kitsuと連携するカスタム・メッセージング統合は、常に似たパターンに従います。メッセージングプラットフォーム上でボットを作成し、Kitsuのイベントを購読し、構造化された通知を送信し、受信したメッセージを処理するためのバックエンドのルートを公開します。",[48,10937,10938],{},"しかし、それだけではありません。Kitsuプラグインにビューを追加することも検討してください。",[48,10940,10941],{},"たとえば、ボットのアクティビティや最近のやり取りをダッシュボード上に直接表示します。Kitsu内で作業するスーパーバイザーは、どのアラートが送られ、どのコマンドがトリガーされたかを確認できるようになります。可能性は無限です！",[31,10943,10945,10948],{"className":10944},[34,35,36],[31,10946,524],{"className":10947},[40],[31,10949,10951,10952,10956],{"className":10950},[45],"アニメーション制作プロセスについてもっと知るには",[94,10953,10955],{"href":531,"rel":10954},[533],"Discordコミュニティに参加することを検討してください","！私たちはベストプラクティスを共有する1,000人以上の専門家とつながっており、ときには対面イベントも企画しています。ぜひ歓迎します！ 😊",[31,10958,10960],{"className":10959},[34,539,540],[94,10961,546],{"href":531,"className":10962},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":10964},[10965,10966,10967,10968,10969,10970],{"id":10518,"depth":548,"text":10519},{"id":10536,"depth":548,"text":10537},{"id":10632,"depth":548,"text":10633},{"id":10719,"depth":548,"text":10720},{"id":10793,"depth":548,"text":10794},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1577563908411-5077b6dc7624?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fG1lc3NhZ2V8ZW58MHx8fHwxNzczMDM5MzU5fDA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":10973,"featured_at":561,"visibility":562},"2026-03-09T08:00:23.000+01:00","/blog-i18n/ja/kitsu-telegram-bot-integration",{"title":10489,"description":12},"kitsu-telegram-bot-integration","blog-i18n/ja/kitsu-telegram-bot-integration/index",[10979],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"DZCBNZfi2QPcGCBcbdG8r9f5atrGYoCgP3nwBMXnoZ8",{"id":10982,"title":10983,"authors":10984,"body":10986,"description":12,"extension":557,"feature_image":11351,"html":7,"meta":11352,"navigation":13,"path":11354,"published_at":11353,"seo":11355,"slug":11356,"stem":11357,"tags":11358,"__hash__":11360,"updated_at":11353,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/kitsu-webhooks-pipeline-automation/index.md","Kitsu Webhookでパイプラインアクションをトリガーする方法",[10985],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":10987,"toc":11342},[10988,10998,11005,11008,11015,11018,11043,11045,11049,11057,11060,11063,11066,11069,11072,11075,11077,11081,11088,11111,11114,11116,11120,11126,11150,11160,11167,11172,11178,11190,11202,11204,11208,11211,11238,11245,11248,11255,11261,11264,11266,11270,11273,11276,11279,11282,11289,11291,11295,11298,11301,11307,11310,11313,11315,11317,11320,11323,11336],[31,10989,10991,10994],{"className":10990},[34,35,36],[31,10992,2601],{"className":10993},[40],[31,10995,10997],{"className":10996},[45],"Kitsuのwebhookで、制作イベントを即時のパイプラインアクションに変えましょう。",[48,10999,11000,11001,11004],{},"スタジオが成長するにつれて、手作業のパイプラインに生じたほころびがより大きく目立つようになります。アーティストがアセットをパブリッシュし、スーパーバイザーがショットを承認し、タスクが",[655,11002,11003],{},"Done","に切り替わる。しかし、どこかの段階で別のツールがまだ「何かを言われ待ち」になっている。そうした遅れは積み重なっていきます。",[48,11006,11007],{},"KitsuのEvent APIは、制作で何が起きたかを、その瞬間に配信することで状況を一変させます。ポーリングも、推測も不要です。行動に移せるリアルタイムのシグナルだけが得られます。",[48,11009,11010,11011,11014],{},"webhookを使えば、",[94,11012,11013],{"href":9186},"レンダリングの起動","、トラッキングツールの同期、チームへの通知、あるいは人を介した引き継ぎなしでの下流システムの更新などのように、制作データが変化した瞬間に自動アクションをトリガーできます。",[48,11016,11017],{},"この記事では、セットアップ方法と、それを実際に活用する手順を解説します。スタジオで検証済みの実用的な例を、リアルなパイプラインにそのまま組み込めます。",[31,11019,11021,11024],{"className":11020},[34,35,108],[31,11022,112],{"className":11023},[40],[31,11025,11027,11031,11033,6968,11035,11037,134,11039],{"className":11026},[45],[117,11028,11029],{},[120,11030,623],{"style":122},[125,11032],{},[125,11034],{},[125,11036],{},[125,11038],{},[94,11040,11042],{"href":11041},"https://github.com/cgwire/blog-tutorials/tree/main/kitsu-webhooks%20?ref=blog.cg-wire.com","https://github.com/cgwire/blog-tutorials/tree/main/kitsu-webhooks%20",[61,11044],{},[64,11046,11048],{"id":11047},"why-webhooks","なぜwebhookなのか",[72,11050,11052],{"className":11051},[34,75],[77,11053],{"src":11054,"className":11055,"alt":12,"loading":82,"width":83,"height":84,"srcSet":11056,"sizes":86},"https://blog.cg-wire.com/content/images/2026/02/data-src-image-9c7a79f2-b129-45df-bea5-52e3d0e07988.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/02/data-src-image-9c7a79f2-b129-45df-bea5-52e3d0e07988.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/02/data-src-image-9c7a79f2-b129-45df-bea5-52e3d0e07988.png 1000w, https://blog.cg-wire.com/content/images/2026/02/data-src-image-9c7a79f2-b129-45df-bea5-52e3d0e07988.png 1600w",[48,11058,11059],{},"数分おきにAPIをポーリングするのは、フロア中に叫んで「更新はないのか」と制作に尋ねるようなものです。遅い上に騒がしく、しかも「問題が起きた瞬間」を見逃しやすい。",[48,11061,11062],{},"webhookはこのモデルを反転させます。Kitsuが変わったかどうかを確認するのではなく、Kitsuが変化した瞬間にあなたのパイプラインへすぐに伝えてくれるのです。",[48,11064,11065],{},"これにより、実際の制作では複数のメリットがあります。たとえばモデラーがKitsuで新しいプロップを作成すると、数秒以内に、アセット構築システムがサーバー上で正しいディレクトリ構造を立ち上げます。さらにDCCツールにアセットを登録し、レイアウトから見えるようにします。誰も名前をコピーしたり、ボタンをクリックしたりする必要はありません。",[48,11067,11068],{},"後のスケジュールで、ライティングのタスクがDoneに移動するとします。たった1回のステータス変更が、レンダーマネジメントシステムに対してショットを自動提出させるトリガーになります。最新の承認済みファイルと、そのショーに適した正しいレンダー設定を使います。誰かがタスクの完了に気づく頃には、すでにフレームがレンダリングされている状態です。",[48,11070,11071],{},"アーティストがファイルをパブリッシュしたとき、webhookはそのバージョンをそのままレビュー用スタックへ押し込むこともできます。承認済みが開封される前にメディアをトランスコードし、アップロードし、正しいショットに紐づけます。レビューはより早く行われ、ノートはより速く返り、作業は「誰かが次の手順を思い出すのを待つ」状態から解放されて流れ続けます。",[48,11073,11074],{},"つまりwebhookがもたらすのはこれです。制作データが、そのままアクションに直結すること。引き継ぎが減り、フィードバックループがより密になり、アーティストが作業するのと同じスピードでパイプラインが反応できるようになります。",[61,11076],{},[64,11078,11080],{"id":11079},"available-events","利用可能なイベント",[48,11082,11083,11084,11087],{},"Kitsuは、",[94,11085,11086],{"href":250},"利用可能なデータモデル","でカバーされている制作アクションすべてに対してイベントを発行します：",[212,11089,11090,11093,11096,11099,11102,11105,11108],{},[215,11091,11092],{},"アセットの作成と更新",[215,11094,11095],{},"ショットの作成と更新",[215,11097,11098],{},"タスクステータスの変更",[215,11100,11101],{},"プレビュー用ファイルの作成とパブリッシュ",[215,11103,11104],{},"人（担当）の管理",[215,11106,11107],{},"組織の変更",[215,11109,11110],{},"ショットおよびシーケンスの更新",[48,11112,11113],{},"各イベントには構造化されたデータ（ID、タイムスタンプ、ユーザー情報など）が含まれるため、何が変わったのかを正確に特定し、それに応じてリアクションできます。購読できるリアルタイムの制作ログです！",[61,11115],{},[64,11117,11119],{"id":11118},"_1-create-an-event-listener","1. イベントリスナーを作成する",[48,11121,11122,11123,11125],{},"最初のステップは、Kitsu Pythonクライアント（",[155,11124,165],{},"）を使ってイベントリスナーを登録することです。このリスナーはwebhookエンドポイントのように振る舞います。つまり、イベントを待ち、発生したらコールバック関数を呼び出します。",[152,11127,11128,11145],{},[155,11129,176,11131,11141],{"className":11130},[728],[48,11132,182,11133,10659,11136,188,11139,869],{},[94,11134,185],{"href":185,"rel":11135},[187],[94,11137,185],{"href":185,"rel":11138},[187],[94,11140,192],{"href":191},[48,11142,10668,11143,2098],{},[263,11144,2093],{},[48,11146,11147],{},[155,11148,10676],{"className":11149},[728],[48,11151,11152,11153,3017,11156,11159],{},"まず、Kitsu向けの公式PythonクライアントであるGazuをインポートし、ローカルで動作するKitsuサーバーに接続するように設定します。",[155,11154,11155],{},"set_host",[155,11157,11158],{},"set_event_host","は、どちらも同じAPI URLを指しています。前者は通常のREST呼び出しに使われ、後者はイベント（websocket）エンドポイントに特化しています。本番では、イベントを聴く処理がブロッキングになるため、2つを別スレッドで設定することが推奨されます。ただしこのチュートリアルでは、わかりやすさのために1つのエンドポイントでまとめて行います。",[48,11161,11162,11163,11166],{},"次に、ユーザーとして認証します。",[155,11164,11165],{},"gazu.log_in","を呼び出すと、指定した資格情報でログインされ、セッションが確立されるため、クライアントがKitsuからのイベントを受け取る権限を得ます。",[48,11168,11169,11171],{},[155,11170,10693],{},"関数は、イベントを受け取ったときにパイプラインがどう反応するかを定義します。入力としてイベントのペイロードを受け取り、この場合は新しく作成されたアセットのIDを単に表示するだけです。中規模のアニメーションスタジオでは、このコールバックが、たとえばKitsuに新しいアセットが追加されたときにファイルサーバーへ標準化されたディレクトリ構造を作成するスクリプトをトリガーする、という形になるかもしれません。アーティストは手作業で設定する必要がなくなり、命名規則も一貫性を保てます。",[48,11173,11174,11175,11177],{},"その後、",[155,11176,10699],{},"でイベントクライアントを初期化します。このクライアントは、Kitsuのイベントシステムへの永続的な接続を維持します。",[48,11179,11180,11183,11184,11186,11187,11189],{},[155,11181,11182],{},"gazu.events.add_listener","の呼び出しは、特定のイベントタイプに対してコールバック関数を登録します：",[155,11185,10703],{},"。これはGazuに対して、「Kitsuが新しいアセットが作成されたことを示すイベントを発行したら、イベントデータを使って",[155,11188,10693],{},"を呼び出してほしい」と伝えるものです。",[48,11191,9977,11192,11194,11195,11198,11199,11201],{},[155,11193,10709],{},"がイベントループを開始します。この時点以降、スクリプトはブロックされ、WebSocket接続を通じて継続的に待ち受けます。Kitsuで誰かがアセットを作成するとすぐに、Kitsuが",[155,11196,11197],{},"asset:new","イベントを発行し、Gazuが受け取り、",[155,11200,10693],{},"が即座に実行されます。",[61,11203],{},[64,11205,11207],{"id":11206},"_2-send-test-events","2. テストイベントを送信する",[48,11209,11210],{},"セットアップを検証するには、実際のイベントを生成する必要があります。最も簡単な方法は、すでに本番で使っている標準APIアクションを実行することです。たとえば、アセットをプログラムで作成してみます：",[152,11212,11213,11232],{},[155,11214,2943,11216,11223,11227],{"className":11215},[728],[48,11217,182,11218,188,11221,869],{},[94,11219,185],{"href":185,"rel":11220},[187],[94,11222,192],{"href":191},[48,11224,261,11225],{},[263,11226,265],{},[48,11228,11229,11230],{},"asset_types = gazu.asset.all_asset_types()\nasset_type = asset_types",[263,11231,265],{},[48,11233,11234],{},[155,11235,11237],{"className":11236},[728],"asset = gazu.asset.new_asset(\nproject,\nasset_type,\n\"My new asset\",\n\"My asset description\"\n)\n",[48,11239,11240,11241,11244],{},"認証の後、",[155,11242,11243],{},"gazu.project.all_projects()","を呼び出してログイン済みユーザーから見えるすべてのプロジェクトの一覧を取得します。そのリストから最初のプロジェクトを選択します。本番の制作ツールでは通常、名前やIDで特定のプロジェクトを探すことが多いですが、この例ではシンプルに保ちます。",[48,11246,11247],{},"アセットタイプでも同様のパターンを使います。スクリプトは利用可能なすべてのアセットタイプを問い合わせ、最初のものを選びます。アセットタイプは、どのような種類のアセットを作成するか（キャラクター、プロップ、環境など）を定義し、新しいアセットを作成する際にKitsuでは指定が必須です。",[48,11249,11250,11251,11254],{},"プロジェクトとアセットタイプを用意したら、",[155,11252,11253],{},"gazu.asset.new_asset","を呼び出して新しいアセットを作成します。この関数は、対象プロジェクト、アセットタイプ、名前、説明を受け取ります。この呼び出しが成功すると、Kitsuは即座に自分のデータベースへアセットを作成し、作成されたばかりのアセットオブジェクトを返します。",[48,11256,11257,11258,11260],{},"この時点でアセットは、Webインターフェースから作成されたかのようにKitsuに存在します。このアクションはまた、残りのパイプラインが自動的に反応できるように、",[155,11259,11197],{},"イベントを発行します。",[48,11262,11263],{},"スタジオ全体に展開する前に、パイプラインTDがステージング用のプロジェクトでアセットを作成し、実運用データに触れることなく、イベントが下流のオートメーションを確かにトリガーするかを確認することができます。",[61,11265],{},[64,11267,11269],{"id":11268},"_3-react-to-events-with-callbacks","3. コールバックでイベントにリアクションする",[48,11271,11272],{},"コールバックは、Kitsuのイベントが具体的なパイプラインアクションへ変わるポイントです。コールバックが実行されると、何が変わったのかを正確に説明するペイロードが渡されます。たとえばアセットが作成された、タスクが新しいステータスへ移動した、ファイルがパブリッシュされた、などです。このペイロードが、オートメーションを動かすための入口になります。",[48,11274,11275],{},"コールバック内で最初に行われることが多いのは、イベントデータに含まれるIDを使ってKitsuから完全なコンテキストを引き出すことです。たとえばタスク更新イベントを受け取った場合、変更が制作のどこで起きたのか、どのルールが適用されるべきかを理解するために、完全なタスク、紐づいたショット、関連するプロジェクトを取得できます。",[48,11277,11278],{},"そこから先は、多くの場合、コールバックが本来手動の介入を要するであろう副作用（サイドエフェクト）を実行します。アセット作成イベントは、たとえばディスク上に標準化されたフォルダーのツリーを作成することにつながるかもしれません。ファイルのパブリッシュイベントは、メディアをレビューシステムへ投入し、メタデータを紐づけ、スーパーバイザーにすぐ見えるようにします。",[48,11280,11281],{},"重要な考え方は、コールバックによって制作の状態が振る舞いを決めることです。人が更新に反応するのではなく、あなたのパイプラインが、毎回同じルールで一貫して、かつ即時に反応します。",[48,11283,11284,11288],{},[94,11285,11287],{"href":11041,"rel":11286},[533],"こちらの例のGithubリポジトリをフォーク","して、自分で試してみてください。",[61,11290],{},[64,11292,11294],{"id":11293},"_4-search-events","4. イベントを検索する",[48,11296,11297],{},"ライブイベントは全体の半分にすぎません。Kitsuは過去のイベントも記録しており、実際に制作で何が起きたのかを信頼できる形で追跡できます。何かがうまくいかなかったとき、または「うまく動いた」ことを証明する必要があるとき、このイベント履歴は欠かせないデバッグ手段です。",[48,11299,11300],{},"APIを通じて、最近のイベントを照会したり、期間やイベントタイプでフィルタリングしたりできます。直近の100件を引っ張るだけで、失敗直後の状況把握に十分なことが多いです。照会を特定の日時範囲に絞れば、そのシフトや夜間バッチの間に何が起きたかを詳しく調べられます。ファイル関連のイベントに絞り込むのは、パブリッシュやメディア取り込みの問題を追跡する際に特に有用です。",[152,11302,11303],{},[155,11304,11306],{"className":11305},[728],"events = gazu.client.get(\"data/events/last?page_size=100\")\nevents = gazu.client.get(\"data/events/last?page_size=100&before=2019-02-01\")\nevents = gazu.client.get(\"data/events/last?page_size=100&before=2019-02-01&after=2019-01-01\")\nevents = gazu.client.get(\"data/events/last?page_size=100&only_files=true\")\n",[48,11308,11309],{},"実際には、これを使うことで壊れたオートメーションを復元できます。たとえば、夜のどこかでパブリッシュスクリプトが失敗し、朝のチームがレビューシステム上でメディアが欠けているのを見つけたとします。アーティストに「いつパブリッシュしたのか」を聞いたり、複数のマシンにまたがるログを掘り起こしたりする代わりに、前日分のすべてのファイルイベントをKitsuに問い合わせられます。そうすれば、パブリッシュの正確な時系列、タイムスタンプ、ユーザー、紐づいたエンティティを把握できます。",[48,11311,11312],{},"また、生産性レポートのために、パイプライン内で特定のイベントを追跡することもできます。たとえば、アニメーションチームの活動ログをまとめて「誰が何をしたか」を知る、というようなことです。",[61,11314],{},[64,11316,2530],{"id":507},[48,11318,11319],{},"Kitsu APIのイベントは、リアクティブなパイプラインを構築するための、きれいで信頼できる手段を提供します。ポーリングして変化を探すのではなく制作の変化を待ち受けることで、遅延を減らし、手作業のステップを排除し、スタジオがスケールしていく際にもより強靭になります。",[48,11321,11322],{},"もちろん、webhookはKitsuのスクリプトに対するあなたの知識の範囲でしか進められません。より技術的なチュートリアルについては、ぜひブログもチェックして、どんなものを作れるかのイメージをつかんでください！",[31,11324,11326,11329],{"className":11325},[34,35,36],[31,11327,524],{"className":11328},[40],[31,11330,528,11332,11335],{"className":11331},[45],[94,11333,3875],{"href":531,"rel":11334},[533],"！私たちはベストプラクティスを共有する1,000人以上の専門家とつながっており、ときどき対面イベントも企画しています。ぜひようこそお迎えできれば嬉しいです！😊",[31,11337,11339],{"className":11338},[34,539,540],[94,11340,546],{"href":531,"className":11341},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":11343},[11344,11345,11346,11347,11348,11349,11350],{"id":11047,"depth":548,"text":11048},{"id":11079,"depth":548,"text":11080},{"id":11118,"depth":548,"text":11119},{"id":11206,"depth":548,"text":11207},{"id":11268,"depth":548,"text":11269},{"id":11293,"depth":548,"text":11294},{"id":507,"depth":548,"text":2530},"https://images.unsplash.com/photo-1644088379091-d574269d422f?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fGNvbm5lY3Rpb25zfGVufDB8fHx8MTc3MDA0NTM2OXww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":11353,"featured_at":561,"visibility":562},"2026-02-23T10:00:39.000+01:00","/blog-i18n/ja/kitsu-webhooks-pipeline-automation",{"title":10983,"description":12},"kitsu-webhooks-pipeline-automation","blog-i18n/ja/kitsu-webhooks-pipeline-automation/index",[11359],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"sLJpvKcpuMByIH_qITo1pZqyTeHsIF93i5ilLym_3fo",{"id":11362,"title":11363,"authors":11364,"body":11366,"description":12,"extension":557,"feature_image":11742,"html":7,"meta":11743,"navigation":13,"path":11745,"published_at":11744,"seo":11746,"slug":11747,"stem":11748,"tags":11749,"__hash__":11751,"updated_at":11744,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/retopology-animation-blender-guide/index.md","アニメーションパイプラインにおけるリトポロジーが重要な理由",[11365],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":11367,"toc":11732},[11368,11378,11381,11388,11391,11393,11397,11411,11416,11432,11435,11438,11441,11444,11446,11450,11455,11462,11468,11474,11480,11482,11486,11491,11497,11500,11503,11506,11514,11517,11519,11523,11528,11531,11534,11536,11540,11545,11552,11555,11573,11579,11582,11593,11596,11601,11603,11607,11612,11618,11621,11639,11642,11647,11650,11652,11656,11661,11668,11671,11680,11683,11686,11689,11692,11694,11696,11701,11704,11707,11710,11713,11726],[31,11369,11371,11374],{"className":11370},[34,35,36],[31,11372,1862],{"className":11373},[40],[31,11375,11377],{"className":11376},[45]," リトポロジーは、ぐちゃぐちゃになった3Dメッシュをアニメーションに使えるアセットへ変えます。",[48,11379,11380],{},"AIツールは、数分で3Dモデルを生成できるようになりましたが、たいていはトポロジーがぐちゃぐちゃです。つまり、表面に沿ったポリゴンの並び方が均一でなく、構造も貧弱ということです。見た目は問題ないように見えるかもしれませんが、アニメーションを付け始めた瞬間に壊れます。",[48,11382,11383,11384,11387],{},"何らかのアニメーションやレンダリングを行うなら、",[120,11385,11386],{},"リトポロジーが必要になる","と考えてください。",[48,11389,11390],{},"どこから始めればいいかわからない場合も大丈夫です。この記事では、工程を順を追って説明し、作業を楽にするために使えるさまざまなツールを紹介します。",[61,11392],{},[64,11394,11396],{"id":11395},"whats-retopology","リトポロジーとは",[31,11398,11400,11403],{"className":11399},[34,35,108],[31,11401,112],{"className":11402},[40],[31,11404,11406,600],{"className":11405},[45],[117,11407,11408],{},[120,11409,11410],{"style":122},"リトポロジーとは、既存のスカルプの上に、アニメーションで正しく変形できるように、よりクリーンなポリゴン配置を作るために、3Dモデルのサーフェス・トポロジーを作り直すプロセスです",[48,11412,11413],{},[94,11414],{"href":11415},"https://github.com/cgwire/blog/blob/main/drafts/retopology/index.md?ref=blog.cg-wire.com#whats-retopology",[72,11417,11419,11424],{"className":11418},[34,75,6381],[77,11420],{"src":11421,"className":11422,"alt":12,"loading":82,"width":10928,"height":11423},"https://blog.cg-wire.com/content/images/2026/03/image-5.png",[81],220,[6389,11425,11426],{},[6392,11427,11428],{},[655,11429,11431],{"className":11430,"style":122},[6397],"出典：Blender Manual",[48,11433,11434],{},"たとえば、私たちは通常、ZBrushから出てきた高密度のスカルプをそのままアニメーションしません。代わりに、その上に軽量で構造化されたメッシュを構築します。",[48,11436,11437],{},"メッシュは、頂点（点）、エッジ（点と点の間の線）、面（表面）でできた3Dオブジェクトです。",[48,11439,11440],{},"リギングを考える前に、まずワイヤーフレーム表示でメッシュを確認し、高密度のかたまり、引き伸ばされたポリゴン、そしてエッジフローの混沌（エッジが表面上で辿る方向）を特定します。",[48,11442,11443],{},"キャラクターの場合、たとえば肩は三角形ではなく均等に配置したクワッド（4辺のポリゴン）で作り直すことで、腕がピンチせずに回転できるようにします。これがリトポロジーです。",[61,11445],{},[64,11447,11449],{"id":11448},"why-retopology-is-key","リトポロジーが重要な理由",[48,11451,11452],{},[94,11453],{"href":11454},"https://github.com/cgwire/blog/blob/main/drafts/retopology/index.md?ref=blog.cg-wire.com#why-retopology-is-key",[48,11456,11457,11458,11461],{},"リトポロジーは、モデルのサーフェスをクリーンなジオメトリで作り直します。そしてそれは、",[120,11459,11460],{},"制作をまたいでメンテナンスしやすく、再利用できるアセット","が欲しいなら必要です。アニメーターは、高密度スカルプのトポロジーをそのまま下流へ渡しません。代わりに、次のアニメーターやリガーが素早く理解して変更できるように、クリーンなエッジループで再構築します。",[48,11463,11464,11467],{},[120,11465,11466],{},"良いリトポロジーは、変形が予測可能になるためアニメーションを簡単にします。","変形とは、ジョイントが回転したときにメッシュがどのように形状を変えるかです。肘、膝、口まわりには、均等に配置したクワッドを用意し、変形を支えましょう。ジョイントの周囲に半径方向のエッジループを5〜7本配置すると、皮膚が潰れずに曲がるための十分なジオメトリが得られます。",[48,11469,9977,11470,11473],{},[120,11471,11472],{},"ポリゴン密度を制御することでレンダリングコストを抑えられます。","ポリゴンはジオメトリの1つの面で、数が増えるほど処理するデータも増えるため、シルエットが変化するディテールには集中し、平坦な部分は軽量にしてコストを削減します。",[48,11475,11476,11479],{},[120,11477,11478],{},"リトポロジーは必ず、どこかのタイミングで役に立ちます。"," 3Dモデルを修正する場合でも、異なるレベル・オブ・ディテール（LOD）を作る場合でも同じです。では、袖まくりして掘り下げていきましょう。",[61,11481],{},[64,11483,11485],{"id":11484},"_1-back-up-your-3d-model","1. 3Dモデルをバックアップする",[48,11487,11488],{},[94,11489],{"href":11490},"https://github.com/cgwire/blog/blob/main/drafts/retopology/index.md?ref=blog.cg-wire.com#1-back-up-your-3d-model",[48,11492,11493,11494,600],{},"まず最初に、",[120,11495,11496],{},"リトポロジーに触れる前に、毎回必ずモデルをバックアップすることが重要です",[48,11498,11499],{},"自動リトポロジーのツールは、トポロジーを最初から作り直すため、元のメッシュデータを上書き、または削除します。アーティストが長い一日の終わりにオート・レトポを走らせたあと、「新しいエッジフローのせいで肩周りの変形が壊れた」ことに気づき、しかも元のスカルプが消えてしまっている——そんなことが起こりがちです。",[48,11501,11502],{},"アンドゥに頼らないでください。クリーンな重複（コピー）を保存し、破壊的な処理を実行する前に、現在のメッシュをシーンにアーカイブしておきましょう。",[48,11504,11505],{},"制作現場では、変更を追跡・復元可能にするためにKitsuで新しいバージョンも作成します。こうすれば、リギングテストで新しいトポロジーが失敗しても、ITにファイル復元を頼む代わりに、数分でロールバックできます。",[72,11507,11509],{"className":11508},[34,75],[77,11510],{"src":11511,"className":11512,"alt":12,"loading":82,"width":3057,"height":3058,"srcSet":11513,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-6.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-6.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/03/image-6.png 1000w, https://blog.cg-wire.com/content/images/2026/03/image-6.png 1438w",[48,11515,11516],{},"バックアップはリトポロジー作業そのものの一部として扱いましょう！2分のバージョン更新と重複保存だけで、スカルプの作業日を守れます。また、上長が「before」と「after」のメッシュを比較したいと言ったときも、パイプラインが止まらないようにできます。",[61,11518],{},[64,11520,11522],{"id":11521},"_2-general-process","2. 一般的な進め方",[48,11524,11525],{},[94,11526],{"href":11527},"https://github.com/cgwire/blog/blob/main/drafts/retopology/index.md?ref=blog.cg-wire.com#2-general-process",[48,11529,11530],{},"基本のワークフローはシンプルです。スカルプをクリーンアップし、安定性のためにボクセルでリメッシュし、構造のためにクワッドでリメッシュし、その後、肩や腰などの変形領域を手作業で微調整します。",[48,11532,11533],{},"常に最初の段階で、素早いスキンウェイトと極端なポーズでテストしてください。",[61,11535],{},[64,11537,11539],{"id":11538},"_3-automated-retopology-with-remeshing","3. リメッシングによる自動リトポロジー",[48,11541,11542],{},[94,11543],{"href":11544},"https://github.com/cgwire/blog/blob/main/drafts/retopology/index.md?ref=blog.cg-wire.com#3-automated-retopology-with-remeshing",[48,11546,11547,11548,11551],{},"もしクリーチャーが800万ポリゴンもの高密度で、しかもぐちゃぐちゃな三角形ばかりで入ってきたら、",[120,11549,11550],{},"最初から手作業でリトポロジーを始めない","ほうがいいです。代わりに、まず自動のリメッシュ処理で構造を作り出します。",[48,11553,11554],{},"そのためにBlenderでは、リメッシングのアルゴリズムとしてVoxelとquadの2種類を提案しています。",[72,11556,11558,11565],{"className":11557},[34,75,6381],[77,11559],{"src":11560,"className":11561,"alt":12,"loading":82,"width":11562,"height":11563,"srcSet":11564,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-7.png",[81],1280,720,"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-7.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/03/image-7.png 1000w, https://blog.cg-wire.com/content/images/2026/03/image-7.png 1280w",[6389,11566,11567],{},[6392,11568,11569],{},[655,11570,11572],{"className":11571,"style":122},[6397],"出典：MediumのSofia Pahaoja",[48,11574,11575,11578],{},[120,11576,11577],{},"ボクセル・リメッシング","（VDB Remesh）は、メッシュを3Dグリッド上の小さな立方体（ボクセル）に変換し、元のエッジフローではなく体積に基づいてサーフェスを作り直すことで機能します。",[48,11580,11581],{},"その結果、均等に分布したジオメトリが得られるため、穴の修正、非マニホールド形状（一定のサーフェス法線を保ったまま2D平面へ展開できない構造）、交差している部分などの修正に非常に適しています。既存のトポロジーを厳密に保持することをあまり気にせず、「新しいベースメッシュ」が必要なときはボクセルを使います。すると結果はぐちゃぐちゃになり得ます。",[48,11583,11584,11585,11588,11589,11592],{},"一方で、",[120,11586,11587],{},"アニメーション向けのエッジループ","が欲しい場合は、",[120,11590,11591],{},"クワッド・リメッシング","を使えます。クワッド・リメッシングはサーフェスの曲率を分析し、スキニングの下で予測可能に変形するクワッドを生成します。QuadriFlowはモデルの形状に沿って処理します。",[48,11594,11595],{},"もちろん、この2つを組み合わせることもできます。たとえばフェイスリグの場合、ボクセルのクリーンアップの後にクワッドでリメッシュし、その上でガイドを調整して、目と口の周囲にループを強制することができます。",[48,11597,11598],{},[120,11599,11600],{},"自動リトポロジーは、多くの場合「最初の出発点」であって最終納品物ではありません。",[61,11602],{},[64,11604,11606],{"id":11605},"_4-manual-retopology-with-poly-build","4. ポリビルドによる手動リトポロジー",[48,11608,11609],{},[94,11610],{"href":11611},"https://github.com/cgwire/blog/blob/main/drafts/retopology/index.md?ref=blog.cg-wire.com#4-manual-retopology-with-poly-build",[48,11613,11614,11617],{},[120,11615,11616],{},"Poly Buildツールを使った手動リトポロジー","は、変形品質が最重要になるとき、特にクローズアップを担うヒーローキャラクターに対して使うものです。",[48,11619,11620],{},"Blenderでは、Poly Buildツールを使って、高密度メッシュの表面に直接新しいポリゴンを描けます。描画した各頂点はスカルプにスナップされます。",[72,11622,11624,11631],{"className":11623},[34,75,6381],[77,11625],{"src":11626,"className":11627,"alt":12,"loading":82,"width":11628,"height":11629,"srcSet":11630,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-8.png",[81],1078,516,"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-8.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/03/image-8.png 1000w, https://blog.cg-wire.com/content/images/2026/03/image-8.png 1078w",[6389,11632,11633],{},[6392,11634,11635],{},[655,11636,11638],{"className":11637,"style":122},[6397],"出典：Blender Nation",[48,11640,11641],{},"フェイスリグの例で言えば、アーティストはまず唇の周囲にクワッド（4辺のポリゴン）を配置して、エッジループが笑顔のラインに沿うことを確認してから、口周りを作り直すことができます。これにより、リガーはブレンドシェイプ向けに予測可能なループを得られ、極端なフォネム（音素）でジオメトリが潰れるのを避けられます。",[48,11643,11644],{},[120,11645,11646],{},"また、Subdivision Surface ModifierやMultiresolution Modifierのような他のモディファイアを使って、特定の作業を行うこともできます。",[48,11648,11649],{},"このステップでは経験が非常に重要です。多くのアニメーターは、高品質モデルのトポロジーを研究して、その同じ原理を自分のモデルへ適用することで学びます。それは暗黙知なので、実践が鍵です！",[61,11651],{},[64,11653,11655],{"id":11654},"_5-measuring-retopology-performance","5. リトポロジーのパフォーマンスを測る",[48,11657,11658],{},[94,11659],{"href":11660},"https://github.com/cgwire/blog/blob/main/drafts/retopology/index.md?ref=blog.cg-wire.com#5-measuring-retopology-performance",[48,11662,11663,11664,11667],{},"リトポロジーは見た目（美しさ）がすべてのように思えますが、",[120,11665,11666],{},"シーン内のメッシュ数を数えるなどして、数値でリトポロジーのパフォーマンスを測るのは良い習慣です","。そうすれば、どれくらいの作業量が必要か評価でき、進捗も追跡できます。",[48,11669,11670],{},"BlenderではOutlinerを開き、メッシュオブジェクトがいくつあるか確認してください。そのうえで、ビューポートのオーバーレイでStatisticsを有効にすると、頂点数と面数をリアルタイムで見られます。",[72,11672,11674],{"className":11673},[34,75],[77,11675],{"src":11676,"className":11677,"alt":12,"loading":82,"width":11678,"height":11679},"https://blog.cg-wire.com/content/images/2026/03/image-9.png",[81],317,159,[48,11681,11682],{},"キャラクターモデルは軽く見えるかもしれませんが、統計では別々の衣装メッシュにまたがって12万ポリゴン（面）があることが分かる場合があります。さらに、静的アクセサリを結合し、見えない内側の面を削除するだけで、より複雑なリトポロジー作業を始める前に面数を大きく減らせることもあります。",[48,11684,11685],{},"また、LOD戦略に応じて別メッシュの数も考慮することが重要です。",[48,11687,11688],{},"LOD（Level of Detail）とは、同じアセットを異なる解像度の複数バージョンで用意し、エンジンがカメラ距離に応じてそれらを切り替えることを意味します。",[48,11690,11691],{},"メッシュ数の削減やLODの最適化も、実行時のパフォーマンスに関わるためです。そこで、肩や腰などの重要な変形領域をリトポロジーし直し、低いLODでもアニメーション中に正しく曲がるようにします。細部に時間をかけすぎずに済むよう、状況に応じて判断するのが大切です。文脈が重要です。",[61,11693],{},[64,11695,2530],{"id":507},[48,11697,11698],{},[94,11699],{"href":11700},"https://github.com/cgwire/blog/blob/main/drafts/retopology/index.md?ref=blog.cg-wire.com#conclusion",[48,11702,11703],{},"AIが生成した3Dモデルにより、アイデアからメッシュまで一気に進めるスピードは驚くほど速くなりました。しかし、構造のないスピードには代償があります。クリーンなトポロジーこそが、未加工でぐちゃぐちゃなアセットを制作に耐える状態へ変えてくれます。",[48,11705,11706],{},"このガイドでは、リトポロジーとは何か、なぜメンテナンス性、アニメーション、レンダリングのパフォーマンスにとって重要なのか、そしてBlender内で段階的にどうアプローチするかを解説しました。",[48,11708,11709],{},"元のメッシュをバックアップすることがどれほど重要かはお分かりいただけたはずです。そこから、素早い結果を得るためにVoxelやQuadのようなリメッシングツールを使った自動リトポロジーを見ていきました。さらに、精度が最も重要なときに使うモディファイアによる手動リトポロジーも紹介しました。最後に、メッシュ数を分析し、LODとトポロジーのトレードオフを理解することでパフォーマンスを測る方法を確認しました。",[48,11711,11712],{},"リトポロジーは単なるクリーンアップ工程ではありません。そして、Blenderでプロセスを実演しましたが、同じ原理は主要なDCCツールすべてに当てはまります。Blenderで作業していようが、Maya、Houdini、その他の3Dソフトであろうが、基本は変わりません。",[31,11714,11716,11719],{"className":11715},[34,35,36],[31,11717,524],{"className":11718},[40],[31,11720,5958,11722,11725],{"className":11721},[45],[94,11723,10955],{"href":531,"rel":11724},[533],"！私たちはベストプラクティスを共有する1,000人以上の専門家とつながっており、たまに対面イベントも企画しています。ぜひあなたを歓迎したいです！ 😊",[31,11727,11729],{"className":11728},[34,539,540],[94,11730,546],{"href":531,"className":11731},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":11733},[11734,11735,11736,11737,11738,11739,11740,11741],{"id":11395,"depth":548,"text":11396},{"id":11448,"depth":548,"text":11449},{"id":11484,"depth":548,"text":11485},{"id":11521,"depth":548,"text":11522},{"id":11538,"depth":548,"text":11539},{"id":11605,"depth":548,"text":11606},{"id":11654,"depth":548,"text":11655},{"id":507,"depth":548,"text":2530},"https://images.unsplash.com/photo-1590285359328-dce54ee24c1c?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDQwfHxhbmltYXRpb24lMjBtb2RlbHxlbnwwfHx8fDE3NzMwMzgxMDN8MA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":11744,"featured_at":561,"visibility":562},"2026-03-09T07:41:49.000+01:00","/blog-i18n/ja/retopology-animation-blender-guide",{"title":11363,"description":12},"retopology-animation-blender-guide","blog-i18n/ja/retopology-animation-blender-guide/index",[11750],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"VC18gtbPd85SrppqGciKI-JG0AUH8kFAfaZ94ju4Rwo",{"id":11753,"title":11754,"authors":11755,"body":11757,"description":12,"extension":557,"feature_image":12056,"html":7,"meta":12057,"navigation":13,"path":12059,"published_at":12058,"seo":12060,"slug":12061,"stem":12062,"tags":12063,"__hash__":12065,"updated_at":12058,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/scaling-animation-studio-systems/index.md","アニメーションスタジオを5人から50人へ拡張する",[11756],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":11758,"toc":12048},[11759,11770,11773,11776,11781,11784,11786,11790,11795,11798,11805,11813,11820,11827,11829,11833,11838,11841,11848,11851,11858,11866,11873,11881,11883,11887,11892,11895,11900,11903,11912,11915,11918,11924,11930,11932,11936,11941,11944,11949,11952,11958,11968,11974,11976,11980,11985,11988,11994,12008,12010,12012,12017,12023,12026,12029,12042],[31,11760,11762,11766],{"className":11761},[34,35,36],[31,11763,11765],{"className":11764},[40],"📈",[31,11767,11769],{"className":11768},[45],"アニメーションスタジオの拡張は、より多くのアーティストを採用することよりも、適切なシステムを構築することが重要です。",[48,11771,11772],{},"小規模なチームでは、全員が顔を突き合わせて話し、問題は椅子を回してすぐ解決できます。50人規模になると、同じ習慣が騒音や遅延を生み出してしまいます。",[48,11774,11775],{},"システム思考（個人の英雄的な働きに頼るのではなく、反復可能なプロセスを設計すること）は、より大きなスタジオの中でそれを目にしないと学びにくいものです。多くのアーティストがそれに気づくのは、プロジェクトがずれたときです。誰がショットを承認するのか、ファイルがどこに保存されるのか、フィードバックがどう追跡されるのかが定義されていないために起きます。それを新規採用10人分の増加と締切と掛け算すれば、混乱が続きます。",[48,11777,11778],{},[120,11779,11780],{},"課題は、良い仕事が「確実に」できる構造を作ること。解決策は、成長がつらい学びを強制する前に、情報・アセット・意思決定の流れを意図的に設計することです。",[48,11782,11783],{},"この記事では、事前に計画するためのベストプラクティスを定義します。",[61,11785],{},[64,11787,11789],{"id":11788},"_1-layered-team-structure","1. レイヤー化されたチーム構造",[48,11791,11792],{},[94,11793],{"href":11794},"https://github.com/cgwire/blog/blob/main/drafts/scaling-pipeline-from-5-to-50-artists/index.md?ref=blog.cg-wire.com#1-layered-team-structure",[48,11796,11797],{},"スタジオに5人のアーティストしかいないときは、全員があらゆることに触れ、意思決定も同じ部屋で起こります。50人になると、このモデルは混乱しか生みません。",[48,11799,11800,11801,11804],{},"animation、rigging、lighting、compositing のような部門を定義し、クリエイティブと技術面の方向性を担う監督者、そしてその範囲内で実行するアーティストを定めることで、",[120,11802,11803],{},"早い段階でレイヤー化されたチーム構造を整えることが重要","です。監督者とは、最も年次の高いアニメーターであることが重要なのではなく、最終品質と承認に対して責任を負う人です。各部門に明確な監督者と、承認の一本のルートができれば、フィードバックは一つのチャネルを通って流れ、ショットの手戻り時間が短くなります。",[72,11806,11808],{"className":11807},[34,75],[77,11809],{"src":11810,"className":11811,"alt":12,"loading":82,"width":3057,"height":3058,"srcSet":11812,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/03/image.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/03/image.png 1000w, https://blog.cg-wire.com/content/images/2026/03/image.png 1438w",[48,11814,11815,11816,11819],{},"部門は分けるべきです。そうすることで、",[120,11817,11818],{},"部門間の依存関係を減らす","ことができ、他者を待つのではなく並行してチームが作業できるパイプラインを設計できます。依存関係とは、あるタスクの開始を別のタスクが妨げるようなものです。また、リグの標準化、命名規則、公開プロセスを整備することで、アニメーションが土壇場のリグ調整待ちにならないようにできます。",[48,11821,11822,11823,11826],{},"明確なチーム構造は、拡張に伴って制作予算を管理しつつ、消化ペース（毎月どれだけの現金が費出されるか）を追跡して、",[120,11824,11825],{},"採用判断を導く","うえでも役立ちます。制作側が、「中堅アニメーターを2名追加すれば、納期マイルストーンに合わせて消化ペースを維持できる」と理解できれば、採用はもはや賭けではなくなります。",[61,11828],{},[64,11830,11832],{"id":11831},"_2-centralized-asset-management","2. 集約されたアセット管理",[48,11834,11835],{},[94,11836],{"href":11837},"https://github.com/cgwire/blog/blob/main/drafts/scaling-pipeline-from-5-to-50-artists/index.md?ref=blog.cg-wire.com#2-centralized-asset-management",[48,11839,11840],{},"アセット管理は早い段階で集約する必要があります。5人なら部屋の向こうから最新のリグを叫ぶことができますが、50人ではそれができません。",[48,11842,11843,11844,11847],{},"アセット管理の発端は単純です。",[120,11845,11846],{},"誰もが常に最新のアセットで作業しなければならない","という要件です。照明担当が半日かけてショットを磨いたのに、キャラクターのリグが2バージョンも古いと分かるほど、やりきれないことはありません。散らばったフォルダや気軽なファイル共有をやめ、承認済みファイルが置かれる「唯一の情報源」をすぐに用意することが重要です。",[48,11849,11850],{},"スプレッドシートでショットやバージョンを追跡できそうに見えても、3人の監督者が同時に更新した瞬間に崩れますし、誰かが変更を記録し忘れると一気に破綻します。Google Driveは馴染みがあるため魅力的ですが、アセットのバージョン管理が難しく、プレビュー用のレンダリングがストレージの上限をすぐに食ってしまいます。",[48,11852,11853,11854,11857],{},"解決策はシンプルです。",[120,11855,11856],{},"アクセス制御された安全なサーバーに制作アセットをすべて保存","し、ファイルが手作業で回されないようにして、権限により誤った上書きを防ぎます。DCCツールの選定を固定し、共有するファイル形式を揃え、バージョニング戦略を導入しましょう。",[72,11859,11861],{"className":11860},[34,75],[77,11862],{"src":11863,"className":11864,"alt":12,"loading":82,"width":3057,"height":3058,"srcSet":11865,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-1.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-1.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/03/image-1.png 1000w, https://blog.cg-wire.com/content/images/2026/03/image-1.png 1438w",[48,11867,11868,11869,11872],{},"バージョニングとは、変更を追跡でき、ロールバックもできるように、ファイルの増分で明確に番号付けされた反復を保存することです。アーティストに「final_v7_reallyFinal」などとファイル名を勝手に変えさせるのではなく、",[120,11870,11871],{},"DCCパイプラインを通じて自動でバージョン公開を強制","できます。具体例として、リガーがKitsuに新しいキャラクターを公開すると、システムがバージョンをインクリメントします。アニメーターはショットを開くだけで、最新の承認済みリグが自動参照されます。",[72,11874,11876],{"className":11875},[34,75],[77,11877],{"src":11878,"className":11879,"alt":12,"loading":82,"width":3057,"height":3058,"srcSet":11880,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-2.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-2.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/03/image-2.png 1000w, https://blog.cg-wire.com/content/images/2026/03/image-2.png 1438w",[61,11882],{},[64,11884,11886],{"id":11885},"_3-tracking-documentation","3. 追跡 & ドキュメンテーション",[48,11888,11889],{},[94,11890],{"href":11891},"https://github.com/cgwire/blog/blob/main/drafts/scaling-pipeline-from-5-to-50-artists/index.md?ref=blog.cg-wire.com#3-tracking--documentation",[48,11893,11894],{},"大規模なスタジオでは、責任はカジュアルな会話の中にはもう存在しません。",[48,11896,11897],{},[120,11898,11899],{},"制作トラッカー（共有システム）を用意し、タスク、締切、担当者をひと目で分かる場所に割り当てる必要があります。",[48,11901,11902],{},"例えばKitsuでは、コンセプト、アセット、ショット、シーンをすべて追跡可能なタスクとして設定し、担当者を明確に1人割り当てられます。",[72,11904,11906],{"className":11905},[34,75],[77,11907],{"src":11908,"className":11909,"alt":12,"loading":82,"width":3057,"height":11910,"srcSet":11911,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-3.png",[81],833,"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-3.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/03/image-3.png 1000w, https://blog.cg-wire.com/content/images/2026/03/image-3.png 1438w",[48,11913,11914],{},"小規模チームなら、誰がウォークサイクルを仕上げているかを全員が覚えています。より大きなチームでは、2人のアニメーターが「もう片方がやっているはず」と思い込んでしまうことがあります。簡単なトラッカーが、その混乱を防ぎ、責任を明示してくれます。",[48,11916,11917],{},"これに、進捗が「直感」ではなく具体的なチェックポイントに基づいて測定されるよう、マイルストーンを定義しましょう。",[48,11919,11920,11923],{},[120,11921,11922],{},"ドキュメントも、人数に応じてスケールさせなければなりません。"," すべての人が使えるように、ツール、プロセス、慣習を集約する知識ベースが必要です。例えば、Notion や Confluence のようなツールでスタジオWikiを作り、新しいツールや修正を行ったら、タスク完了の一部としてドキュメントを残すことをアーティストに求めます。",[48,11925,9977,11926,11929],{},[120,11927,11928],{},"予測（フォーキャスト）ツールを活用","して遅れを早期に見つけることが重要です。もしレイアウトが各シーケンスで一貫して2日オーバーするなら、クライアントが文句を言う前ではなく、締切がずれる前に、見積もりと人員を調整しましょう。",[61,11931],{},[64,11933,11935],{"id":11934},"_4-structure-review-loops-team-communication","4. レビューのループ設計 & チームコミュニケーション",[48,11937,11938],{},[94,11939],{"href":11940},"https://github.com/cgwire/blog/blob/main/drafts/scaling-pipeline-from-5-to-50-artists/index.md?ref=blog.cg-wire.com#4-structure-review-loops--team-communication",[48,11942,11943],{},"フィードバックのサイクルにも、構造が必要です。",[48,11945,11946],{},[120,11947,11948],{},"レビューのループは、作業を提出し、レビューし、修正し、明確な段階を経て承認されるように設計された、スケジュール化された反復可能なプロセスであるべきです。",[48,11950,11951],{},"書面でのコミュニケーションも重要です。記録が残り、不明確さが解消されるためです。毎週、提出のタイミングを固定し、「何が変わったか」と「どんなフィードバックを求めているか」を短い文章で明記することをアーティストに求めるか、会議の過負荷を減らすために、同じ時間に全員が揃う必要のない非同期コメントを使いましょう。",[48,11953,11954,11957],{},[120,11955,11956],{},"レビューエンジン","（Kitsuのようなもの）を用いると、チャットのスレッド内にフィードバックが迷子になるのを防ぎ、バージョン、ノート、承認を集約できます：",[72,11959,11961],{"className":11960},[34,75],[77,11962],{"src":11963,"className":11964,"alt":12,"loading":82,"width":11965,"height":11966,"srcSet":11967,"sizes":86},"https://blog.cg-wire.com/content/images/2026/03/image-4.png",[81],1122,549,"https://blog.cg-wire.com/content/images/size/w600/2026/03/image-4.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/03/image-4.png 1000w, https://blog.cg-wire.com/content/images/2026/03/image-4.png 1122w",[48,11969,11970,11973],{},[120,11971,11972],{},"それをメッセージングプラットフォームと組み合わせ","て、最終ノートはレビューシステム内に保ちながら素早い確認を行うことができます。多くのチームが気づくのは、監督者がプライベートメッセージで重要なノートを渡すのをやめ、代わりにレビュー用ツールに公開するようにすると、意思疎通が改善し、重複作業が大幅に減るという点です。",[61,11975],{},[64,11977,11979],{"id":11978},"_5-infrastructure-pipeline-management","5. インフラ & パイプライン管理",[48,11981,11982],{},[94,11983],{"href":11984},"https://github.com/cgwire/blog/blob/main/drafts/scaling-pipeline-from-5-to-50-artists/index.md?ref=blog.cg-wire.com#5-infrastructure--pipeline-management",[48,11986,11987],{},"スタジオが成長すると、インフラは「裏方の心配事」では済まなくなります。50人のアーティストでは、同期するために毎日1人あたり15分の摩擦（ファイルの同期待ち、テクスチャの再リンク、壊れたショットの再レンダリングなど）が積み重なり、毎日12時間以上の制作時間の損失になります。",[48,11989,11990,11993],{},[120,11991,11992],{},"専任のパイプラインチームは重要です。"," 問題が発生した都度みんなでパッチを当てるのではなく、標準、バージョニング、オートメーションを所有する1つのパイプラインチームを用意すれば、アーティストはショットに集中し続けられます。テクニカルアーティストは、アニメーションスタジオの複数の重要コンポーネントを担当します：",[212,11995,11996,11999,12002,12005],{},[215,11997,11998],{},"NAS（Network Attached Storage）により、全員が同じ「唯一の情報源」から作業できます。チャットでファイルをコピーする代わりに、アセットは単一の場所へ公開されます。",[215,12000,12001],{},"バックアップと冗長化が災害から守ります。1つの破損したドライブで50人規模のスタジオが止まってしまうべきではありません。自動の夜間バックアップとミラーリングされたサーバーで、パニックを防ぎます。",[215,12003,12004],{},"スケーラブルなレンダーファームが、ライティングがアニメーションをブロックしないようにします。",[215,12006,12007],{},"制作中に数十万フレームを扱う段階では、カスタムのオートメーションがすぐに積み上がって大きな効果になります。",[61,12009],{},[64,12011,508],{"id":507},[48,12013,12014],{},[94,12015],{"href":12016},"https://github.com/cgwire/blog/blob/main/drafts/scaling-pipeline-from-5-to-50-artists/index.md?ref=blog.cg-wire.com#conclusion",[48,12018,12019,12020],{},"アニメーションスタジオを拡張するのは、単にアーティストを増やすことだけではありません。",[120,12021,12022],{},"相互に邪魔をせずに、より多くのアーティストが成功できるシステムを設計する必要があります。",[48,12024,12025],{},"意思決定にはレイヤーが必要です。アセットには構造が必要です。タスクには可視性が必要です。フィードバックにはプロセスが必要です。インフラには責任者が必要です。かつて会話や共有された直感の中にあったものは、ドキュメント化されたシステムと、明確に定義された責任へと進化しなければなりません。これらのシステムは互いを強化し合い、連携してスタジオの成長を支えます。",[48,12027,12028],{},"品質やカルチャーを犠牲にせずスムーズに拡張したいなら、この構造を支えるツールが必要です。そこでKitsuが役立ちます。アニメーションおよびVFXスタジオ向けに特化して作られたKitsuは、追跡を集約し、アセットを管理し、レビューを整理し、部門をまたいだ可視性を1つの場所で維持することを助けます。適切なシステムで、自信を持って拡張しましょう！",[31,12030,12032,12035],{"className":12031},[34,35,36],[31,12033,524],{"className":12034},[40],[31,12036,8155,12038,12041],{"className":12037},[45],[94,12039,961],{"href":531,"rel":12040},[533],"！ 私たちはベストプラクティスを共有する1,000人以上の専門家とつながっており、時々対面イベントも企画しています。ぜひようこそお迎えしたいです！ 😊",[31,12043,12045],{"className":12044},[34,539,540],[94,12046,546],{"href":531,"className":12047},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":12049},[12050,12051,12052,12053,12054,12055],{"id":11788,"depth":548,"text":11789},{"id":11831,"depth":548,"text":11832},{"id":11885,"depth":548,"text":11886},{"id":11934,"depth":548,"text":11935},{"id":11978,"depth":548,"text":11979},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1648014613911-e355dc51e2e3?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDR8fGFuaW1hdGlvbiUyMHN0dWRpbyUyMHRlYW18ZW58MHx8fHwxNzczMDM2OTgyfDA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":12058,"featured_at":561,"visibility":562},"2026-03-09T07:18:45.000+01:00","/blog-i18n/ja/scaling-animation-studio-systems",{"title":11754,"description":12},"scaling-animation-studio-systems","blog-i18n/ja/scaling-animation-studio-systems/index",[12064],{"id":987,"name":988,"slug":989,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":990},"Ki5SKB3t-kWFivD4hSiqYycPkXkgqg4ja5Rh4p-_6BM",{"id":12067,"title":12068,"authors":12069,"body":12071,"description":12,"extension":557,"feature_image":12568,"html":7,"meta":12569,"navigation":13,"path":12571,"published_at":12572,"seo":12573,"slug":12574,"stem":12575,"tags":12576,"__hash__":12579,"updated_at":12570,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/self-hosted-blender-render-farm/index.md","Flamencoを使って2026年に自宅ホスティングのBlenderレンダーファームを構築する",[12070],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":12072,"toc":12558},[12073,12084,12087,12090,12093,12096,12099,12109,12111,12115,12118,12128,12138,12145,12152,12154,12158,12165,12171,12174,12176,12180,12183,12197,12207,12209,12213,12237,12240,12249,12252,12260,12262,12266,12273,12276,12279,12287,12293,12295,12299,12302,12331,12341,12347,12367,12370,12379,12381,12385,12388,12394,12405,12408,12446,12456,12463,12480,12482,12485,12495,12498,12509,12511,12515,12521,12524,12527,12530,12537,12552],[31,12074,12076,12080],{"className":12075},[34,35,36],[31,12077,12079],{"className":12078},[40],"🖥️",[31,12081,12083],{"className":12082},[45],"クラウドに触れることなく、アイドル状態のマシンを強力なBlenderレンダーファームに変えましょう。",[48,12085,12086],{},"レンダリングのせいで期限をほとんど逃しかけたのは、最後にいつでしたか？",[48,12088,12089],{},"Blenderを開くたびに、作業用ワークステーションの音が離陸準備をするジェットエンジンのようになり、何ヶ月分もの制作物がたった1つの進捗バーに人質にされます。",[48,12091,12092],{},"一方で、昔の大学ノートPCは箱の中でホコリをかぶっています。強力ではありませんがGPUはあります。RAMもあります。パニックしながら、まったく何もせずにいるだけの完全に機能するPCです。",[48,12094,12095],{},"「レンダーファーム」という概念は、1人規模のスタジオにとっては少し怖く聞こえるかもしれません。冷房の効いた部屋にサーバーラックが並び、高価なライセンス、そしてIPアドレスについて叫ぶIT担当者…そんな光景を想像するかもしれません。",[48,12097,12098],{},"しかし、現代のBlenderのエコシステムでは、それはもう現実ではありません。",[48,12100,12101,12102,12108],{},"この記事では、",[120,12103,12104,12105],{},"古いデバイスを",[120,12106,12107],{},"Flamenco","で統一されたレンダリングシステムにする方法を説明します。ネットワーク設定の難しさを解きほぐし、数時間で複数のマシンでレンダリングできるようにします。",[61,12110],{},[64,12112,12114],{"id":12113},"why-self-host-a-render-farm","なぜレンダーファームをセルフホストするのか？",[48,12116,12117],{},"イーサネットケーブルを挿す前に、そもそもなぜやるべきなのかを話しましょう。「クラウドのファームに全部送ればいいのでは？」と思うかもしれません。クラウドファームは素晴らしいですが、ローカルのセルフホストレンダーファームは、ワークフローを3つの基本的な点で変えます。",[48,12119,12120,12121,600,12124,12127],{},"クラウドファームにお金を払うとき、あなたは「最終出力」に対して支払っています。",[94,12122,12123],{"href":9227},"心理的にテストレンダリングをしにくくなります",[120,12125,12126],{},"すべてが100%完璧だと確信できるまで「レンダー」を押すのが怖くなる","のです。",[48,12129,12130,12131,600,12134,12137],{},"ファームを自分で所有していると、レンダリングのコストは電気代です。",[94,12132,12133],{"href":2759},"タイミングやライティングを確認するために、解像度50%のラフなアニメーションをレンダリングできます",[120,12135,12136],{},"この自由によって、より速く反復できます。","当てずっぽうをやめて、テストを始められます。",[48,12139,12140,12141,12144],{},"時には、NDAのある技術クライアント向けの商業プロジェクトに取り組んでいて、製品名すら口にしてはいけないほど厳格な場合があります。",[120,12142,12143],{},"それらのアセットを第三者のクラウドサーバー（たとえ安全なものでも）にアップロードすると、厳格なNDA契約に違反する可能性があります。","データをローカルネットワーク（LAN）に保持しておけば、あなたがそう言うまで、スタジオからピクセルが外に出ることはありません。",[48,12146,12147,12148,12151],{},"2GBのプロジェクトファイルをクラウドにアップロードし、レンダリングが終わるのを待ち、フレームをダウンロードして、物理キャッシュを焼き忘れていたと気づく――その苦痛には特有のものがあります。",[120,12149,12150],{},"Flamencoのようなローカルファームなら、ミスを見つけたら「キャンセル」を押して直し、もう一度「レンダー」を押せば済みます。アップロード時間もダウンロード時間もありません。","まるでワークステーションの延長のように感じられます。",[61,12153],{},[64,12155,12157],{"id":12156},"what-is-blender-flamenco","Blender Flamencoとは？",[48,12159,12160,12161,12164],{},"スクラッチからレンダーファームを立ち上げるには ",[94,12162,12163],{"href":9186},"かつては複雑なスクリプトが必要でした","し、または高価なサードパーティソフトウェアが必要でした。ところが今は、Blender Flamencoがあります。",[48,12166,12167,12170],{},[120,12168,12169],{},"FlamencoはBlenderのオープンソースのレンダーファームです。","セットアップはとても簡単です。マネージャーが脳になってやるべきタスクのリスト（レンダリングするフレーム）を保持し、他のコンピュータに何をすべきかを伝えます。ワーカーは追加のノートPCやデスクトップです。ワーカーはマネージャーの指示を聞き、フレームを要求し、レンダリングして保存し、次のフレームをまた要求します。",[48,12172,12173],{},"Flamencoはゼロ設定で動くように設計されています。ほぼ自動でネットワーク上を見つけてくれます。Blenderをインストールできるなら、Flamencoもセットアップできます。",[61,12175],{},[64,12177,12179],{"id":12178},"_1-the-setup","1. セットアップ",[48,12181,12182],{},"このチュートリアルでは、マネージャーとワーカーの両方をデスクトップPCで兼ねる、最もシンプルな構成から始めます。後でノートPCを追加する方法も見ていきます。",[1710,12184,12185,12191],{},[215,12186,12187,12190],{},[120,12188,12189],{},"Blenderをインストール"," - コンピュータにBlenderがインストールされていることを確認してください。",[215,12192,12193,12196],{},[120,12194,12195],{},"Flamencoをダウンロード"," - FlamencoのWebサイトにアクセスし、ご利用のOS用のパッケージをダウンロードします。フォルダに展開してください。",[72,12198,12200],{"className":12199},[34,75],[77,12201],{"src":12202,"className":12203,"alt":12,"loading":82,"width":12204,"height":12205,"srcSet":12206,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-cec7140f-c6aa-4e18-83fb-be86e5a39ac7.png",[81],1064,721,"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-cec7140f-c6aa-4e18-83fb-be86e5a39ac7.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-cec7140f-c6aa-4e18-83fb-be86e5a39ac7.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-cec7140f-c6aa-4e18-83fb-be86e5a39ac7.png 1064w",[61,12208],{},[64,12210,12212],{"id":12211},"_2-run-flamenco-manager","2. Flamenco Managerを起動する",[1710,12214,12215,12218,12224,12227,12230],{},[215,12216,12217],{},"展開したFlamencoフォルダを開きます。",[215,12219,12220,12223],{},[155,12221,12222],{},"flamenco-manager","をダブルクリックします。",[215,12225,12226],{},"いくつかのテキストログとともに、ターミナルウィンドウがポップアップします。",[215,12228,12229],{},"設定ウィザードを進めて、レンダリングするためにblendファイルをアップロードするジョブフォルダを作成します。",[215,12231,12232,12233,12236],{},"少ししてから、Webブラウザが自動的に ",[155,12234,12235],{},"http://localhost:8080"," を開くはずです。これがFlamencoのWebインターフェースです。",[48,12238,12239],{},"フレンドリーなダークテーマのダッシュボードが表示されたら、おめでとうございます。あなたはすでにサーバー管理者の半分を達成しています。Managerが起動しています。",[72,12241,12243],{"className":12242},[34,75],[77,12244],{"src":12245,"className":12246,"alt":12,"loading":82,"width":10304,"height":12247,"srcSet":12248,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-ac803a05-e189-4c17-9fe9-d5749f916aa0.png",[81],821,"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-ac803a05-e189-4c17-9fe9-d5749f916aa0.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-ac803a05-e189-4c17-9fe9-d5749f916aa0.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-ac803a05-e189-4c17-9fe9-d5749f916aa0.png 1319w",[48,12250,12251],{},"マネージャーはアドオンのダウンロードを促します。それを今やってください。ステップ4で必要になります。",[72,12253,12255],{"className":12254},[34,75],[77,12256],{"src":12257,"className":12258,"alt":12,"loading":82,"width":12204,"height":12205,"srcSet":12259,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-ccd6a3fb-4abd-469e-a566-5adfddf76196.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-ccd6a3fb-4abd-469e-a566-5adfddf76196.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-ccd6a3fb-4abd-469e-a566-5adfddf76196.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-ccd6a3fb-4abd-469e-a566-5adfddf76196.png 1064w",[61,12261],{},[64,12263,12265],{"id":12264},"_3-the-worker","3. ワーカー",[48,12267,12268,12269,12272],{},"次に、マネージャーを動かしたままにして、",[155,12270,12271],{},"flamenco-worker","をダブルクリックしてください。",[48,12274,12275],{},"以上です。",[48,12277,12278],{},"ワーカーはローカルネットワークをスキャンし、同じコンピュータ上で動いているManagerを見つけて自己紹介します。デスクトップのWebブラウザ（Managerの画面）を見てみると、「Workers」タブに「Idle」として表示され、出番を待っているはずです。",[72,12280,12282],{"className":12281},[34,75],[77,12283],{"src":12284,"className":12285,"alt":12,"loading":82,"width":10304,"height":12247,"srcSet":12286,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-6bad58f1-615a-4a7b-8aff-38f07279ebe0.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-6bad58f1-615a-4a7b-8aff-38f07279ebe0.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-6bad58f1-615a-4a7b-8aff-38f07279ebe0.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-6bad58f1-615a-4a7b-8aff-38f07279ebe0.png 1319w",[48,12288,12289,12290,12292],{},"デスクトップでも",[155,12291,12271],{},"を動かしてください。メインPCは同時にレンダリングと管理を行えます。",[61,12294],{},[64,12296,12298],{"id":12297},"_4-add-the-blend-file-and-render","4. blendファイルを追加してレンダリングする",[48,12300,12301],{},"準備は整いました。さあ、作業に入りましょう！",[1710,12303,12304,12310,12316,12322],{},[215,12305,12306,12307,600],{},"デスクトップで",[120,12308,12309],{},"Blenderを開く",[215,12311,12312,12315],{},[120,12313,12314],{},"アドオンを有効化"," - 編集 > 設定 > アドオン > ディスクからインストールへ移動します。マネージャーのセットアップ中にダウンロードしたflamencoのzipファイルを検索してください。",[215,12317,12318,12321],{},[120,12319,12320],{},"Managerを紐付ける"," - Flamencoアドオンの設定で、マネージャーのURLをコピー＆ペーストします。",[215,12323,12324,12327,12328,12330],{},[120,12325,12326],{},"ファイルを保存する"," - 設定されたジョブフォルダに",[155,12329,4865],{},"ファイルを保存します。",[72,12332,12334],{"className":12333},[34,75],[77,12335],{"src":12336,"className":12337,"alt":12,"loading":82,"width":12338,"height":12339,"srcSet":12340,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-88504c81-44cf-4d32-a374-0b2dc6746b56.png",[81],724,732,"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-88504c81-44cf-4d32-a374-0b2dc6746b56.png 600w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-88504c81-44cf-4d32-a374-0b2dc6746b56.png 724w",[48,12342,12343,12344,12346],{},"Blenderのレンダー プロパティタブで、下にスクロールして",[120,12345,12107],{},"パネルを表示します。",[1710,12348,12349,12355,12361],{},[215,12350,12351,12354],{},[120,12352,12353],{},"「Fetch Job Types」","をクリック。",[215,12356,12357,12360],{},[120,12358,12359],{},"「Simple Render」","を選択。",[215,12362,12363,12366],{},[120,12364,12365],{},"「Submit to Flamenco」","を押す。",[48,12368,12369],{},"次に、Webブラウザへ切り替えます。ジョブが表示されるはずです。「Workers」リストのステータスバーが緑に変わります。デスクトップは、一度に1フレームずつレンダリング用に取得します。",[72,12371,12373],{"className":12372},[34,75],[77,12374],{"src":12375,"className":12376,"alt":12,"loading":82,"width":10304,"height":12377,"srcSet":12378,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-6e7fa2fb-b997-4f6f-ba60-bcc3c70d5bb0.png",[81],918,"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-6e7fa2fb-b997-4f6f-ba60-bcc3c70d5bb0.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-6e7fa2fb-b997-4f6f-ba60-bcc3c70d5bb0.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-6e7fa2fb-b997-4f6f-ba60-bcc3c70d5bb0.png 1319w",[61,12380],{},[64,12382,12384],{"id":12383},"_5-bringing-in-the-laptop","5. ノートPCを追加する",[48,12386,12387],{},"次に、ホコリをかぶったノートPCをファームに追加します。",[48,12389,12390,12391],{},"ここであなたに伝えたい、最も実行可能なアドバイスが1つあります。それは90%の初心者が失敗するポイントでもあります：",[120,12392,12393],{},"すべてのコンピュータが、同じ場所にあるファイルが見えていなければなりません。",[48,12395,12396,12397,12400,12401,12404],{},"デスクトップでテクスチャが ",[155,12398,12399],{},"C:\\Users\\Dave\\Texture.png"," にあるなら、ノートPCはそのパスに",[655,12402,12403],{},"アクセスできません","。ノートPCにはDaveというユーザーが存在しないうえ、Cドライブにもそのファイルがありません。",[48,12406,12407],{},"必要なのは共有ネットワークフォルダで、通常はNASを使います。OSによって手順は似ていますが、少しだけ違います：",[1710,12409,12410,12413,12420,12433],{},[215,12411,12412],{},"イーサネットケーブルでデスクトップとノートPCを接続",[215,12414,12415,12416,12419],{},"デスクトップ上にNASフォルダを作成し、名前を",[155,12417,12418],{},"RenderFarm","にする。",[215,12421,12422,12423,12426,12427,12426,12430,12432],{},"右クリック > ",[120,12424,12425],{},"プロパティ"," > ",[120,12428,12429],{},"共有",[120,12431,12429],{},"。ユーザーに読み取り/書き込みの権限を付与する。",[215,12434,12435,12438,12439,12442,12443,12445],{},[120,12436,12437],{},"ネットワークドライブを割り当てる：","デスクトップで、このフォルダをドライブレターに割り当てます。たとえば",[155,12440,12441],{},"Z:","。ノートPCでは、デスクトップのネットワーク共有に移動し、これを**同じレター ",[155,12444,12441],{},"** に割り当てます。",[48,12447,12448,12449,12452,12453,12455],{},"これで、Blenderファイルを",[155,12450,12451],{},"Z:\\RenderFarm\\MyProject.blend","として保存すれば、両方のコンピュータが",[155,12454,12451],{},"としてそれを見られます。パスは絶対で、同一です。",[48,12457,12458,12459,12462],{},"デスクトップは起動したままにして、",[120,12460,12461],{},"コンピュータB（ノートPC）","へ移ってください。",[1710,12464,12465,12470,12473,12476],{},[215,12466,12467,12469],{},[155,12468,12441],{},"ドライブ（またはセットアップした共有ストレージ）がアクセス可能か確認します。念のため、その中のファイルを開いてみてください。",[215,12471,12472],{},"ノートPCでFlamencoフォルダをインストールして開きます。",[215,12474,12475],{},"デスクトップと同じBlenderバージョンがインストールされていることを確認します。",[215,12477,12478,12223],{},[155,12479,12271],{},[48,12481,12275],{},[48,12483,12484],{},"ワーカーはローカルネットワークをスキャンし、デスクトップで動いているManagerを見つけます。",[72,12486,12488],{"className":12487},[34,75],[77,12489],{"src":12490,"className":12491,"alt":12,"loading":82,"width":12492,"height":12493,"srcSet":12494,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-90501d50-29c3-4d8f-9b54-511e6c674739.png",[81],1504,932,"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-90501d50-29c3-4d8f-9b54-511e6c674739.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-90501d50-29c3-4d8f-9b54-511e6c674739.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-90501d50-29c3-4d8f-9b54-511e6c674739.png 1504w",[48,12496,12497],{},"Flamencoが、コンピュータ間でジョブを自動的にオーケストレーションします。",[48,12499,12500,12501,12504,12505,12508],{},"NASにアクセスできない、またはNASを購入したくない場合は、Linuxのワークステーションに無料のSambaサーバーをインストールする方法を検討できます。Flamencoは非同期サービスを扱えないため、クラウドストレージは使えません（独自のジョブタイプを作成する場合を除く）。そのやり方については",[94,12502,12503],{"href":6415},"将来の記事","で、Kitsuを非同期の",[94,12506,12507],{"href":7314},"アセットストレージサーバー","として使う方法を見ていきます。",[61,12510],{},[64,12512,12514],{"id":12513},"conclusion-knowing-when-to-scale","まとめ：いつスケールするべきかを知る",[48,12516,12517,12518],{},"ハードウェアのセットアップ、重要な共有ストレージの考え方、そしてソフトウェアのインストールまで解説しました。ここまで実施できたなら、",[120,12519,12520],{},"自宅で機能するレンダーファームが完成し、ホコリをかぶったノートPCは今やチームの生産的なメンバーになっています。",[48,12522,12523],{},"Flamencoは、セルフホストレンダリングへの参入障壁を非常に低くしてくれます。プライバシーを尊重し、電気代以外はコストがかからず、すでに持っているハードウェアの性能を余すところなく引き出せます。",[48,12525,12526],{},"ただし、1人で達成できる範囲には限界があります。",[48,12528,12529],{},"いずれ、デスクトップ＋ノートPCの組み合わせでは足りない期限にぶつかるでしょう。たとえば、24時間で重たいボリューメトリクスのある4Kシーケンスをレンダリングする必要があり、自宅ファームの見積もりでは完了まで3週間かかる、という状況です。これがセルフホスティングの天井です。",[48,12531,12532,12533,12536],{},"この壁に当たったら、さらに5台のコンピュータを買う必要はありません。",[120,12534,12535],{},"CPU/GPUノードを何百台も即座に利用できるサービス、Ranch Computingへ切り替えるタイミングです。","自宅ファームは、テスト、プレビュー、軽めのプロジェクトに最適な素晴らしい日常ドライバーです。一方で、クラウドのレンダーファームは、クライアント向けの高品質な成果物を素早くレンダリングするのに非常に役立ちます。",[31,12538,12540,12543],{"className":12539},[34,35,36],[31,12541,524],{"className":12542},[40],[31,12544,12546,12547,12551],{"className":12545},[45],"アニメーション制作のプロセスについてもっと知りたい方は",[94,12548,12550],{"href":531,"rel":12549},[533],"ぜひDiscordコミュニティに参加することを検討してください","！ベストプラクティスを共有する1,000人以上の専門家とつながれ、時には対面イベントも企画しています。ぜひ歓迎します！ 😊",[31,12553,12555],{"className":12554},[34,539,540],[94,12556,546],{"href":531,"className":12557},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":12559},[12560,12561,12562,12563,12564,12565,12566,12567],{"id":12113,"depth":548,"text":12114},{"id":12156,"depth":548,"text":12157},{"id":12178,"depth":548,"text":12179},{"id":12211,"depth":548,"text":12212},{"id":12264,"depth":548,"text":12265},{"id":12297,"depth":548,"text":12298},{"id":12383,"depth":548,"text":12384},{"id":12513,"depth":548,"text":12514},"https://images.unsplash.com/photo-1683322499436-f4383dd59f5a?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDd8fGRhdGElMjBjZW50ZXJ8ZW58MHx8fHwxNzY3NjE4NDAxfDA&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":12570,"featured_at":561,"visibility":562},"2026-02-20T06:04:52.000+01:00","/blog-i18n/ja/self-hosted-blender-render-farm","2026-01-19T10:00:41.000+01:00",{"title":12068,"description":12},"self-hosted-blender-render-farm","blog-i18n/ja/self-hosted-blender-render-farm/index",[12577,12578],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},{"id":1844,"name":1845,"slug":1846,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":1847},"8mcpjtvbYb0aFNMIG1CN_zWjvqBTKM3gs6SXZZk4xBA",{"id":12581,"title":12582,"authors":12583,"body":12585,"description":12,"extension":557,"feature_image":13081,"html":7,"meta":13082,"navigation":13,"path":13084,"published_at":13085,"seo":13086,"slug":13087,"stem":13088,"tags":13089,"__hash__":13091,"updated_at":13083,"featured_at":561,"visibility":562},"blog/blog-i18n/ja/share-kitsu-playlists/index.md","(2026) PythonでKitsuプレイリストをエクスポートして共有する方法",[12584],{"id":25,"name":6,"slug":10,"profile_image":7,"cover_image":7,"bio":7,"website":7,"location":7,"facebook":7,"twitter":7,"meta_title":7,"meta_description":7,"threads":7,"bluesky":7,"mastodon":7,"tiktok":7,"youtube":7,"instagram":7,"linkedin":7,"url":26},{"type":28,"value":12586,"toc":13073},[12587,12598,12609,12616,12619,12626,12629,12636,12639,12666,12668,12672,12678,12681,12692,12695,12706,12709,12715,12723,12725,12729,12732,12739,12754,12761,12786,12793,12816,12822,12824,12828,12831,12837,12842,12845,12848,12856,12859,12871,12878,12896,12899,12905,12908,12917,12920,12934,12937,12943,12946,12948,12952,12959,12971,12974,12979,12982,12984,12988,12994,13000,13008,13014,13016,13018,13024,13027,13033,13041,13053,13067],[31,12588,12590,12594],{"className":12589},[34,35,36],[31,12591,12593],{"className":12592},[40],"📥",[31,12595,12597],{"className":12596},[45],"クライアントが直接Kitsuにアクセスできない場合でも、Kitsuプレイリストを分かりやすく共有しましょう。",[48,12599,12600,12601,12604,12605,12608],{},"アニメーターとしてキャリアを始めた頃、たいてい最初に直面するのはつらい真実です――時には痛い形で。",[120,12602,12603],{},"素晴らしい仕事をするのは仕事の半分にすぎず、分かりやすく共有することが残りの半分","です。映像そのものはしっかりしていたのに、レビューのプロセスは完全にカオスだったショートフィルムの案件を覚えているかもしれません。メールで行ったり来たりするQuickTimes、",[155,12606,12607],{},"shot_final_v3_really_final.mov","のような名前のファイル、そして「どのメモがどのバージョンに当たるのか」が誰にもはっきり分からない状況。クライアントは混乱し、上長はイライラし、あなたはアニメーションよりもファイル管理に時間を費やしていました。",[48,12610,12611,12612,12615],{},"数年先の話になると、",[120,12613,12614],{},"Kitsuプレイリスト","はスタジオのアニメーションレビューのあり方を根本から変えてくれます。",[48,12617,12618],{},"プレイリストは、構造化、追跡性、そして見せ方をきれいに整えてくれます。ショットをグループ化し、バージョンを追い、フィードバックを一元化できます。多くのチームにとって、それだけで十分大きなメリットです。",[48,12620,12621,12622,12625],{},"ただし制作現場で長年学ぶことがあります。",[94,12623,12624],{"href":8331},"どのスタジオやクライアントも、まったく同じレビュー手順を共有しているわけではない","ということ。資産をオフラインで送る必要があることもあります。クライアントが「シーケンスごとにきちんと梱包されたもの」を求めることもあります。法務やセキュリティ上の制約で、直接Kitsuアクセスを渡せない場合もあります。そういうときでも、単一の共有方法に閉じ込められることなく、Kitsuの強みを活かしたいはずです。",[48,12627,12628],{},"この記事はまさにそのための内容です。",[48,12630,12631,12632,12635],{},"最後には、",[120,12633,12634],{},"Kitsuプレイリストを作成し、Pythonでそのデータを抽出し、関連するすべてのアセットを分かりやすいフォルダ構造にダウンロードし、共有しやすいようにまとめて圧縮する","方法が分かるようになります。このやり方は実制作で何時間も節約でき、アーティストとクライアント双方のレビューをよりスムーズにします。",[48,12637,12638],{},"では、順を追って分解していきましょう。",[31,12640,12642,12645],{"className":12641},[34,35,108],[31,12643,112],{"className":12644},[40],[31,12646,12648,12653,12655,12657,12658,12660,134,12662],{"className":12647},[45],[117,12649,12650],{},[120,12651,12652],{"style":122},"実例を探していますか？",[125,12654],{},[125,12656],{},"本ガイドで紹介しているサンプル連携の完全なソースコードは、こちらのGitHubで確認できます：",[125,12659],{},[125,12661],{},[94,12663,12665],{"href":12664},"https://github.com/cgwire/blog-tutorials/tree/main/share-kitsu-playlist?ref=blog.cg-wire.com","https://github.com/cgwire/blog-tutorials/tree/main/share-kitsu-playlist",[61,12667],{},[64,12669,12671],{"id":12670},"_1-create-a-kitsu-playlist","1. Kitsuプレイリストを作成する",[48,12673,12674,12677],{},[120,12675,12676],{},"しっかりしたレビューのワークフローは、明確な意図から始まります","：あなたは一体、何についてフィードバックが欲しいのでしょうか？ Kitsuプレイリストは、その目的のために作られています。",[48,12679,12680],{},"Kitsuのダッシュボードからプレイリストを作成するのは簡単です。プロジェクトに移動し、Shots または Assets のセクションへ進み、レビューしてほしいアイテムを選び始めます。プレイリストは「レビューの物語（ナラティブ）」だと考えると分かりやすいです。すべてを放り込むのではなく、次のことを自問してみてください：",[212,12682,12683,12686,12689],{},[215,12684,12685],{},"これはブロッキングのレビューですか？",[215,12687,12688],{},"これは仕上げ（ポリッシュ）のパスですか？",[215,12690,12691],{},"アニメーション、ライティング、コンポのどこに焦点を当てていますか？",[48,12693,12694],{},"たとえばショートのシネマティック案件なら、別々のプレイリストを作るかもしれません：",[212,12696,12697,12700,12703],{},[215,12698,12699],{},"\"Animation Blocking – Act 1\"",[215,12701,12702],{},"\"Facial Polish – Key Shots\"",[215,12704,12705],{},"\"Final Lighting Review\"",[48,12707,12708],{},"この小さな整理だけでも、クライアントのレビューが大幅に焦点を持つようになります。",[48,12710,12711,12712],{},"Kitsuでは、ショットを選択したら新しいプレイリストを作成し、分かりやすい名前を付け、物語が伝わるようにショットを並べ替えられます。並び順は、人が思う以上に重要です。",[94,12713,12714],{"href":598},"クライアントが再生ボタンを押したとき、アート、タイミング、そしてリビジョンを1か所で判断できます。",[72,12716,12718],{"className":12717},[34,75],[77,12719],{"src":12720,"className":12721,"alt":12,"loading":82,"width":10304,"height":12247,"srcSet":12722,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-712558f4-4b58-4b1e-8bb1-7bfa2fee1c74.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-712558f4-4b58-4b1e-8bb1-7bfa2fee1c74.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-712558f4-4b58-4b1e-8bb1-7bfa2fee1c74.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-712558f4-4b58-4b1e-8bb1-7bfa2fee1c74.png 1319w",[61,12724],{},[64,12726,12728],{"id":12727},"_2-get-the-playlist-data","2. プレイリストのデータを取得する",[48,12730,12731],{},"準備が整ったら、次はコードを書いていきます。",[48,12733,12734,12735,12738],{},"まずは",[120,12736,12737],{},"Gazu APIクライアントでKitsuに認証","します：",[152,12740,12741,12744],{},[155,12742,176],{"className":12743},[728],[48,12745,12746],{},[155,12747,182,12749,10663,12752,193],{"className":12748},[728],[94,12750,185],{"href":185,"rel":12751},[187],[94,12753,192],{"href":191},[48,12755,12756,12757,12760],{},"続いて",[120,12758,12759],{},"利用可能なプロジェクトをKitsuに問い合わせ","、ターミナルに表示します。ユーザーはプロジェクトを選択し、その選択が以降すべての範囲（スコープ）を決定します。プロジェクトは動的に取得されるため、スクリプトは修正なしでさまざまな制作環境で動作します：",[152,12762,12763,12777],{},[155,12764,12766,12767],{"className":12765},[728],"productions = gazu.project.all_projects()",[48,12768,12769,12770,12773,12774,12776],{},"for i, p in enumerate(productions):\nprint(f\"",[263,12771,12772],{},"{i}"," {p",[263,12775,2456],{},"}\")",[48,12778,12779],{},[155,12780,12782,12783],{"className":12781},[728],"production = productions",[263,12784,12785],{},"int(input(\"Select project: \"))",[48,12787,12788,12789,12792],{},"そこから",[120,12790,12791],{},"選択したプロジェクトからプレイリストを問い合わせ","、同じように表示します。プレイリストが選ばれたら、スクリプトはAPIからプレイリスト全体のオブジェクトを取得します。",[152,12794,12795,12807],{},[155,12796,12798,12799],{"className":12797},[728],"playlists = gazu.playlist.all_playlists_for_project(production)",[48,12800,12801,12802,12804,12805,12776],{},"for i, pl in enumerate(playlists):\nprint(f\"",[263,12803,12772],{}," {pl",[263,12806,2456],{},[48,12808,12809],{},[155,12810,12812,12813,10779],{"className":12811},[728],"playlist = gazu.playlist.get_playlist(playlists",[263,12814,12815],{},"int(input(\"Select playlist: \"))",[48,12817,12818,12821],{},[155,12819,12820],{},"playlist","には、編集（選定）のための参照情報がすべて含まれています。ショット、バージョン、並び順、そしてリンクされたファイルに至るまで、このオブジェクトからアクセスできます。",[61,12823],{},[64,12825,12827],{"id":12826},"_3-download-related-assets","3. 関連アセットをダウンロードする",[48,12829,12830],{},"次のステップは、プレイリストのデータを「ディスク上でレビューできる形」に変換することです。",[48,12832,12833,12836],{},[120,12834,12835],{},"出力は、制作の現実を反映したフォルダ階層","になります。最上位にプレイリスト、その下にシーケンス、さらにその中にショット。実際のメディアは、誰もが見つけられる場所に配置されます。",[152,12838,12839],{},[155,12840,12841],{},"Playlist_Name/\n└── Seq_010/\n├── Shot_010_001/\n│   ├── anim_v003.mov\n│   └── anim_v003.png\n└── Shot_010_002/\n└── Seq_020/\n└── Shot_020_005/\n",[48,12843,12844],{},"この構造こそがポイントです。曖昧さを取り除き、ファイルをただ平らに投げ込むのを避け、上長やクライアントがファイル名ではなく「文脈」でナビゲートできるようになります。",[48,12846,12847],{},"プレイリスト名をルートフォルダとして使うため、エクスポートは常に自己完結しており、再実行もしやすくなります。",[152,12849,12850],{},[155,12851,12853,12854],{"className":12852},[728],"playlist_name = playlist",[263,12855,2350],{},[48,12857,12858],{},"次に、プレイリストの各エントリを順に処理し、ショットの完全なレコードを取得します。プレイリスト自体にはシーケンス情報が含まれていないためです。",[152,12860,12861],{},[155,12862,12864,12865,12868,12869,10779],{"className":12863},[728],"for shot in playlist",[263,12866,12867],{},"\"shots\"",":\nshot_data = gazu.shot.get_shot(shot",[263,12870,2958],{},[48,12872,12873,12874,12877],{},"シーケンス名とショット名を使って、決定論的なディレクトリパスを組み立てます。これにより、ディスク上に ",[155,12875,12876],{},"playlist/sequence/shot"," の一貫したレイアウトが強制されます。",[152,12879,12880,12890],{},[155,12881,12883,12884,12886,12887],{"className":12882},[728],"shot_name = shot_data",[263,12885,2350],{},"\nsequence_name = shot_data",[263,12888,12889],{},"\"sequence_name\"",[48,12891,12892],{},[155,12893,12895],{"className":12894},[728],"shot_dir = os.path.join(\nplaylist_name,\nsequence_name,\nshot_name,\n)\n",[48,12897,12898],{},"ディレクトリが存在しなければ作成します。これで、スクリプトを複数回実行しても失敗したり、途中までのダウンロード結果を上書きしたりしにくくなります。",[152,12900,12901],{},[155,12902,12904],{"className":12903},[728],"os.makedirs(shot_dir, exist_ok=True)\n",[48,12906,12907],{},"続いて、各ショットに対応するプレビューのファイル情報を取得します。通常は画像または動画です：",[152,12909,12910],{},[155,12911,12913,12914,10779],{"className":12912},[728],"preview = gazu.files.get_preview_file(shot",[263,12915,12916],{},"\"preview_file_id\"",[48,12918,12919],{},"出力が、アーティストや上長が期待する見た目と一致するように、元のファイル名と拡張子を保持します。",[152,12921,12922],{},[155,12923,12925,12926,12929,12930,12933],{"className":12924},[728],"preview_filename = f\"{preview",[263,12927,12928],{},"'original_name'","}.{preview",[263,12931,12932],{},"'extension'","}\"\npreview_path = os.path.join(shot_dir, preview_filename)\n",[48,12935,12936],{},"プレビューのメディアはショットフォルダへ直接ダウンロードします。この時点で、プレイリストはディスク上に「きれいで、レビュー可能なディレクトリツリー」として存在しています。",[152,12938,12939],{},[155,12940,12942],{"className":12941},[728],"gazu.files.download_preview_file(preview, preview_path)\n",[48,12944,12945],{},"結果は、説明なしでもzip化・送付・アーカイブ・レビューできる、プレイリストのローカルミラーになります。",[61,12947],{},[64,12949,12951],{"id":12950},"_4-compress-the-folder","4. フォルダを圧縮する",[48,12953,12954,12955,12958],{},"すべてダウンロードできたら、最後のステップは「共有しやすくすること」です。",[120,12956,12957],{},"スクリプトはルートのプレイリストフォルダを自動的に1つのアーカイブに圧縮すべき","です：",[152,12960,12961,12965],{},[155,12962,12964],{"className":12963},[728],"import shutil",[48,12966,12967],{},[155,12968,12970],{"className":12969},[728],"shutil.make_archive(\nbase_name=playlist_name,\nformat=\"zip\",\nroot_dir=os.path.dirname(playlist_name),\nbase_dir=os.path.basename(playlist_name),\n)\n",[48,12972,12973],{},"このアーカイブは引き渡し用の成果物になります。クラウドストレージにアップロードしたり、セキュアなクライアントポータル経由で送ったり、内部でバックアップフォルダとしてアーカイブしたりできます。",[48,12975,12976],{},[120,12977,12978],{},"クライアントは「ファイルが足りない」「構造が壊れている」といった心配をしなくて済みます。1回ダウンロードして1回解凍するだけで、あとはそのまま動きます。",[48,12980,12981],{},"アーカイブファイル名には、プレイリスト名と日付を含めましょう。半年後に「どのバージョンを送ったの？」と聞かれたとき、その判断が役に立ちます。",[61,12983],{},[64,12985,12987],{"id":12986},"onboard-clients-in-kitsu","Kitsuでクライアントをオンボードする",[48,12989,12990,12991],{},"ある時点から、Kitsuプレイリストのエクスポートが邪魔になってきます。素早いスナップショットを送るときや、単発のメモ対応をするときは問題ありませんが、プロジェクトが本格的に反復フェーズに入ると、状況は急速に散らかっていきます。調整のたびに毎回エクスポートし直し、クライアントは古いカットにコメントしてしまい、フィードバックがメール、PDF、チャットスレッドに分散してしまう。",[120,12992,12993],{},"本当にショットを直す代わりに、「そのメモが何を指しているのか」を突き止めるために多くのエネルギーが費やされがちです。",[48,12995,12996,12999],{},[120,12997,12998],{},"そこで、クライアントを直接Kitsuに招き入れるのが合理的になることが多いのです。"," 彼らは常に最新バージョンを見られますし、フレーム上に直接描いたりコメントしたりできます。全員がメモを文脈付きで見られるためです。バージョン履歴も保たれるので、クライアントが「2つ前のバージョンの件なんだけど」と聞いてきたとしても、実際に確認できます。チームとしては、推測する場面が減り、メモを別の場所にコピペする時間も減ります。",[72,13001,13003],{"className":13002},[34,75],[77,13004],{"src":13005,"className":13006,"alt":12,"loading":82,"width":3057,"height":3058,"srcSet":13007,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-1b596b1f-9757-47e5-a893-2c41164a1eab.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-1b596b1f-9757-47e5-a893-2c41164a1eab.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-1b596b1f-9757-47e5-a893-2c41164a1eab.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-1b596b1f-9757-47e5-a893-2c41164a1eab.png 1438w",[48,13009,13010,13011],{},"エクスポートは手早い確認には向いていますが、実制作の規模感には広がりません。",[120,13012,13013],{},"Kitsuにクライアントを入れることで、全員が同じ現実に立脚した状態を保てます。",[61,13015],{},[64,13017,508],{"id":507},[48,13019,13020,13021],{},"アニメーションの現場で何年も過ごすと、繰り返し出てくる教訓があります。それは「レビューのワークフローがスムーズであるほど、クリエイティブな成果も良くなる」ということです。Kitsuは、プレイリスト、バージョニング、そしてフィードバックの一元化によって、強力な土台をすでに提供してくれています。",[120,13022,13023],{},"そのデータを活用し、小さな自動化ツールを組み立てることで、ほぼどんなレビュー状況にも適応できます。",[48,13025,13026],{},"さらに、Kitsuからプレイリストのデータを抽出し、カスタムのレビュー手順に合わせて再構成することも可能です。オフラインパッケージを送る場合でも、外部パートナー向けにアセットを整理する場合でも、あるいはクライアントの手間を少しでも減らしたい場合でも、このアプローチなら主導権をあなたの手に置けます。",[48,13028,13029,13032],{},[94,13030,13031],{},"公開Githubリポジトリをチェック","して、あなたのワークフローに合わせてコードをクローンし、修正してみてください！",[72,13034,13036],{"className":13035},[34,75],[77,13037],{"src":13038,"className":13039,"alt":12,"loading":82,"width":10304,"height":12247,"srcSet":13040,"sizes":86},"https://blog.cg-wire.com/content/images/2026/01/data-src-image-5c610ee3-e726-4198-8b9b-480d3546530c.png",[81],"https://blog.cg-wire.com/content/images/size/w600/2026/01/data-src-image-5c610ee3-e726-4198-8b9b-480d3546530c.png 600w, https://blog.cg-wire.com/content/images/size/w1000/2026/01/data-src-image-5c610ee3-e726-4198-8b9b-480d3546530c.png 1000w, https://blog.cg-wire.com/content/images/2026/01/data-src-image-5c610ee3-e726-4198-8b9b-480d3546530c.png 1319w",[48,13042,13043,13044,13047,13048,13052],{},"そして最後に、ぜひ守りたいアドバイスが1つあります。",[120,13045,13046],{},"可能な限り、クライアントを直接Kitsuにオンボードしてください！"," クライアントが",[94,13049,13051],{"href":13050},"https://www.cg-wire.com/review-engine?ref=blog.cg-wire.com","リアルタイムのレビュー・ルーム","、注釈付きメモ、バージョン履歴を体験すると、多くの人は二度と散らかったメールのやり取りに戻りたがらなくなります。",[31,13054,13056,13059],{"className":13055},[34,35,36],[31,13057,524],{"className":13058},[40],[31,13060,7777,13062,13066],{"className":13061},[45],[94,13063,13065],{"href":531,"rel":13064},[533],"Discordコミュニティに参加することを検討してみてください","！ベストプラクティスを共有する1,000人以上の専門家とつながれて、時には現地イベントも企画します。ぜひ私たちもあなたを歓迎したいです！ 😊",[31,13068,13070],{"className":13069},[34,539,540],[94,13071,546],{"href":531,"className":13072},[544,545],{"title":12,"searchDepth":548,"depth":548,"links":13074},[13075,13076,13077,13078,13079,13080],{"id":12670,"depth":548,"text":12671},{"id":12727,"depth":548,"text":12728},{"id":12826,"depth":548,"text":12827},{"id":12950,"depth":548,"text":12951},{"id":12986,"depth":548,"text":12987},{"id":507,"depth":548,"text":508},"https://images.unsplash.com/photo-1727142073871-d40f5a7c76d8?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fHZpZGVvJTIwZWRpdCUyMHN1aXRlfGVufDB8fHx8MTc2NzYyMDEwNnww&ixlib=rb-4.1.0&q=80&w=2000",{"updated_at":13083,"featured_at":561,"visibility":562},"2026-02-20T06:04:53.000+01:00","/blog-i18n/ja/share-kitsu-playlists","2026-01-26T10:00:19.000+01:00",{"title":12582,"description":12},"share-kitsu-playlists","blog-i18n/ja/share-kitsu-playlists/index",[13090],{"id":570,"name":571,"slug":572,"description":7,"feature_image":7,"visibility":562,"og_image":7,"og_title":7,"og_description":7,"twitter_image":7,"twitter_title":7,"twitter_description":7,"meta_title":7,"meta_description":7,"codeinjection_head":7,"codeinjection_foot":7,"canonical_url":7,"accent_color":7,"url":573},"Smu1ItN09wBosItPscFo8TrxGy5C7USiBQdjpSunfqY",[13093,13101,13109,13117,13125,13133,13141],{"id":13094,"title":1845,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":1846,"meta":13095,"navigation":13,"pageType":13096,"path":13097,"seo":13098,"slug":1846,"stem":13099,"__hash__":13100},"jsonPages/ja/tags/blender.json",{"name":1845},"tags","/ja/tags/blender",{},"ja/tags/blender","s4z5DotSr1p7Mg14_r6HHutTMqzvNFonyD_A2quT8xI",{"id":13102,"title":13103,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13103,"meta":13104,"navigation":13,"pageType":13096,"path":13105,"seo":13106,"slug":13103,"stem":13107,"__hash__":13108},"jsonPages/ja/tags/company.json","会社",{"name":13103},"/ja/tags/company",{},"ja/tags/company","YM2CkWfBFOJet05_Rb6Ucf5-TzUendAmWVqASlGfSKc",{"id":13110,"title":13111,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13111,"meta":13112,"navigation":13,"pageType":13096,"path":13113,"seo":13114,"slug":13111,"stem":13115,"__hash__":13116},"jsonPages/ja/tags/customer-stories.json","お客様事例",{"name":13111},"/ja/tags/customer-stories",{},"ja/tags/customer-stories","uoSx-JR1O8hK5nH3Hk2ElbjvRitYGnTpIYQzQc9eT4Q",{"id":13118,"title":13119,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13119,"meta":13120,"navigation":13,"pageType":13096,"path":13121,"seo":13122,"slug":13119,"stem":13123,"__hash__":13124},"jsonPages/ja/tags/glossary.json","用語集",{"name":13119},"/ja/tags/glossary",{},"ja/tags/glossary","vyZu5vN-1gRjGuTaZNOLMCGduYntrw6VCvpmmA402Pc",{"id":13126,"title":13127,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13127,"meta":13128,"navigation":13,"pageType":13096,"path":13129,"seo":13130,"slug":13127,"stem":13131,"__hash__":13132},"jsonPages/ja/tags/pipeline.json","パイプライン",{"name":13127},"/ja/tags/pipeline",{},"ja/tags/pipeline","jgDgq8M2lQc4oHTpgVOGiCVHPE1MjJwO_3Q5kmuENAQ",{"id":13134,"title":13135,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13135,"meta":13136,"navigation":13,"pageType":13096,"path":13137,"seo":13138,"slug":13135,"stem":13139,"__hash__":13140},"jsonPages/ja/tags/production-management.json","制作管理",{"name":13135},"/ja/tags/production-management",{},"ja/tags/production-management","iiB4szWmr7_hZx-aVOXQy70yVrJIogzwYVRgejcnp_M",{"id":13142,"title":13143,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13143,"meta":13144,"navigation":13,"pageType":13096,"path":13145,"seo":13146,"slug":13143,"stem":13147,"__hash__":13148},"jsonPages/ja/tags/resources.json","リソース",{"name":13143},"/ja/tags/resources",{},"ja/tags/resources","tvx-FMl8FURm9Nc35OyIlHW5PaVLDJOJL6U0LSm5syI",[13150,13153,13156,13159,13162,13165,13168],{"id":13094,"title":1845,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":1846,"meta":13151,"navigation":13,"pageType":13096,"path":13097,"seo":13152,"slug":1846,"stem":13099,"__hash__":13100},{"name":1845},{},{"id":13102,"title":13103,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13103,"meta":13154,"navigation":13,"pageType":13096,"path":13105,"seo":13155,"slug":13103,"stem":13107,"__hash__":13108},{"name":13103},{},{"id":13110,"title":13111,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13111,"meta":13157,"navigation":13,"pageType":13096,"path":13113,"seo":13158,"slug":13111,"stem":13115,"__hash__":13116},{"name":13111},{},{"id":13118,"title":13119,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13119,"meta":13160,"navigation":13,"pageType":13096,"path":13121,"seo":13161,"slug":13119,"stem":13123,"__hash__":13124},{"name":13119},{},{"id":13126,"title":13127,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13127,"meta":13163,"navigation":13,"pageType":13096,"path":13129,"seo":13164,"slug":13127,"stem":13131,"__hash__":13132},{"name":13127},{},{"id":13134,"title":13135,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13135,"meta":13166,"navigation":13,"pageType":13096,"path":13137,"seo":13167,"slug":13135,"stem":13139,"__hash__":13140},{"name":13135},{},{"id":13142,"title":13143,"body":7,"description":7,"extension":8,"lang":9,"localizedSlug":13143,"meta":13169,"navigation":13,"pageType":13096,"path":13145,"seo":13170,"slug":13143,"stem":13147,"__hash__":13148},{"name":13143},{},1776340333312]