Claude Media
Claude CodeでUnityシェーダーを書かせる — スクリーンショットで描画を確かめる

Claude CodeでUnityシェーダーを書かせる — スクリーンショットで描画を確かめる

シェーダーはコードが通っても見た目が合うとは限りません。マゼンタとシアンの意味、撮影用スクリプト、基準画像との見比べで、HLSLやShader Graphの調整をClaude Codeに回させる手順です。

Unityのシェーダーは、コードが正しくても見た目が合うとは限りません。法線の向きが逆でも、色の計算が一段ずれていても、コンパイルは通ります。Claude Codeにシェーダーを書かせるときは、テキストの検証に加えて「画面を見て確かめる」ループが要ります。

方法は2段です。ログとマゼンタ表示で「動いているか」を、撮影した画像と基準画像の見比べで「狙った見た目か」を確かめます。Claude Codeは画像のパスを渡せば読めるので、撮影をスクリプト化すれば人が画面を見て報告する手間が減ります。本記事はUnity 6.0(6000.0)のマニュアルに基づきます。

シェーダー作業で何をClaude Codeに確かめさせるか

確かめる対象は3つに分かれます。それぞれ使う手段が違います。

確かめたいこと手段向いている書き手
構文・コンパイルが通るか手段エディタログ、マゼンタ表示向いている書き手HLSL(ShaderLab)
見た目が狙いどおりか手段撮影したPNGと基準画像の比較向いている書き手HLSL・Shader Graph両方
ノード構成が妥当か手段Shader Graphウィンドウのスクリーンショット向いている書き手Shader Graph

C#やビルドの検証をバッチモードで回す手順は、Claude CodeでUnityゲーム開発を進める手順にまとめています。ここではシェーダー固有の部分、特に「画面の確かめ方」を扱います。

コンパイルエラーはログに頼り切れない

C#と同じ感覚で「バッチモードで起動して、ログのエラーをgrepする」だけでは足りません。理由はUnityのシェーダーコンパイルの仕組みにあります。

Unity Editorは、プロジェクトのビルド時にはすべての必要なバリアントをコンパイルします。一方、Editor作業中は全部を先にコンパイルしません。マニュアルによると、シェーダーアセットのインポート時には最小限の処理だけを行い、バリアントの表示が必要になった時点でLibrary/ShaderCacheを調べ、なければコンパイルします。

つまり、起動してすぐ終了する検証では、そのシェーダーのバリアントがまだ一度も表示されていません。ログにエラーが出ないことが、コンパイルが通ったことの証明にならない場合があります。マニュアルは、この動作とログ上のエラー表記の関係までは書いていません。

そのため確認は次の順で組みます。

手順

シェーダー修正後の確認順

  1. 1

    エディタログを読む

    -logFileで書き出したログを読ませ、シェーダー名を含むエラー行がないかを見ます。

  2. 2

    実際にそのシェーダーを表示する

    マテリアルを当てた物体をカメラに映します。表示して初めてバリアントがコンパイルされます。

  3. 3

    画面の色を見る

    マゼンタなら失敗、シアンならコンパイル中です。それ以外の色なら、見た目の比較に進みます。

ログ取得の起動コマンドは、先に紹介した記事の-batchmode -quit -logFileの形がそのまま使えます。-logFileはEditorのログの出力先を指定する引数で、-nographicsを付けたバッチモードでは、出力ログを残すためにこの指定が必要です。

マゼンタとシアンが「失敗」と「待ち」を教えてくれる

Unityは、通常のシェーダーで描画できないとき、特別なシェーダーで物体を描きます。この色の意味を知っているかどうかで、Claude Codeへの指示の精度が変わります。

くらべる

特別なシェーダーの色と意味

エラー

マゼンタ(明るいピンク)

マテリアルが割り当てられていない、シェーダーがコンパイルできない、サポートされていない、といった問題があるときに使われます。エディタでもビルドでも同じです。

コンパイル中

シアン(明るい青)

必要なバリアントをコンパイルしている最中に使われます。非同期シェーダーコンパイルが有効なエディタ、またはShader Live Linkが有効な開発ビルドで見えます。

シアンは失敗ではありません。撮影が早すぎるとシアンの絵を撮ってしまい、Claude Codeが「シェーダーが壊れている」と誤判断する原因になります。撮影の前に待ち時間を入れる理由はここにあります。

