AdskShaderSDK に基づいてシェーダを作成し、マルチレンダー パスを自動的にサポートするシェーダとなるコンポーネントを実装します。コンポーネントは、マテリアルとライトのインタラクションを分解したものです。つまり、拡散マテリアル カラーのコンポーネント、アンビエント コンポーネントなどがあります。
パス コンプライアント シェーダは、独特の 2 つのパーツで構成されています。シェーダ mi 宣言と、mentalmay API と AdskShaderSDK を使用して構築する必要のある C++ 実装です。
シェーダ宣言ファイルは、Maya と mentalray 間のインタフェースを定義します。また、このシェーダをサポートする mentalray のバージョンも定義します。
フレームワークの階層構造を利用するためには、AdskShaderSDK を使用して記述されたパス コンプライアント シェーダを C++ に実装しておく必要があります。
次にファイルをコンパイルして mentalray API と AdskShaderSDK に対してリンクさせ、Maya で使用可能なダイナミック ライブラリを作成します。
AdskShaderSDK のすべてのリファレンスも参照してください。
サンプルの MayaPhong.mi は、次のとおりです。
declare shader # Return struct struct { color "outColor", color "outGlowColor", color "outMatteOpacity", color "outTransparency", # BRDF components color "outAmbient", color "outIncandescence", color "outIrradiance", color "outDiffuseShadowed", color "outDiffuseNoShadow", color "outShadow", color "outSpecularShadowed", color "outSpecularNoShadow", color "outReflection", color "outRefraction", color "outScatter", color "outOpacity" } "MayaPhong" ( # Render Pass Parameters array string "FrameBufferNames", array integer "FrameBufferTypeCounts", boolean "UsingPerLightContribution", string "LightFrameBufferMapping", # Inherited from Base Material color "color", color "transparency", # Inherited from Matte Material integer "matteOpacityMode", scalar "matteOpacity", # Inherited from Glow Material scalar "glowIntensity", # Inherited from Lambertian Material integer "refractionLimit", scalar "refractiveIndex", boolean "refractions", scalar "diffuse", color "ambientColor", color "incandescence", scalar "translucence", scalar "translucenceFocus", scalar "translucenceDepth", scalar "opacityGain", Boolean "hideSource", scalar "surfaceThickness", scalar "shadowAttenuation", scalar "transparencyDepth", scalar "lightAbsorbance", boolean "chromaticAberration", vector "normalCamera", color "irradiance", color "irradianceColor", scalar "refractionBlur", integer "refractionBlurLimit", integer "refractionRays", color "scatterColor", scalar "scatterRadius", integer "scatterAccuracy", integer "scatterFalloff", integer "scatterLimit", integer "scatterCache", # Inherited from Reflective Material integer "reflectionLimit", color "specularColor", color "reflectedColor", scalar "reflectivity", scalar "reflectionSpecularity", scalar "reflectionBlur", scalar "reflectionBlurLimit", integer "reflectionRays", # Phong parameters scalar "cosinePower" ) version 1 apply material end declare
上に示すとおり、シェーダ宣言は、返し構造とレンダー パス パラメータの 2 つのセクションで構成されます。
例では、返し構造に Maya の旧式レンダー パスのコンポーネントを含んでいます。レンダー パス(マルチ レンダー パス)は、AdskShaderSDK の名前の付いたフレーム バッファに自動的に書き込まれます。
シェーダ宣言ファイルの記述方法の詳細については、mental ray シェーダ言語拡張とシェーダの宣言ファイルを記述するを参照してください。
C++ ファイルのこのセクションでは、シェーダで使用されるパラメータを提示する必要があります。このパラメータ リストの順番は、シェーダ宣言ファイルで定義された順番に一致していなければなりません。
そのためには、MayaPhongParameters 構造体にADSK_REFLECTIVE_MATERIAL_PARAMETERS マクロを使用して、最初に提示する反射シェーダの既定のパラメータを定義します。その後 MayaPhong の実装に必要なカスタム パラメータが続きます。例では、miScalar cosPower がサンプル シェーダの Phong スペキュラ指数を表しています。その他の関連パラメータのマクロについては、adskShader.h を参照してください。
struct MayaPhongParameters { ADSK_REFLECTIVE_MATERIAL_PARAMETERS miScalar cosPower; };
AdskShaderSDK の既定のコンポーネントは、adskComponent.h で定義されています。この例の場合、既定では鏡面反射性がないためスペキュラ コンポーネントをオーバーライドします。オーバーライドとして記述するコンポーネントは、既定の宣言と正確に一致している必要があります。
template <typename ParameterType> class MayaPhongSpecularComponent { public: MayaPhongSpecularComponent(miState *state, ParameterType *paras); ~MayaPhongSpecularComponent() {}; miColor operator()(miState *state, ParameterType *paras, miColor &pLightColor, miVector &pLightDirection, miVector &pReflectionDirection); };
各サンプルには、operator ()メンバー関数が要求されます。この関数内に、任意の mental ray 関数と AdskShaderSDK 関数が呼び出されます。ダイナミックに割り当てられたメモリが必要な場合は、必ず mental ray API コールの mi_mem_allocate()と mi_mem_release() を使用する必要があります。
次に、基本の Phong 鏡面反射性の実装例を示します。
template<typename ParameterType> miColor MayaPhongSpecularComponent<ParameterType>::operator()(miState *state, ParameterType *paras, miColor &pLightColor, miVector &pLightDirection, miVector &pReflectionDirection){ // get the relevent parameters miScalar specularExponent = *mi_eval_scalar(¶s->cosPower); miScalar reflectionSpecularity = *mi_eval_scalar(¶s->reflectionSpec); miColor materialSpecularColor = *mi_eval_color(¶s->specularColor); miScalar phongSpecular = compute_phong_specular(&pLightDirection, specularExponent, reflectionSpecularity, &pReflectionDirection, state); if (phongSpecular > 0.0){ return phongSpecular * materialSpecularColor * pLightColor; } else{ return BLACK; } }
新規のシェーダ クラスは、マテリアル クラスのテンプレート インスタンスであるため、テンプレートのパラメータを指定する必要があります。
typedef Material< MayaPhongParameters, DefaultAmbientMaterialColorComponent<MayaPhongParameters>, DefaultAmbientComponent<MayaPhongParameters>, DefaultDiffuseMaterialColorComponent<MayaPhongParameters>, DefaultDiffuseComponent<MayaPhongParameters>, MayaPhongSpecularComponent<MayaPhongParameters> > MayaPhongClass;
最後に、新規シェーダを Maya に提示するため、以下のマクロをコールします。
EXPOSE_CUSTOM_MATERIAL(MayaPhong)
マクロ パラメータには、MayaPhongParameters のような名前が付けられ、MayaPhongClass は定義済みになっています。つまり各タイプを検索する場合、パラメータとクラスが常に引数に追加されます。
ShaderSDK のサンプルについては、Maya インストールディレクトリの mental ray の ../devkit/adskShaderSDK/Samples/MayaPhong フォルダを参照してください。