Appearance
第02回 Shader Graph基礎
前回: 第01回 GPUとシェーダー / 次回: 第03回 テクスチャーサンプリングと UV
今回の授業内容
- Shader Graphの画面構成と、値を左から右へつなぐ考え方を理解する
ColorとFloatを使い、単色シェーダーを実装する- RGBとHSVを比較し、色を数値として扱う
- GammaとLinearの違いを理解する
- HDR Colorと通常の色の違いを確認する
Shader Graphで色を出力する
最小構成で単色シェーダーを作る
Color を Base Color に接続すれば指定した色が表示されるシェーダーになります
間に倍率を掛ければ、同じ色でも明るさを変えられます
今回はまず最小限の色操作を行う Color x Brightness -> Base Color のシェーダーを作ります
ノードを左から右へ接続する
ノードは、入力と出力を持ちます
入力は左側、出力は右側にあります
ノードの出力をドラッグして、別のノードの入力に接続することで計算をつなげていきます
Base Color などの出力に値をつなげて最終的な色を決めるのがシェーダープログラミングの基本的な流れです
プロパティで設定値を渡す
シェーダーは、マテリアルに設定された値を使って描画結果を決めます
Color プロパティを作ると、マテリアルで指定した色を描画に反映できます
Float プロパティを使うと、明るさや量といった数値もマテリアル側で指定できます
マテリアルの設定を描画に反映させるために、プロパティを定義します
色空間の基礎
人間の知覚が作る色
人間の目の色覚細胞は、赤・緑・青の光を感じる三種類の受容体を持っておりこの三種類の受容体が受け取る光の強さの組み合わせによって人間は様々な色を認識しています
コンピューターグラフィックスの世界では主にこの三色の強さを数値で表すことで色を扱いますですがこれはデータ化のしやすさやディスプレイの仕組みに合わせた表現であり必ずしも色の本質を表しているわけではありません
色を座標で扱う色空間
色を座標で扱うことができれば、数値計算によって色を指定したり、混ぜたり、色味を変えたりといった操作が可能になります
色を座標で表すためのルールが色空間です
赤青緑の三原色で色を表現する RGB や色相・鮮やかさ・明るさで表す HSV など、多くの色空間が存在します
CGでは主にRGBが使われますが、色の操作によっては必ずしもRGBが最適とは限りません
必要な計算に応じて、色空間を使い分けることが重要になります
光の三原色で表すRGB
出典: Quark67 / Monami, Wikimedia Commons,CC BY-SA 3.0
一般にコンピューター用のディスプレイは発光によって色を作るため CGでも色を光の三原色で扱うのが基本です
赤・緑・青の値が弱ければ暗くなり 3つとも 0 に近いと黒に 3つとも強いと白に近づきます
例えば Shader Graph の Color プロパティはこの RGB の値を扱います
印刷物で使われるCMYK
出典: SharkD, Wikimedia Commons, CC0
CMYK は、シアン・マゼンタ・イエロー・ブラックの4色を使って色を表す色空間で主に印刷物で使用されます
CMYK は加法混色の光の三原色とは異なり減法混色と呼ばれる方法で色を表現します
シアンは赤を吸収し、マゼンタは緑を吸収し、イエローは青を吸収するためこれらを組み合わせることで様々な色を表現します
色相・彩度・明度で表すHSV

