Unityを使ってシェーダーを作る方法を学ぶ連載。今回はオブジェクトをスライス(輪切り)したような見栄えになるシェーダーを紹介する。
Unityを使ってシェーダーを作る方法を学ぶ連載「Unityで始めるシェーダー入門」。連載第1回ではシェーダーの概要と作り始めるまでの環境構築を紹介した。
今回はオブジェクトをスライス(輪切り)したような見栄えになるシェーダーを紹介する。Sphere(球体)と3Dキャラクターがスライスされた画像が図1だ。今回は、このような表示になるシェーダーを紹介する。
Hierarchyの「Create」→「3D Object」→「Sphere」と選択してSphereをScene画面上に配置する。同じく、これまでの連載でインポートしておいた、「Ethan」の3DキャラクターをScene画面上に1体配置しておこう。カメラの位置やSphereや3Dキャラクターの位置を調整して図2のような表示にしておく。
新しいScene画面を開き、「Shaders」フォルダを選択して、マウスの右クリックで表示されるメニューから「Create」→「Shader」→「Standard Surface Shader」と選択する。新しく作成されたShaderには「SliceShader」と名前を付けておこう。
次に、「Materials」フォルダを選択して、マウスの右クリックで表示されるメニューから「Create」→「Material」と選択する。新しく作成されたMaterialには「SliceMaterial」と名前を付けておこう。
先ほど作成した、Materialsフォルダにある、SliceMaterialを選択して、Inspectorを表示させてみよう。Shaderの位置に先ほど作成したSliceShaderが「Custom/SliceShader」として関連付けられている。通常は、Standard Surface Shaderとして作成したシェーダーは「Custom」というグループ名付きで表示される。
SliceShaderの中身は、これまでの連載通り、Standard Surface Shaderのコードが記述されている。このコードをリスト1のように変更する。
Shader "Custom/SliceShader" { Properties { _Color("Color",Color) = (1.0,1.0,1.0,1.0) } SubShader { Tags {"RenderType"="Opaque"} Cull off CGPROGRAM #pragma surface surf Lambert struct Input { float3 worldPos; }; float4 _Color; void surf (Input IN, inout SurfaceOutput o) { o.Albedo = _Color; clip(frac(IN.worldPos.y * 15) - 0.5); } ENDCG } FallBack "Diffuse" }
コードの解説については、今までの連載で解説したコードについては省略しているので、ご了承願いたい。
ここで使用しているサーフェースシェーダーのInput構造体には、下記のURLで使用されている値(「worldPos」「worldRefl」など)を使用している。
12〜14行目のInput構造体の中で、float3型のworldPos変数を定義している。これによって、オブジェクトの位置であるワールド座標の位置が取得できる。
18〜21行目のsurf関数では、リスト2のように記述している。
void surf (Input IN, inout SurfaceOutput o) { o.Albedo = _Color; clip(frac(IN.worldPos.y * 15) - 0.5); }
リスト1の20行目では、「IN.worldPos.y*15」でワールド座標に15を乗算し、frac関数では引数に指定された値の小数部(10進数値)を取得する。つまり、0以上1未満の値を返す。それから0.5をマイナスすることで、「-0.5」から「0.5」を繰り返すことになる。clip関数では、与えられた引数が「0」より小さい場合は描画を行わない。「0」以上で描画を行う。これを利用してマスク処理を行うことで、縦に輪切りされたような模様が作成される。
「IN.worldPos.y*15」の「15」の値を変更することで、縞模様の幅を変更できる。値を小さくすれば縞模様の幅が大きくなる。
MaterialsフォルダにあるSliceMaterialを選択してInspectorを表示させると、図3のように表示される。Colorに青色を選択するだけだ。スライスはシェーダーの中で自動的に行われる。
図3のColorの指定によってSliceMaterialは図4のような表示になる。
この図4のマテリアルをScene画面上に配置した、Sphereと3Dキャラクターの上にドラッグ&ドロップする。すると、図5のように輪切りにされたような縞模様で表示される。
今回はこれで終わりだ。今回のコードは今までの連載でやってきたコードが出てきているので、surf関数以外は十分に理解できたのではないかと思う。今回の肝は、このsurf関数内の処理になる。
「clip関数では、与えられた引数が0より小さい場合は、描画を行わない」と解説をしておいたが、0.5をマイナスしなかった場合はどうなるかというと、輪切りにはならず、縞模様は表示されない。要するに、スライス表示は行われずに描画が完全に行われてしまうわけだ。オブジェクトが青色のままで完全に表示される。
では「-0.9」を指定すればどうなるかを試すと、縞模様は表示されるがごくわずかに表示されるだけだ(図6)。オブジェクトもほとんど消えかけて表示される。「1」を指定してしまうと、透明人間になって、3Dキャラクターのサングラスだけが表示される。「-0.1」を指定すると、縞模様の間隔が極端に狭く表示される。
よって「-0.5」と指定するのがちょうどいい表示になるわけだ。どのような処理になるか分からない場合は、そこに指定されている値をいろいろ変化させて試してみると、理解ができるようになる。各自がいろいろ試してみてほしい。
次回は、鏡面反射(オブジェクトのガラス化)について解説するので、お楽しみに。
薬師寺 国安(やくしじ くにやす) / 薬師寺国安事務所
薬師寺国安事務所代表。Visual Basicプログラミングと、マイクロソフト系の技術をテーマとした、書籍や記事の執筆を行う。
1950年生まれ。事務系のサラリーマンだった40歳から趣味でプログラミングを始め、1996年より独学でActiveXに取り組む。
1997年に薬師寺聖とコラボレーション・ユニット「PROJECT KySS」を結成。
2003年よりフリーになり、PROJECT KySSの活動に本格的に参加。.NETやRIAに関する書籍や記事を多数執筆する傍ら、受託案件のプログラミングも手掛ける。
Windows Phoneアプリ開発を経て、現在はWindowsストアアプリを多数公開中。
Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。
Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。
Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。
Microsoft MVP for Development Platforms-Windows Platform Development(Oct 2014-Sep 2015)。
Copyright © ITmedia, Inc. All Rights Reserved.