UnityでShaderの入力パラメータとして行列を渡す

久しぶりにCG系の話題。かなりニッチな需要だとは思うけど、UnityのShader Labのお作法の話。

UnityのShaderで、入力パラメータ(プロパティ)として渡せるデータ型を調べてたら、なんと行列(Matrix4x4)もいけるらしいと分かったのでメモしておく。
Shader Lab関連の公式ドキュメントには行列の入力についてちゃんと載っていなかったんだけど、フォーラムの方にあった。

こちらが公式ドキュメントの入力パラメータ一覧↓

ShaderLab文法:プロパティ

Properties { Property [Property …] }
プロパティのブロックを定義します。波括弧{}の中で次のように複数のプロパティを定義します。

name (“display name”, Range (min, max)) = number
floatプロパティを定義し、インスペクタ上でスライドバーがminからmaxとして表現。

name (“display name”, Color) = (number,number,number,number)
colorプロパティを定義。

name (“display name”, 2D) = “name” { options }
2Dテクスチャプロパティを定義。

name (“display name”, Rect) = “name” { options }
長方形(2のべき乗でない)テクスチャのプロパティを定義。

name (“display name”, Cube) = “name” { options }
キューブマップテクスチャのプロパティを定義。

name (“display name”, Float) = number
floatプロパティを定義

name (“display name”, Vector) = (number,number,number,number)
4コンポーネント ベクトルのプロパティを定義。

ここに列挙されているのはGUIのInspectorからいじれる入力パラメータのみで、実はScript経由だと他の型もパラメータとして入力できるという話。



そして、フォーラムの以下に行列(Matrix4x4)をプロパティとして渡す方法が載っている。

How to set Matrix as a Property?

Script側

...
 
public class ObjectBlur : MonoBehaviour {
    ...
    protected void LateUpdate() {
        Vector4 currentPosition = transform.position;
        currentPosition.w = 1f;
        // Calculate ModelView matrices
        Matrix4x4 _mv = CameraInfo.ViewMatrix*transform.localToWorldMatrix;
        Matrix4x4 _mvPrev = CameraInfo.PrevViewMatrix*m_prevModelMatrix;
        // Give material the matrices it needs
        m_stretchMaterial.SetMatrix("_mv", _mv);
        m_stretchMaterial.SetMatrix("_mvPrev", _mvPrev);
        m_stretchMaterial.SetMatrix("_mvInvTrans", _mv.transpose.inverse);
        m_stretchMaterial.SetMatrix("_mvpPrev", CameraInfo.PrevViewProjMatrix*m_prevModelMatrix);
        // Record our previous transform
        m_prevModelMatrix = transform.localToWorldMatrix;
    }
   
    ...
}

Shader側

Shader "Hidden/Motion Vectors" {
    SubShader {
        Tags { "RenderType"="Moving" }
        Pass {
            Fog { Mode Off }
            CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #pragma fragmentoption ARB_fog_exp2
                #pragma fragmentoption ARB_precision_hint_fastest
                #include "UnityCG.cginc"
               
                ...
               
                uniform float4x4 _mv;
                uniform float4x4 _mvPrev;
                uniform float4x4 _mvInvTrans;
                uniform float4x4 _mvpPrev;
               
                ...
            ENDCG
        }
    }
    ...
}

というように、4×4の行列をパラメータとしてShaderに渡したい場合は、ScriptからMaterialクラスのSetMatrix関数を使って行列を渡せるみたい。

Material.SetMatrix

public void SetMatrix(string propertyName, Matrix4x4 matrix);
public void SetMatrix(int nameID, Matrix4x4 matrix);

関連記事

ZBrushで仮面ライダー3号を造る 仮面編 横顔のシルエットをリファレンスに合わせる

AMIMOTO(PVM版)で作成したインスタンスをAMIMOTO (HVM版)へ移行する

ポリゴンジオメトリ処理ライブラリ『pmp-library (Polygon Mesh Process...

ZBrushで仮面ライダー3号を造る 仮面編

フリーのUV展開ツール Roadkill UV Tool

顔のモデリング

ジュラシック・パークのメイキング

UnityのuGUIチュートリアル

ZBrushでアヴァン・ガメラを作ってみる 脚のトゲの作り直し

ZBrush用トポロジー転送プラグイン『ZWrap Plugin for ZBrush』

OpenCVのfindEssentialMat関数を使ったサンプルを読んでみる

Unityで360度ステレオVR動画を作る

HTML5・WebGLベースのグラフィックスエンジン『Goo Engine』

『ゴジラ キング・オブ・モンスターズ』のVFXブレイクダウン

布地のシワの法則性

映画『ジュラシック・ワールド』のVFXメイキング

Raspberry PiのGPIOを操作するPythonライブラリ『RPi.GPIO』の使い方

Unity Scriptコーディング→Unreal Engine Scriptコーディング

ZBrushでゴジラ2001を作ってみる 身体のバランスを探る

Verilog HDL

映画『ジュラシック・ワールド/炎の王国』のVFXブレイクダウン まとめ

MFnDataとMFnAttribute

天体写真の3D動画

UnrealCV:コンピュータビジョン研究のためのUnreal Engineプラグイン

UnityからROSを利用できる『ROS#』

機械学習に役立つPythonライブラリ一覧

ZBrushでカスタムUIを設定する

ZBrushCoreのTransposeとGizmo 3D

Arduinoで人感センサーを使う

Unreal Engineの薄い本

ZBrushでアヴァン・ガメラを作ってみる 爪とトゲを追加

Stanford Bunny

フルCGのウルトラマン!?

ZBrushでゴジラ2001を作ってみる 姿勢の変更

Google App Engine上のWordPressでAmazonJSを利用する

CGWORLD CHANNEL 第21回ニコ生配信は『シン・ゴジラ』メイキングスペシャル!

Python for Unity:UnityEditorでPythonを使えるパッケージ

UnityプロジェクトをGitHubで管理する

JavaScriptとかWebGLとかCanvasとか

Maya 2015から標準搭載されたMILA

フィクションに登場するUIデザインのまとめサイト

ZBrushの練習 手のモデリング

コメント