!!!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(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(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自身が落ちやすくなりますので注意です。