2012年8月24日金曜日

Unityシェーダについて考える ~その1


最近Unityアジアブートキャンプの内容が公開された。

[Unity3D]Unityアジアブートキャンプの内容の一部を一般公開 - テラシュールウェア
http://terasur.blog.fc2.com/blog-entry-239.html

テーマのひとつで「ShaderLab入門」紹介があったのだが、UnityではAras Pranckevičiusさんという方がでこのエリアをご担当されており、そのブログの内容からUnityがシェーダに対して目指していることが分かるのでちょっと紹介をしたい。



http://aras-p.info/blog/page/4/
2010-07-16

「シェーダ死すべし」という自分の発見から1年が経った。

どうしたことかUnity3になって、いよいよこの発見が実現に至ることになった。新機能をSurface Shaderという名前にした理由は「シェーダ死すべし」としたかったものの、それではイカンだろうと判断してグッとこらえたからである(笑)

実現したいこと
主に実現したいこととしてはサーフェイスのプロパティ宣言に時間の90%をかけてあとは余計なことをしたくないということだ。言い換えると:

「おーい、Albedoにこのテキスチャを適用して、ノーマルはこのノーマルマップを使うぞ。あとBlinn-Phongのライティングモデルを使うからな。それ以上は面倒だからいちいち聞いてくれるなよ!」

もっと言うと、フォワードレンダリングやデファードレンダリングであるか、ライトタイプの処理や、どれだけの数のライトをフォワードレンダラーで処理して、間接照明のSHプローブの処理をどうするかとか、まったく興味がないよ!ってことだ。汚れ仕事はレンダリングプログラマーの仕事なんだから、なんとかしろや!と。

具体例
簡単な事例だけど、完全に使えるUnity3.0シェーダで、拡散ライティングでテキスチャ、ノーマルマップつかったものを紹介する:

良いモデルとテキスチャの組み合わせで結構生かす画像ができているだろ!どんなもんだい。(注:画像は冒頭の画像)
Shader "Example/Diffuse Bump" {
  Properties {
    _MainTex ("Texture", 2D) = "white" {}
    _BumpMap ("Bumpmap", 2D) = "bump" {}
  }
  SubShader {
    Tags { "RenderType" = "Opaque" }
    CGPROGRAM
    #pragma surface surf Lambert
    struct Input {
      float2 uv_MainTex;
      float2 uv_BumpMap;
    };
    sampler2D _MainTex;
    sampler2D _BumpMap;
    void surf (Input IN, inout SurfaceOutput o) {
      o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
      o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
    }
    ENDCG
  } 
  Fallback "Diffuse"
}

コードのなかで面白味に欠けるところはグレーにしてみた(※本ブログではグレーにできなかったが、CGPROGRAM~ENDCG以外はグレー)。(宣言として、シリアライズしたシェーダのプロパティやUI名、古い機械向けに使用するシェーダ(Fallback)、等)そうすると残るのはCg/HLSLコードで、これは自動生成で大量のコード(ライティングや、その他諸々)に変換してくれる。

上記のシェーダはいくつかのパーツに分解できる:

  • surfをメイン関数としたsurface shaderで、Lambertライティングモデルを使用する。Lambertはデフォルト選択できるモデルのひとつだが、自分で書くことも出来る。
  • surface shaderからデータの入力を行う。これもデフォルト選択できる入力から選ぶことも出来て、頂点ごとに計算されピクセルごとにsurface関数に渡される。この例ではふたつのテキスチャ位置を設定する。
  • 実際のsurface shaderコードにあたる。入力値をとり、SurfaceOutput(デフォルトで存在する構造体)に書き込むことができる、ただしそのライティングモデルにその構造体に対応していることが前提となる。実際のコードはAlbedoおよびNormalを出力に指定するのみである。

-----

うーん。まったく別世界の話なので分かっていないところが多く誤訳などあったらご勘弁を。

次回はいかにUnityがコードを自動生成してくれているか紹介する。やはりコードは自身で書く部分は少ないにこしたことはないと感じる。

世界でも数少ないシェーダを使いこなすプログラマになろう!

0 件のコメント:

コメントを投稿

ブックマークに追加

このエントリーをはてなブックマークに追加

自己紹介

自分の写真
Unity3D公式マニュアル翻訳やってる人がスマホ(iPhone, Android)のゲーム開発しています。気軽に面白く初心者が遊べる内容がモットー。Blogでは開発情報をひたすら、Twitterではゲーム作成の過程で参考にしている情報を中心につぶやきます

ページビューの合計

過去7日間の人気投稿

ブログ アーカイブ