shaderinterface_shade8sdk
shader_interfaceでのstream情報渡し
shader_interfaceを使用すると、表面材質に独自のプロシージャルテクスチャ(3次元テクスチャ)を貼り付けることができます。Shade7.5以前とShade8では、若干仕様が変わっているようです。
Shade7.5以前でのshader_interfaceの使用
ask関数は、「表面材質」のマッピングでの「その他」ボタンが押されたときに呼ばれます。このときダイアログを表示するわけですが、設定した値はask関数の第一引数のstream_interface経由で保存します。
evaluate関数で、get_stream_interface()にてstream_interfaceのポインタを取得して操作しています。これは、Shade7.5までは正常に動作したのですが、Shade8ではこれを行うとShade自身が不安定になります。Shade8は別の方法でask関数で設定した値を取得してくる必要があります。
//情報ダイアログの表示 virtual bool ask (stream_interface *stream, void * = 0) { compointer<dialog_interface> dialog(stream->get_dialog_interface()) ; dialog->append_item(dialog_interface::float_type, "size"); dialog->set_float_property_value(0, 8.0f); float value; try { stream->set_pointer(0); stream->read_float(value); dialog->set_float_property_value(0, value); } catch (...) { } if(dialog->ask()) { dialog->get_float_property_value(0, value); stream->set_pointer(0); stream->write_float(value); return true; } return false; } //スカラー値のパターンの生成を有効にする virtual bool supports_evaluate (void * = 0) { return true; } //スカラー値のパターンの生成 virtual float evaluate (const vec3 &p, void * = 0) { //ストリームより値を取得 // Shade8では以下の処理を行うと不安定になる! float value = 8.0f; try { compointer<stream_interface> stream(get_stream_interface()); if(stream) { stream->set_pointer(0); stream->read_float(value); } } catch(...) { } //位置情報より、その位置での値を返す return noise1(p * value); }
Shade8でのshader_interfaceの使用
「shader_info_base_class」から派生したクラスを定義します。これに、ダイアログのパラメータをweight変数に持たせます。「new_shader_info」関数は、shader_interfaceクラスが自動で呼び出す関数です。第一引数がstream_interfaceになっています。この関数内で、streamの情報を取得します。
戻り値は、shader_info_base_classクラスから派生したspotted_info_classを返しています。
evaluate関数にて、stream_interfaceを呼び出す変わりに
spotted_info_class &info = (spotted_info_class &)(*(get_shader_info()));
にて、spotted_info_classを取得してきます。これは、表面材質のマッピングでの「その他」ボタンで値を変更した場合でも、その情報が反映されています(変数weight内に格納されている)。「info.weight」が「その他」ダイアログで指定した値となりますので、それを計算に使用します。後は、Shade7.5のときと同じです。
// ダイアログから取得したパラメータを保持するクラス(Shade8から追加) struct spotted_info_class : shader_info_base_class { float weight; spotted_info_class (float weight) : weight(weight) { } }; // ダイアログから値を取得するときに呼ばれる virtual shader_info_base_class *new_shader_info (stream_interface *stream, void * = 0) { float weight = 8.0; if (stream) { stream->set_pointer(0); stream->read_float(weight); } return new spotted_info_class(weight); } //スカラー値のパターンの生成を有効にする virtual bool supports_evaluate (void * = 0) { return true; } //スカラー値のパターンの生成 virtual float evaluate (const vec3 &p, void * = 0) { //ストリームより値を取得 float value = 8.0f; // stream_interfaceの値を取得(Shade8から有効) spotted_info_class &info = (spotted_info_class &)(*(get_shader_info())); value = info.weight; //位置情報より、その位置での値を返す return noise1(p * value); }
この部分、古いままにしていますとShade自身が落ちやすくなりますので注意です。
Future's Laboratory 技術格納庫 2004-2013 Yutaka Yoshisaka.