トップ 差分 一覧 ソース 検索 ヘルプ PDF RSS ログイン

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.