URP(Universal Render Pipeline)のプロジェクトでは、ビルトインレンダーパイプライン用のシェーダーを使った物体がマゼンタになることがあります。パイプラインの取り違えは、HLSLを書かせるときに起きやすい失敗です。CLAUDE.mdに使っているパイプラインを書いておけば、Claude Codeが別パイプライン向けの書き方を選ぶのを減らせます。

## Unityシェーダーの規約
 
- レンダーパイプラインは URP。ビルトイン用の書き方(Surface Shaderなど)を使わない
- シェーダーは Assets/Shaders/ に置き、検証用の物体は Assets/Scenes/ShaderTest.unity に置く
- 修正のたびに Shots/current.png を撮影し、Shots/reference.png と見比べて差を説明する
- 画面がマゼンタなら失敗、シアンならコンパイル待ち。シアンのときは撮り直す

撮影を自動化する:ScreenCaptureを使った確認用スクリプト

Claude Codeに渡す画像は、人が画面をキャプチャしても構いません。ただし修正のたびに手で撮ると回転が遅くなります。確認用のシーンにスクリプトを置き、再生すると決まった場所へPNGを書き出す形にすると、Claude Codeは「再生して、Shots/current.pngを読む」だけで済みます。

ScreenCapture.CaptureScreenshotはPNGをファイルに保存します。相対パスはプロジェクトフォルダ(Assetsフォルダを含む場所)を基準に解釈され、既存ファイルは上書きされます。モバイル以外のプラットフォームでの挙動です。

またCaptureScreenshotAsTextureのマニュアルは、描画が終わってから呼ぶように求めています。確実にするにはWaitForEndOfFrameを待つコルーチンから呼びます。CaptureScreenshot側のページには同じ注意書きがありませんが、ここでは同じ書き方にそろえます。

using System.Collections;
using System.IO;
using UnityEngine;
 
public class ShaderShot : MonoBehaviour
{
    [SerializeField] private float waitSeconds = 1f;
 
    private IEnumerator Start()
    {
        // バリアントのコンパイル待ち(シアン表示)を避けるため少し待つ
        yield return new WaitForSeconds(waitSeconds);
        yield return new WaitForEndOfFrame();
 
        string dir = Path.GetFullPath(
            Path.Combine(Application.dataPath, "..", "Shots"));
        Directory.CreateDirectory(dir);
        ScreenCapture.CaptureScreenshot(Path.Combine(dir, "current.png"));
    }
}

このスクリプトを検証用シーンのオブジェクトに付けます。再生するとShots/current.pngができます。Application.dataPathの1つ上がプロジェクトフォルダなので、Shotsはプロジェクト直下に作られます。

Shots/フォルダはGit管理から外しておくと、確認用の画像でコミットが膨らみません。基準画像のreference.pngだけは残す運用が扱いやすいです。

バッチモードで撮れるか

ここまでの手順は、Editorを通常起動して再生する想定です。バッチモード(-batchmode)だけでGame Viewを撮影できるかは、マニュアルに記載がありません。

分かっているのは-nographicsの挙動です。バッチモードに-nographicsを付けると、Unityはグラフィックスデバイスを初期化しません。GPUのない機械で自動処理を回すための引数で、描画結果が必要な撮影とは相性が合いません。撮影を伴う確認では、-nographicsを付けない前提で組むのが安全です。

基準画像と見比べさせる

撮れた画像は、Claude Codeに画像として渡します。公式ドキュメントでは、画像を渡す方法として次の3つが挙げられています。

  • ウィンドウへのドラッグ&ドロップ
  • Ctrl+Vでのペースト(WindowsとWSLはAlt+V)
  • プロンプトに画像のパスを書く

撮影をスクリプト化したなら、3つ目が最も簡単です。複数の画像を同じ会話に入れることもできるので、基準画像と現在の画像を並べて渡せます。

Shots/reference.png が目標の見た目、Shots/current.png が現在の描画です。
2枚を比べて、違いを「色」「ハイライトの位置」「輪郭」の3点で説明し、
その差を縮めるようにAssets/Shaders/Rim.shaderを直してください。

「いい感じにして」では画像を見ても指示になりません。比べる観点を3点ほど挙げ、直すファイルを指定すると、Claude Codeの修正が1回で収まりやすくなります。