出典: 3ucky3all, Wikimedia Commons, CC BY-SA 3.0
HSV は色を色相(Hue)・鮮やかさ(Saturation)・明るさ(Value)の3つの要素で表す色空間です
H = Hue は色の種類を表します
S = Saturation は色の鮮やかさを表し、高いほど鮮やかに、低いほど白や灰色に近づきます
V = Value は明るさを表し、低いほど黒に近づきます
RGBと色相の関係
出典: Goffrie, "HSV-RGB-comparison", Wikimedia Commons, CC BY-SA 3.0
色相は HSV だけの概念ではありません RGB の値の組み合わせとしても表現できます
例えば赤から黄へ変わるときは G が増えシアンから青へ変わるときは G が減ります
色相の移り変わりは RGB の3成分の増減として規則的に読み取れます
この対応関係から、RGB と HSV の間で色を相互変換できることがわかります
色空間を相互変換する
RGB は、赤・緑・青をそれぞれどれだけ出すかで色を表します
HSV は、H = Hue で色相、S = Saturation で鮮やかさ、V = Value で明るさを表します
RGB では 3 つの値を同時に扱うため、色合いだけを操作するのは難しいですが HSV では色相・鮮やかさ・明るさを分けて指定できるため、 色の鮮やかさを保ったまま明るさを変えたり明るさを保ったまま色みを変えたりの操作が簡単に行えます
RGBとHSVは相互変換できますが、無彩色ではHueを一意に決められず、計算精度や値の範囲によって往復時に差が出る場合があります
シェーダーでは、色相、彩度、明度のどれを操作したいかに応じてRGBとHSVを使い分けます
シェーダーで色を計算する
色をベクトルとして扱う
- RGB は
R、G、Bの3つの値で色を表します - HSV も
H、S、Vの3つの値で色を表します - シェーダーでは、こうした複数の成分からなる値を ベクトルとして扱います
- 色をベクトルとして扱うことで、 成分ごとの値を計算で加工できるようになります
複数の数値をまとめるベクトル
ベクトルは、複数の数値をまとめて扱うための表現です
2つの値なら二次元ベクトル 3つの値なら三次元ベクトル 4つの値なら四次元ベクトルと呼びます
例えば位置は (x, y, z) 色は (r, g, b) のように表せます
本来は方向と大きさを表す数学的な概念ですが今回は詳しい計算までは扱いません
シェーダーでは、複数の値をまとめて渡したりまとめて計算したりするために使います
数値やベクトルを計算で加工する
シェーダーでは、数値やベクトルを計算で加工してから出力できます
Add は値を足します
Subtract は値を引きます
Multiply は値を掛けます
Divide は値を割ります
どのノードも入力された値を計算し結果を次のノードへ渡します
Multiplyで色の強さを調整する
- 色を表すベクトルに
Floatを掛けると複数の成分をまとめて調整できます 1.0なら元の値です0.5なら各成分の値が半分になります2.0なら各成分の値が2倍になります- 今回の実習では
Multiplyを使ってColor x Intensity -> Base Colorの流れを作ります
明るさを正しく扱う
ガンマ空間とリニア空間
出典: Kakurady, Wikimedia Commons, CC0
ガンマ空間 は、人間の見た目の印象に合わせて明るさを扱う考え方です
リニア空間 は、光のエネルギー量をそのまま計算するための考え方です
光の計算はリニア空間のほうが自然に扱えます
一方で、画面に表示するときは人間の見え方に合わせたガンマ空間への変換が必要になります
100%を超える明るさを扱うHDR Color
色の明るさは光のエネルギー量を表しますがディスプレイが表示できる明るさには限界があります
この表示できる明るさの幅がダイナミックレンジです
High Dynamic Range (高ダイナミックレンジ)はその範囲を広く扱える表現です
通常の色は 0 から 1 の範囲で RGB を指定しますが HDR Color では 1 を超える値も指定できます
これにより、太陽のような非常に強い光も値を切り捨てずに扱えます
HDR Colorで強い光を扱う
例えば空の写真に太陽が写ると、白くつぶれて見えることがありますですが実際の太陽の明るさはディスプレイの白を大きく上回ります
HDR Color を使えば、太陽のような強い光も明るさを保ったまま扱えます
1 を超える明るさを保持できれば光のエネルギーを足し引きするときも情報が失われにくくなります
物理的な光の計算では、このようなハイダイナミックレンジで色を扱うことで太陽光と室内光のように大きく異なる明るさの光も同時に表現できます
色の計算で確認するポイント
- 色は数値で表されますが、その数値が何を意味するかは色空間によって異なります
- そのため、色を足す計算や明るさの計算は、どの色空間で行うかで結果が変わります
色空間を使い分けることで、色の操作を意図どおりに行えます - 光のエネルギー量を正しく扱うには、リニア空間と HDR の考え方が欠かせません
計算はリニア空間で行い、表示時にガンマ空間へ変換することで物理的な整合性と見た目の自然さを両立できます - 色空間と明るさの性質を理解して使い分けることがシェーダーで色を扱う際の基本になります
実習:最小の単色シェーダーを作る
最小でも結構おもしろいよ
実習1:Shader Graphを作成する
Create > Shader Graph > URP > Unlit Shader Graphを選ぶ- Shader Graph に名前を付けて保存する
- Graph を開き、
BlackboardとGraph Inspectorの位置を確認する - Master Stack の
Base Colorが最終出力先だと確認する
実習2:単色シェーダーを作る
Colorプロパティを追加するBase Colorに接続する- 保存してマテリアルを作成する
- オブジェクトに適用して、マテリアル側から色が変わることを確認する
- ここでは余計なノードを増やさず、単色シェーダーの最小構成を確実に把握します
実習3:明るさを調整できるようにする
Floatプロパティを追加するMultiplyノードでColorに掛ける- 値を
0.5、1.0、2.0などに変えて見比べる - HDR Color の有無でも挙動を確認する
- 色と明るさを別々に動かし、どの操作がどの結果につながるかを切り分けてください
実習4:RGBとHSVを相互変換して色を補間する
- 2色の
Colorを用意し、そのまま RGB で補間した結果を確認する - 同じ2色を HSV に変換し、色相を中心に補間する
- 補間後に RGB へ戻して表示し、途中の色の出方を比較する
- 明度を保ったまま色を変えたい場面で、どちらの補間が合うか説明できるようにする
- RGB と HSV では、同じ補間でも途中の色の出方が変わります
- 色をどう表すかで補間結果も変わることを、操作を通して押さえてください
完成条件
- Shader Graph を作成できる
Colorプロパティをマテリアルから変更できるAdd、Subtract、Multiply、Divideの役割を説明できるFloatで明るさ調整ができる- HDR Color の意味を説明できる
- ガンマ空間とリニア空間の違いを説明できる
- RGB と HSV で補間結果がどう変わるか説明できる
今回のまとめ
- 今回は Shader Graph の基本を確認し、 色と明るさの扱いを踏まえて単色シェーダーを実装しました
- マテリアルの設定を描画へ反映する流れを確認し、 プロパティの役割を学びました
- 四則演算ノードで色、明るさ、UV、透明度などを計算で加工できることを確認しました
- さらにガンマ空間とリニア空間の違いを通して光のエネルギー量を扱う意味を学びました
使用画像と出典
- AdditiveColorMixing.svg Quark67 / Modified color by Monami, CC BY-SA 3.0, via Wikimedia Commons
- Linear Distribution versus Gamma Corrected Distribution.svg Kakurady, CC0, via Wikimedia Commons
- HSV cone.png 3ucky3all, CC BY-SA 3.0, via Wikimedia Commons
- CMYK subtractive color mixing.svg SharkD, CC0, via Wikimedia Commons
- HSV RGB Comparison.svg Goffrie, CC BY-SA 3.0, via Wikimedia Commons