ここまでドラゴンの3Dモデルを使っていろいろなシェーダを作ってきました。いい加減ドラゴンも飽きてきたので、今回はテクスチャを使ったシェーダを作ってみましょう。最終的な見た目は次の図のようになります。
シェーダを作る下準備
今回もベースとなるプロジェクトは同じものを使います(自分で作成したプロジェクトでも問題ありません)プロジェクトが作成できたらヒエラルキービューから「Create」→「3D Object」→「Cube」を選択して立方体を追加します。
次に、いま作成した立方体にマテリアルとシェーダを設定します。マテリアルとシェーダの作成方法と設定方法は下の記事で紹介していますので参照して下さい。
これで自前のシェーダをアタッチした立方体のオブジェクトが作成できました。次は立方体の表面にテクスチャを表示するため、シェーダの内容を変更しましょう。
テクスチャを表示するシェーダを作る
テクスチャを表示するシェーダは次のとおりです。先ほど作成したシェーダファイルに次のプログラムを入力して下さい。
Properties{ _MainTex("Texture", 2D) = "white"{} } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Standard fullforwardshadows #pragma target 3.0 struct Input { float2 uv_MainTex; }; sampler2D _MainTex; void surf (Input IN, inout SurfaceOutputStandard o) { o.Albedo = tex2D(_MainTex, IN.uv_MainTex); } ENDCG } FallBack "Diffuse" }
テクスチャを使用するため、テクスチャ格納用の変数(sampler2D型の_MainTex変数)を宣言しています。この変数には後ほどインスペクタから値を代入します。
サーフェイスシェーダでは1ピクセルごとにsurfメソッドが実行されます(次図参照)。そのため、サーフェイスシェーダは現在処理しているテクスチャの位置(uv座標)を知らなければいけません。
テクスチャのuv座標をサーフェイスシェーダに教えるためには、入力の構造体(Input)に、uv[テクスチャ変数名]という名前のメンバ変数を宣言しておきます。これにより、サーフェイスシェーダには処理すべきテクスチャのuv座標が自動的に渡されます。
surfメソッドの中でtex2Dメソッドを使って、_MainTexからuv_MainTexで指定された座標の色を取得して、それを出力する色としてAlbedoに指定しています。
最後に、インスペクタからテクスチャを設定できるようにPropertiesブロックにテクスチャファイルを宣言しています。「シェーダのパラメータをインスペクタから設定する」の記事でも書いたように、Propertiesブロックの書き方は「公開する変数名」「インスペクタ上の表示」「型名」「初期値」の順番です。
ここでは、公開する変数名が_MainTex、インスペクタ上の表示がTexture、型名が2D、初期値が"white"になります。
シェーダにテクスチャをセットする
いま作成したシェーダにテクスチャをセットします。ヒエラルキービューで立方体を選択し、インスペクタからマテリアルのTextureにテクスチャにしたい画像ファイルをドラッグ&ドロップします。
ここまでで、ようやくテクスチャが表示されました。standard shaderを使えば、インスペクタにドラッグ&ドロップするだけでテクスチャが表示されるのに、なんでこんな面倒なことを・・・と思うかもしれません。確かにここまでの過程は面倒ですが、今回作成したプログラムを少し変更するだけで、standard shaderでは実現できないような表現が可能になります。これは、また別の記事で紹介しますのでお楽しみに!