画像から得られるのは見た目の手がかりだけです。数値の根拠(なぜ0.3ではなく0.5なのか)は、画像からは読み取れません。そこはシェーダーのプロパティ値を変えながら複数枚撮り、変化を見る進め方に切り替えます。

同じ条件で撮る

見比べは、条件がそろって初めて意味を持ちます。次の3点を固定します。

  • カメラの位置と向き
  • ライト(向き・強さ・色)
  • 物体のモデルと大きさ

どれかが変わると、シェーダーの差ではなく条件の差が絵に出ます。検証用シーンを1つ用意し、シェーダー以外を触らない約束にしておくと、Claude Codeが「差の原因はシェーダー」と判断してよい状態になります。

Shader Graphの場合は何が変わるか

Shader Graphは、コードではなくノードをつないでシェーダーを作る仕組みです。URPまたはHDRPを導入すると自動的に使えるようになります。

Claude Codeに「ノードを追加して」と頼んでも、グラフの画面は触れません。Shader Graphのファイルを直接編集できるかどうかは、Shader Graphのマニュアルに記載がありません。実際に運用するなら、役割を分けるのが現実的です。

  • Shader Graphウィンドウのスクリーンショットを渡して、ノード構成の読み解きと変更案をClaude Codeに出させる
  • 変更案に沿って、人がノードを操作する
  • 結果は、先ほどの撮影スクリプトで確かめる

コードで書けるものはHLSLに寄せたほうが、Claude Codeが自分で直して撮り直す回転が速くなります。ノードの見た目の調整や、アーティストが触る部分はShader Graphに残す、という分担も考えられます。

落とし穴

撮影が早すぎてシアンの絵を渡してしまう

非同期シェーダーコンパイルが有効なEditorでは、バリアントのコンパイル中は物体がシアンで描かれます。再生直後に撮ると、Claude Codeは「描画に失敗している」と読んでしまいます。撮影前に1秒ほど待たせ、それでもシアンなら撮り直す、とCLAUDE.mdに書いておきます。

画面がおかしいときの切り分け

撮影した画像の見え方から原因を絞る順番です。

切り分け

撮影画像から原因を切り分ける

  1. Q物体がマゼンタですか?
    答えがいいえのとき

    マテリアルの未割り当て、コンパイルエラー、パイプライン違いのいずれかです。ログのエラー行と、マテリアルに設定したシェーダーを見ます。

    答えがはい
  2. Q物体がシアンですか?
    答えがいいえのとき

    コンパイル待ちです。待ち時間を延ばして撮り直します。

    答えがはい
  3. Q基準画像と色は合っていますか?
    答えがいいえのとき

    ライトとカメラが基準画像と同じ条件かを先に確かめます。条件が同じなら、色の計算式をClaude Codeに見直させます。

    答えがはい

形状・ハイライトの差を詰める

色が合っているなら、残りは法線やハイライトの計算です。観点を絞って、基準画像との差を説明させます。

まとめ

Claude Codeにシェーダーを書かせるときの肝は、書かせる前に「見て確かめる道具」を用意しておくことです。マゼンタとシアンの意味を知り、撮影を再生ボタン1つにし、条件をそろえた基準画像を置く。この3つがあれば、修正と確認の往復をClaude Code側に任せられます。

Editorの操作そのものを任せたい場合は、Unity公式MCPサーバーをClaude Codeで使う方法が次の選択肢です。ブラウザで描く3Dの確認なら、Three.jsでスクリーンショットから描画を確かめさせる手順が同じ考え方で書かれています。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. code.claude.com/docs/en/common-workflows
  2. docs.unity3d.com/6000.0/Documentation/Manual/shader-compilation.html
  3. docs.unity3d.com/6000.0/Documentation/Manual/shader-error.html
  4. docs.unity3d.com/6000.0/Documentation/ScriptReference/ScreenCapture.Capture…
  5. docs.unity3d.com/6000.0/Documentation/ScriptReference/ScreenCapture.Capture…
  6. docs.unity3d.com/6000.0/Documentation/Manual/EditorCommandLineArguments.html
  7. docs.unity3d.com/Packages/com.unity.shadergraph@17.0/manual/index.html
この記事を共有:XはてブLinkedIn