シェーダー
シェーダーはGPU(グラフィックスカード)で実行する特別なプログラムである。シェーダーを使うことにより、3Dモデルの「見せ方」(描画)などを自由に変えることができる。ただし、GPUで実行するプログラムは普通のCPUのプログラムと異なり、使い方を学ばないといけない。
GPUとCPUの違い
CPUは「多目的のプロセッサー」で、タスクを切り替えるのは得意な要素である。例えば、Chromeでネットを調べ、見つけたソースコードをVisual Studioに貼り付けたい。プログラムを切り替えるときに、CPUは一旦Chromeを休ませて、Visual Studioを起こして、作業をし続ける。
一方、GPUは「専門的な部品」である。GPUは同時に1つのタスクしかできず、実行中に切り替えることができない。代わりにそのタスクを大変高速に実行ができる。
| CPU | GPU | |
| 目的 | 多目的。同時に様々なプログラムを実行できる(マルチタスク) | 専門的。同時に1つのタスクしかできない(描画のみ)※1 |
| タスク切り替え | 実行中にタスクを切り替えできる | タスクが終わってから切り替えることができる |
| 切り替えるコスト | 低い | 高い |
| 条件分岐(if) | 条件により、実行の流れを切り替えることができる。 | できない※2 |
| 並列化 |
コアが空いていれば、ある程度並列化できる |
非常に強い(千~万単位のコアがある) |
※1:計算専用の「Compute Shader」というものが存在する。計算シェーダーは描画のためではなく、並列化し、速くなる処理に使える。
※2:「if」命令があるが、実行コストが高くて、できるだけ使わないようにしましょう。
GPUとCPUの協力:シェーダーの流れ
OS(Windows)は、ゲームをハードディスクからメモリに転送し、CPUはメモリから1行ずつの命令を読み、実行する。今まで作ってきたスクリプトのすべてはこの流れで実行する。
ただ、ゲームを実行中に「これからGPUのプログラム(シェーダー)が始まる」という特別な命令が現れる可能性がある。この時、CPUは一旦ゲームを休んで、そのプログラムをGPUに転送する。転送し終わったら、ゲームをもう一度起こして、普通の動作に戻る。
TODO:切り替えの流れの画像をついか!
この「一旦止まり→転送→続く」の処理効率が悪いため、GPUのタスク(プログラム)を切り替えるコストが高いといわれる。従って、できるだけゲーム開始の時に必要なシェーダーをGPUに転送し、その後にあまり変わらないようにすれば良いでしょう。
Unityはある程度にシェーダーの転送をしてくれるため、実装しなくても大丈夫だが、ゲームエンジンにより、手動でシェーダーの転送をおこなわないといけない。
シェーダー(プログラム)の他に、必要なデータも転送しなければならない。シェーダーの場合は、主なデータは3Dモデルの頂点や三角形、または位置や変換などである。Unityの「標準シェーダー」の場合はすべてのデータを自動的に転送されるが、「カスタムシェーダー」の場合は、一部のデータを手動で送信する必要な時もある。
TODO:転送画像をついか!
これからUnityのシェーダーについて学び、そして特殊な効果を再現するため、カスタムシェーダーの作り方を学ぼう。
シェーダーとマテリアルの関係性
Unityでは「シェーダー」と「マテリアル」2つの概念がある。シェーダーはGPUで実行するプログラム。マテリアルは「一部のパラメータを設定したシェーダー」のこと。例えば、シェーダーに「Color」というパラメータがあるとしたら、マテリアルでは「Color=Red」にする。
従って、1つのシェーダーからたくさんのマテリアルを作成することができる。例えば、以下の「赤いプラ」「輝く金属」と「草と土」が全く同じシェーダー(Universal Render Pipeline / Lit)を使用しているが、パラメター(色、金属性、滑らか性、など)を変えることによって、様々な表面を作ることが可能。

URP(Universal Rendering Pipeline)のシェーダー
UnityのURPモードは、すぐ使えるたくさんのシェーダーがあるので、最も使うシェーダーについてを細かく見てみましょう。
光と陰の計算あり(Universal Render Pipeline / Lit)

URP で新しいマテリアルを作成すると、このシェーダーになる。いくつかのパラメータがあるので、よく使うのを確認しましょう。
Workflow Mode
反射の計算方法。2つがある:
- 「Metallic」は膨大な素材を再現できる。主には金属を再現するのは得意
- 「Specular」軽くて速い。金属を再現できず、主にプラスチックの雰囲気を再現するモード
Surface Type
透明設定。2つがある:
- 「Opaque」不透明。計算するは速い
- 「Transparent」半透明。後ろのあるものも計算しないといけないので、比較的に遅い
Render Face
見えない三角形(裏側)も描画するかしないか
- 「Front」表のみ
- 「Back」裏のみ
- 「Both」両面
Alpha Clipping
透明度(Alpha)はある数値以下をし下回ると透明になる。この設定は「不透明(Opaque)」でも効く
|
|
|
|
|
透明(Alpha)を持っている画像 |
Alpha Clippingなし |
Alpha Clippingあり |
Base Map
模様と色。画像(テクスチャ)を使わないなら、一定の色になるが、テクスチャを使うと模様を付けることができる。
|
Base Mapなし(色のみ) |
|
|
|
|
なお、テクスチャを正しく貼り付けるため「UV座標」が必要である。「UV座標」については、また後で説明する。
Metallic Map / Specular Map
金属(またはプラスチック)である部分・ではない部分のテクスチャ。全体的に変わりがなければテクスチャは不要であるが、部分的に変えたいなら、このテクスチャを設定:
|
Metallic Map なし |
テクスチャ |
|
Metallic Map あり |
|
Smoothness
表面のなめらかさ。数値が高いほど表面が輝くパラメータ
Normal Map
法線マップのテクスチャ。光の計算を変えるテクスチャであり、細かい凸凹を再現するための特別な画像。
|
|
|
|
|
|
Emission
光る色とテクスチャ(実際に光らないが、光るようにみえる)
|
Emission なし |
Emmision テクスチャ |
|
Emissionあり(色:緑) |
|
光と陰の計算なし(Universal Render Pipeline / Unlit)

