VR 研究記

3D技術の経験を活かして、VRに挑戦するおっさんの奮闘記

【Shaderプログラミング】SurfaceShader入門

Shaderプログラミングとは

入力したメッシュに対しての補正などをするコードです。
これを通した後に描画処理になります。


擬似空間での物質の質感を表現する方法は、3通りあります。
これは、Webで言うとCSSのような位置付けです。

難易度が高い順に説明します。


・固定関数シェーダー (Fixed Function Shader)
最近のGPUではありえないですが、プログラマブルシェーダをサポートしてない古いハード用です。
これは、単調な色表現などになります。

・サーフェイスシェーダ (Surface Shader)
サーフェイスシェーダは、頂点情報をそのままでオブジェクト全体の質感を一元で設定する方法です。
画像のマッピングも出来ますが、リアルに近い表現はそこまで出来ないです。
今回は、こちらを説明します。

・頂点 / フラグメントシェーダ (Vertex / Fragment Shader)
頂点シェーダーは、頂点が多いと処理速度が落ちるために最適化処理をコードでやっていました。(過去形なのは、
物理的な性能が上がったので意識してないでもやってくれるよになったが正しいでしょうか。)
フラグメントシェーダーは、テクスチャーや色を頂点毎に設定するスクリプトです。
複雑なキャラクターや360°ビューなどはコチラを使います。
用途としては、『ガラス』や『布』などの質感を表現する際に利用します。

UnityでのShaderプログラムの作り方

Unityでは、以下の画像の通りにメニューを選択することで、Shaderコードを生成できます。
f:id:subrutm:20161203055924p:plain

それぞれについて説明します。


1. Standard Surface Shader (3D)
標準的なSurface Shaderで初期コードでは、金属質感を設定できるコードになっています。

2. Standard Surface Shader (Instanced) (3D)
GPU instancingを利用したサーフェースシェーダーです。
docs.unity3d.com


3. Unlit Shader (2D用)
光源演算を考慮しない(影などの質感が無い)描画をする際に利用します。

4. Image Effect Shader (2D用)
画像を使ったエフェクトスクリプトです。(3Dなら画面切り替え時の画面演出などに使える)

5. Compute Shader (グラフィックボードプログラミング)
グラフィックボード上で動作するシェーダープログラミング (公式引用)・
docs.unity3d.com

DirectX11のDirectComputeに近い内容だそうです。(OpenGLやPS4/XBOXでも使われている技術だそうです。)
これは、GPU系のシェーダー本を購入したほうが詳しそうですね。

6. Shader Variant Collection
複数のシェーダーファイルをひとつに纏める手段として提供されています。
#pragmaによるコンパイル言語で細かい切り分けなども出来るようです。(ライトあり/なしで質感を切り替えるなど・・・)

UnityでのSurfaceShaderプログラム構文について解説

UnityのSurfaceShaderは、デフォルトで下記のコードが生成されます。

ポイントは、"Shader", "Properties", "SubShader", "FallBack"の4つです。

1. "Shader"の横の名前設定の意味
上記コードでは、"CookBookShaders/DefaultShader"と書かれています。

これは、GUI上では以下の構成になるようにくまれるようになります。
すなわち『/』は、サブメニューを作る意味になります。
また、"DefaultShader"は、Shaderファイルの名前と合わせてることがコンパイラの仕様となってます。
f:id:subrutm:20161203071902p:plain

2. Propertiesの構文について
ShaderのGUI定義の領域になります。
下記の構文にしたがって定義していきます。

f:id:subrutm:20161203081312p:plain
1. 変数名
2. GUIで表示する名称
3. SufaceShader Propertiesで使用できる型です。
4. 初期値です。

型と初期値の組み合わせを表に纏めます。

型名 概要 コード例
Range (Min, Max) スライダー形式で表示・設定する _Range ("Range", Range(0,1)) = 0.5
Color GUIで色を設定できます。 _Color ("Color", Color) = (1,1,1,1)
2D 2Dテクスチャーマッピング _2D ("2D Color", 2D) = "defaulttexture" {}
Cube Cubeマッピング _Cube ("Cube Map", Cube) = "defaulttexture" {}
3D 3Dテクスチャーマッピング _3D ("3D Color", 3D) = "defaulttexture" {}
Rect 2D用 _Rect("Rect Color", Rect) = "white" {}
Float 直接数字を入力するGUIを表示する _Float ("Float", Float) = 0.0
Vector 直接数字を入力するGUIを表示する _Vector ("Vector", Vector) = (1,1,1,1)

より詳しい内容は、公式を見て頂ければ理解が早いと思います。
docs.unity3d.com

3. SubShaderの構文について
SubShaderは、Shaderの実装部分になります。
正確には、レンダリングパス(PASS)の集合体です。

レンダリングパスの中に描画アルゴリズムをコーディングする。

公式による詳細な説明は、以下です。
docs.unity3d.com


4. FallBackについて
このハードウェアでSubShaderで定義されている処理を実行できない場合に指定されたShaderを試す。
Unityでは、3つのLegacy Shaderを用意している。

シェーダー名 Writing Mode / Material
Diffuse Standard
Physicall-based renderingy: Metallic Workflow
Specular Standard(Specular setup)
Physicall-based renderingy: Specular Workflow
Transparent Standard
Rendering Mode: Transparent
Standard
Rendering Mode: Cutoout

Defaultでは、『Diffuse』でしたので『Specular』に変えた結果、Subshaderが出来る出来ない関係なく
反射質感が付与されていたので、『処理が実行できない場合』の部分が理解出来ませんでした。
もう少し、試して理解を深める必要がありそうです。


最後まで読んで頂きありがとうございました。