シェーダー シェーダーは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に転送する。転送し終わったら、ゲームをもう一度起こして、普通の動作に戻る。 この「一旦止まり→転送→続く」の処理効率が悪いため、GPUのタスク(プログラム)を切り替えるコストが高いといわれる。従って、できるだけゲーム開始の時に必要なシェーダーをGPUに転送し、その後にあまり変わらないようにすれば良いでしょう。  Unityはある程度にシェーダーの転送をしてくれるため、実装しなくても大丈夫だが、ゲームエンジンにより、手動でシェーダーの転送をおこなわないといけない。  シェーダー(プログラム)の他に、必要なデータも転送しなければならない。シェーダーの場合は、主なデータは3Dモデルの頂点や三角形、または位置や変換などである。Unityの「標準シェーダー」の場合はすべてのデータを自動的に転送されるが、「カスタムシェーダー」の場合は、一部のデータを手動で送信する必要な時もある。  これから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なし(色のみ) テクスチャ Base Mapあり なお、テクスチャを正しく貼り付けるため「UV座標」が必要である。「UV座標」については、また後で説明する。 Metallic Map / Specular Map 金属(またはプラスチック)である部分・ではない部分のテクスチャ。全体的に変わりがなければテクスチャは不要であるが、部分的に変えたいなら、このテクスチャを設定: Metallic Map なし テクスチャ Metallic Map あり Smoothness 表面のなめらかさ。数値が高いほど表面が輝くパラメータ Normal Map 法線マップのテクスチャ。光の計算を変えるテクスチャであり、細かい凸凹を再現するための特別な画像。 Normal Map なし 法線マップ 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 言語についてお調べください。