前章で考えた理屈を元にしてサンプルコードを実際に作ってみました(サンプルはこちらです)。叩き台でして、色々と改良が必要だなぁと感じる部分がありました。その中で苦労したのが「シェーダコードの打ち間違いと食い違い」です。サンプルコードにシェーダチェッカーも入れておいたので、ミスがあった場合にはコンパイラが教えてくれるのですが、それを直す作業は結構な手間でした。シェーダにはお決まりコードが沢山あります。いうのはできればテンプレート化してしまってプログラマが打たずに済む様にするのが理想かなと思います。そこで本章では前章の叩き台コードを改良するために、シェーダコードの部品(フラグメントコード)の生成支援をする方法を考えていきます。テクスチャサンプリング前章でテクスチャからサンプリングするための関数を作る場面がありました。"\n";}これはDiffuseテクスチャがあった場合はそのサンプラを通して値を取得し、そうで無い場合は初期値として白色を返す関数を挿入している部分です。テクスチャが何枚もあった時にこれを毎回書くのは非常に手間ですしエラーも発生しやすくなります。メンテナンス性が低いわけです。この関数は純粋にテクスチャサンプリングのラッパー関数です。他のテクスチャでもほぼ同様の書き方になります。サンプラー名が変わっています。いう事は、少なくともこれらの情報を内部に保持するクラスがあれば、そこから上の文字列を作る事ができるわけです。);}関数置き換え部分のコードは1行になってしまいました。diffuseFunc);}やった、すげー短い!ここまで出来れば打ち間違いは皆無でしょう。グローバル変数コード支援では上からずばーーっとやっていきましょう。グローバル変数支援です。グローバル変数はシェーダコード全体で固定的に使用されます。そのため、何度も変数名を打つべきではありません。セマンティクス(あれば)」、そして前章で取り決めた「初期値」です。valName;}};コンストラクタで型名と変数名と初期値文字列、そしてあればセマンティクスを設定します。宣言部ではdeclメソッドを呼び出す事で宣言用の文字列が出力されます。変数を使用する時にはnメンバメソッドを使って明示的にしても良いですし、代入用演算子を用いてこのクラスをstd::stringとして扱う事もできます。シェーダ変数は例えばvalue.xyzのようにメンバの一部を使用する書き方ができます。value.xyz();と書けるようにしました。GlobalValクラスは汎用性がありますが、実はsamplerやtextureではちょっと扱いがうまくありません。res;}};これで変数の宣言やShaderCreator内での変数の使用が一本化されました。"\n";}右側の使用後は随分とわかりやすくなりました。シェーダ用構造体宣言支援シェーダの入力セマンティクスや出力セマンティクスは構造体にまとめるのが一般的です。ピクセルシェーダ出力セマンティクスの3つです。「ピクセルシェーダの入力セマンティクスは?」と思われるかもしれませんが、これは頂点シェーダの出力セマンティクスと同じです。した方がパフォーマンス向上にも繋がります。TEXCOORD0;\n""};\n\n";}各メンバは型、変数名、セマンティクスからなっています。お、これは�Aで作ったGlobalValクラスで表現できるではないですか(^-^)。それはもちろん活用します。クラスの機能として必要なのは使用するセマンティクスの選択機能と構造体文字列の出力、そしてシェーダ内での変数の使用です。問題なのは使う時です。Out;\n";}というのはどうかなぁと思うわけです。入力セマンティクスの種類は実は限定的で固定的です。よって、メンバ変数として直接アクセスできてもまぁ良いかなと思うわけです。Out;\n";}とすればかなりすっきりします。これ以上可読性を上げる方法は、ん〜ちょっと思いつかないのでこの位にしておきましょう。{}};ちょっとごちゃごちゃとしているのですが、SemanticsStructクラス自体は実は構造体名とコンストラクタしか持っていません。このクラスは派生クラスの土台となるだけです。str;}};コンストラクタで入力セマンティクスで有効となる変数を確定させています。有効な物には名前が付きますが、無効のものには「**/error/**」という無効な文字列が入ります。間違ってシェーダ内で宣言されていないセマンティクスを使った場合、エラー文字列が刻印されてコンパイル時にエラーが検出されます。この辺り、こう記述はしてみたのですが、正直ぱっと見ではわかりませんよね(^-^;。vtxOutput.decl();}打ち間違いがあり得ないほどすっきりしました(^-^)。これで入力支援はおおよそ終了です。実際に使ってみるとまた色々と変更したくなるかもしれません。その時はまた改良方法を検討します。