今回はShader学習枠です。
MRGTのプロジェクトリーダーであり、筆者の尊敬しているエンジニアでもあるCameronさんによるShaderに関する講座がYoutube上で公開されていました。
全編が英語なのと、若干読み解きにくいところもあったため今回から読み解いていきます。
公開されている動画はこちらになります。
〇セッションの内容
セッションは次の8つのセクションで区切られています。
§1Shaderとは何か?
§ 2 Shaderの実行
§3 マテリアルとレンダーモード
§4 MixedReality における注意点
§5 パフォーマンスと最適化ツール
§6 デバッグ
§7 その他のリファレンス
§8 Q&A
昨日は§1を見てShaderの概要を理解しました。
〇§ 2 Shaderの実行
Shaderは§1で述べられていたようにGPU上で実行される小さなプログラムです。
Shaderは通常のCPU上で実行されるプログラム同様に機能しますが、一般的にC言語系のプログラミング言語の構文が使用されます。
これは実行されるGPUのグラフィックスAPIによって変わりますが、一般的にUnityではHLSL、CG(C for Graphics)、GLSLなどが使用されています。
ほかのプログラミング言語同様シェーダーもコンパイルが必要です。
ビルド時にソースコードからアセンブリに変換され、その後ハードウェア(GPU)ごとの独立したバイナリデータへ変換されます。
このバイナリがシェーダーとして実行されています。
〇Shaderの実行を行う
次にシェーダーを実行するためにはシェーダーをGPU上で実行できるようにバインド(紐づけ)する必要があります。
多くのxR開発者の場合UnityもしくはUnrealEngineを使用しているため簡単にバインドを行うことができますが、両社はアプローチが若干異なっています。
UnrealEngineは、シェーダー言語をビジュアルスクリプトで抽象化することです。(ノードベース)
Unity は、CG/HLSL シェーディング言語の薄いラッパーである ShaderLab に注力しています。(コードベース)
セッションではUnityShaderLabに注力して説明されます。
〇UnlitShader
Shaderを作っていきます。
Unityでシェーダーを作る際はプロジェクトウィンドウで右クリックをし[Create]→[Shader]から作成できます。
UnityではStandard Surface ShaderとUnlit Shaderの二つが基礎的なシェーダーになります。
Standard Surface Shaderは選択しているUnityのパイプラインによっては実行できないことがあるので、一般的にUnlit Shaderを用いてカスタマイズし、独自のシェーダーを作ることが多いです。
ShaderLabはUnityで使用される変数などの構文の中にグラフィックスパイプラインで処理される頂点シェーダーやフラグメントシェーダーなどを定義します。
これらは単一のシェーダーファイルにすべてを記載する必要はなく必要に応じて外部ファイルから読み込むこともできます。
〇シェーダー名
最初の一行目はシェーダーの名前になります。
Shader "Unlit/NewUnlitShader" { ...
これはシェーダーごとに一意の名前を付ける必要があります。
〇プロパティ
ここではシェーダーで使用される変数のうち、Unityのマテリアルで表示される変数が表示されます。
Unity C#で例えるとPublic変数を定義するブロックといったところでしょうか?
Properties { _MainTex ("Texture", 2D) = "white" {} }
表記としては_(シェーダー変数名)("(Unityのマテリアルで表示される変数)",(型))=(デフォルトの値)というようになります。
〇サブシェーダー
SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass
シェーダーでは複数のSubShaderを定義できます。
Unityでは自動的に環境に合わせ実行するSubShaderを選ぶことができます。
例えばハイスペックなマシン用の処理とそうではない一般的なマシンの処理を一つのファイルに分けて記載することができます。
〇Tag
TagはUnityで使用される際のシェーダーの属性などを記述します。
Tags { "RenderType"="Opaque" }
デフォルトではレンダータイプとしてOpaque(不透明)が使用されていますが、透明度を持つシェーダーを書きたい場合Transparentなどを選択します。
〇パス
Pass {
パスは実際に処理されるシェーダーを記述します。
パス内にもTagブロックを置くことができ、この場合パスごとに属性を与えることができます。
パスも複数記載することができ、SubShaderは排他的に実行されますが、パスはシェーダーの処理で複数回実行されます。
〇 CGPROGRAM~ENDCG
このコードの中はCG/HLSL文で記載します。
わかりやすい点としてCG/HLSLはC系の言語のため末尾に;が付きます。
今回はShaderLabの構造を読みときました。
実際のコードの手順は次回以降読み解き紹介します。