はじめに
この記事では、MayaのHLSLシェーダー内でライトの情報を取得する方法を解説します。シェーダーファイルの準備や dx11Shader ノードの基本的な使い方については Mayaで自作シェーダーを使う~HLSL編~ を参照してください。
ライトを手動で取得する
ライト用のセマンティクスを使用して変数を宣言すると、ライトの情報を手動で取得できるUIがAttribute Editorに作成されます。
float3 light_dir: Direction; // 型 変数名: セマンティクス;

プルダウンからライトを選択してバインドすると、その変数にバインドしたライトの情報が格納されます。

主なライト用のセマンティクスは以下のとおりです。
| セマンティクス | 内容 | 型 |
|---|---|---|
| Direction | 方向 | float3/4 |
| Position | 位置 | float3/4 |
| LightIntensity | 強度 | float |
| LightColor | 色 | float3/4 |
その他のセマンティクスについては、Autodesk公式ドキュメント「ビューポート 2.0 の dx11Shader および glslShader プラグインによってサポートされるセマンティックと注釈」の「ライト固有のセマンティック」を参照してください。
アノテーションの設定
セマンティクスの後ろに <> を付けることで、Attribute Editorでの表示名や空間(Object / World / View / Camera)などを設定できます。
float3 light_dir: Direction<
string UIName = "Light Name"; string Space = "World";
>;
その他のアノテーションについては、同ドキュメントの「サポートされるパラメータと均一な注釈」を参照してください。
デフォルト値の設定
後ろに = を付けてデフォルト値を設定することもできます。
float3 light_dir: Direction<> = {0.0f, 1.0f, 0.0f};
ライトを自動で取得する
string Object に設定した文字列に「Light」が含まれている場合、シーン内のライトが自動でバインドされます。
float3 light_dir: Direction< string Object = "Light 0"; >;
同じオブジェクト名を設定することで、単一のライトから複数の情報を取得できます。たとえば、3つのライトの向きと強度を取得したい場合は以下のようにします。
float3 light0_dir: Direction< string Object = "Light 0"; >;
float light0_intensity: LightIntensity< string Object = "Light 0"; >;
float3 light1_dir: Direction< string Object = "Light 1"; >;
float light1_intensity: LightIntensity< string Object = "Light 1"; >;
float3 light2_dir: Direction< string Object = "Light 2"; >;
float light2_intensity: LightIntensity< string Object = "Light 2"; >;
ライトタイプによる制限と対策
ライトの種類ごとにサポートされるセマンティクスが異なる点に注意が必要です。
Direction… ディレクショナルライト、スポットライトをサポートPosition… ポイントライト、スポットライト、エリアライト、ボリュームライトをサポート
ライトの種類を問わず自動でバインドしたい場合は、先に LightType セマンティクスを宣言します。
int light0_type : LightType< string Object = "Light 0";>;
float3 light0_dir: Direction< string Object = "Light 0";> = {0.0f, 1.0f, 0.0f};
float3 light0_pos: Position< string Object = "Light 0";> = {0.0f, 0.0f, 0.0f};
これにより、どのライトタイプでも「Light 0」としてバインドできるようになります。
まとめ
MayaのHLSLシェーダーでは、セマンティクスを使ってライト情報を取得できます。手動バインドはUIから選ぶだけで手軽ですが、string Object アノテーションを使えばシーン内のライトを自動バインドできます。
ライトタイプによるセマンティクスの対応差には LightType を先に宣言することで対処できるので、汎用的なシェーダーを書く際はぜひ活用してください。



コメント