陰は計算されない。UIと2Dゲームなどに便利である。
光と陰の計算あり・複雑(Universal Render Pipeline / Complex Lit)

「Lit」(光計算あり)と同じで、さらに「Clear Coat」というパラメータがある。「Clear Coat」は、車のペンキのように、透明な輝くレイヤ(コーティング)を付けることができる。

パーティクル専用(光の計算あり・なし)
|
|
|
パーティクルエフェクト専用のシェーダー。軽くて速いので、たくさんのパーティクルを作成してもあまり重たくならない。光を計算するとしないバージョンがある。
シェーダの種類
シェーダはいくつかの種類がある:
- Fragment Shader(フラグメントシェーダー)三角形のピクセル(フラグメント)ごとに実行するプログラム(シェーダー)である。モデルの陰、色、模様などをこのシェーダで計算する。
- Vertex Shader(バーテックス・頂点シェーダー)三角形の頂点ごとに実行するシェーダーである。頂点の回転、移動、スケールなどを調整できるシェーダー
- Geometry Shader(三角形シェーダー)三角形ごとに実行するシェーダー。LOD(Level Of Detail)やTesselation(三角形再分割)に使ったりする
- Compute Shader(計算用シェーダー)汎用的な計算をするためのシェーダー。並列化ができる処理があったら、GPUに転送し、速く処理できる。
ゲーム開発での使う頻度
- フラグメントシェーダー:よく使う!モデルの変色、模様のアニメーションやエフェクトなどにカスタムシェーダーを作ることが多い
- 頂点シェーダー:まぁまぁ使う。柔らかいものの変形(海の波、風による草の動き)などの時に便利
- 三角形シェーダー:ほとんど使わない。ゲームエンジン(Unity)は自動的に操作する
- 計算用シェーダー:あまり使わないが、何かの特別な計算を並列に実行したいなら使える。
シェーダの開発言語
シェーダーはGPUで実行するプログラムで、GPUを理解できる言語を使わないといけない。主に2つある:GLSL(GL Shader Language)とHLSL(High-Level Shader Language)。GLSLはOpenGL / Vulkan系のライブラリを使うシェーダー言語である。HLSL は Microsoft社が開発した「DirectX」をベースにしたライブラリで使用する言語である。
Unity は HLSLを基づいた「ShaderLab」という言語を使う。HLSLで使える命令はほとんどそのままUnityで使えるようになり、その上に様々な便利な機能がすでに実装されている。例えば、モデルの変換(移動、回転、スケール)や光の計算は実装済みであり、それ以外に機能だけ実装すれば、カスタムシェーダーを作成ができる。
また、よりも楽にシェーダーを作るには、Unityは「Shader Graph」も対応し、ノードをつなげるだけでシェーダーを作成ができる。
GLSL / HLSL / ShaderLabのどれでも、だいたいC言語と似ている。ただし:
- if文を使わないでほしい(一応できるが、計算のコストが高い)
- 使える関数ははGPU専用のものを使用(テクスチャ・画像の読み方が異なる)
- デバッグしにくい:「Debug.Log」がないし、実行中に止めることができない(ブレーキポイントを使えない)
- すべてのプログラムは「フラグメントごと」または「頂点ごと」に実行することを忘れないでほしい。
Unityでシェーダー実行する方法
シェーダーは「フラグメントごと」、または「頂点ごと」に実行するため、当然、シェーダーとモデルを連携しないといけない。Unityでは、マテリアル(Material)経由でモデルとシェーダーのひも付けが行われる。マテリアルを作成したあと、シェーダーを変えることにより、そのマテリアルを使うモデル(メッシュ)をそのシェーダーで処理する。

ShaderLab / HLSL
ShaderLab および HLSL は全く新しい言語であり、学ぶ時間がないので、興味がある学生は個別でお調べください。以下、参考できる URL をご確認ください:
- UnityのShader(ShaderLab/HLSL)入門その1 : Shaderの書き方
- 【Unity入門】シェーダーを書いてみよう!ShaderLabの簡単な書き方!
- 【Unity Shader入門①】ShaderLabとShader Graphの基礎を解説!【初心者向け】
代わりに、もう少し直感的な「Shader Graph」でシェーダーの基礎を学び、フラグメントシェーダーと頂点シェーダを把握できるようになったら、ShaderLab と HLSL 言語についてお調べください。





Base Mapあり








