AdskShaderSDK に基づいてシェーダを作成し、マルチレンダー パスを自動的にサポートするシェーダとなるコンポーネントを実装します。コンポーネントは、マテリアルとライトのインタラクションを分解したものです。つまり、拡散マテリアル カラーのコンポーネント、アンビエント コンポーネントなどがあります。
パス コンプライアント シェーダは、独特の 2 つのパーツで構成されています。シェーダ mi 宣言と、mentalmay API と AdskShaderSDK を使用して構築する必要のある C++ 実装です。
シェーダ宣言ファイルは、Maya と mentalray 間のインタフェースを定義します。また、このシェーダをサポートする MentalRay のバージョンも定義します。
フレームワークの階層構造を利用するためには、AdskShaderSDK を使用して記述されたパス コンプライアント シェーダを C++ に実装しておく必要があります。
次にファイルをコンパイルして mentalray API と AdskShaderSDK に対してリンクさせ、Maya で使用可能なダイナミック ライブラリを作成します。
AdskShaderSDK のすべてのリファレンスは、 にあります。
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() を使用する必要があります。
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 は定義済みになっています。つまり各タイプを検索する場合、パラメータとクラスが常に引数に追加されます。