Skip to content

第02回 Shader Graph基礎

前回: 第01回 GPUとシェーダー / 次回: 第03回 テクスチャーサンプリングと UV

今回からいよいよ Shader Graph に 触れていきます

ノードベースの プログラミングも たのしいよ

前回の振り返り

GPUとシェーダーの役割

  • シェーダーは、頂点の位置やピクセルの色を計算するために GPU上で実行されるプログラムです
  • Unity のマテリアルは、描画に使用するシェーダーと そのシェーダーに渡す設定値をまとめたものです
  • 今回は Shader Graph でのシェーダーの作成と マテリアルを利用した色の表現に挑戦します

今回の授業の目的

Shader Graphで色を扱う

  • Shader Graph の基本画面と、値をつなぐ考え方を理解します
  • ColorFloat を使い、単色シェーダーを自作します
  • 明るさの操作と HDR Color の意味を把握します
  • GammaLinear の違いが、どの場面で効くかを理解します

今回の授業内容

色を作る / 明るさを操作する / 色空間を見る

  • Shader Graph の基本的な使い方を確認する
  • 色の扱い方を整理する
  • 色空間と Gamma / Linear の違いを理解する
  • 実際に組んで実装する

最小構成で単色シェーダーを作る

指定した色を表示するシェーダーを作ります

  • ColorBase Color に接続すれば 指定した色が表示されるシェーダーになります
  • 間に倍率を掛ければ、同じ色でも明るさを変えられます
  • 今回はまず最小限の色操作を行う Color x Brightness -> Base Color のシェーダーを作ります

Shader Graph のノードの見方

左から右へ値をつないでいく

  • ノードは、入力と出力を持ちます 入力は左側、出力は右側にあります
  • ノードの出力をドラッグして、別のノードの入力に接続することで 計算をつなげていきます
  • 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 の使い分けが多用されます

色はベクトルとして扱える

複数の値をまとめたデータ

  • RGB は RGB の3つの値で色を表します
  • HSV も HSV の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

  • ガンマ空間 は、人間の見た目の印象に合わせて 明るさを扱う考え方です
  • リニア空間 は、光のエネルギー量を そのまま計算するための考え方です
  • 光の計算はリニア空間のほうが自然に扱えます 一方で、画面に表示するときは人間の見え方に 合わせたガンマ空間への変換が必要になります

HDR Color

100% を超える明るさを扱う表現

  • 色の明るさは光のエネルギー量を表しますが ディスプレイが表示できる明るさには限界があります この表示できる明るさの幅がダイナミックレンジです
  • High Dynamic Range (高ダイナミックレンジ)は その範囲を広く扱える表現です
  • 通常の色は 0 から 1 の範囲で RGB を指定しますが HDR Color では 1 を超える値も指定できます
  • これにより、太陽のような非常に強い光も 値を切り捨てずに扱えます

HDR Color の意味

強い光を直接的に扱う

  • 例えば空の写真に太陽が写ると、白くつぶれて見えることがあります ですが実際の太陽の明るさはディスプレイの白を大きく上回ります
  • HDR Color を使えば、太陽のような強い光も明るさを保ったまま扱えます 1 を超える明るさを保持できれば 光のエネルギーを足し引きするときも情報が失われにくくなります
  • 物理的な光の計算では、このようなハイダイナミックレンジで色を扱うことで 太陽光と室内光のように大きく異なる明るさの光も同時に表現できます

色空間を理解し、色の計算を正しく行う

今回押さえたいポイント

  • 色は数値で表されますが、その数値が何を意味するかは色空間によって異なります
  • そのため、色を足す計算や明るさの計算は、どの色空間で行うかで結果が変わります 色空間を使い分けることで、色の操作を意図どおりに行えます
  • 光のエネルギー量を正しく扱うには、リニア空間と HDR の考え方が欠かせません 計算はリニア空間で行い、表示時にガンマ空間へ変換することで 物理的な整合性と見た目の自然さを両立できます
  • 色空間と明るさの性質を理解して使い分けることが シェーダーで色を扱う際の基本になります

実習

最小の単色シェーダーを作る

最小でも結構 おもしろいよ

実習1

Shader Graphを作成する

  1. Create > Shader Graph > URP > Unlit Shader Graph を選ぶ
  2. Shader Graph に名前を付けて保存する
  3. Graph を開き、BlackboardGraph Inspector の位置を確認する
  4. Master Stack の Base Color が最終出力先だと確認する

実習2

単色シェーダーを作る

  1. Color プロパティを追加する
  2. Base Color に接続する
  3. 保存してマテリアルを作成する
  4. オブジェクトに適用して、マテリアル側から色が変わることを確認する
  • ここでは余計なノードを増やさず、単色シェーダーの最小構成を確実に把握します

実習3

明るさを調整できるようにする

  1. Float プロパティを追加する
  2. Multiply ノードで Color に掛ける
  3. 値を 0.51.02.0 などに変えて見比べる
  4. HDR Color の有無でも挙動を確認する
  • 色と明るさを別々に動かし、どの操作がどの結果につながるかを切り分けてください

実習4

RGBとHSVを相互変換して色を補間する

  1. 2色の Color を用意し、そのまま RGB で補間した結果を確認する
  2. 同じ2色を HSV に変換し、色相を中心に補間する
  3. 補間後に RGB へ戻して表示し、途中の色の出方を比較する
  4. 明度を保ったまま色を変えたい場面で、どちらの補間が合うか説明できるようにする
  • RGB と HSV では、同じ補間でも途中の色の出方が変わります
  • 色をどう表すかで補間結果も変わることを、操作を通して押さえてください

この回の到達目標

  • Shader Graph を作成できる
  • Color プロパティをマテリアルから変更できる
  • AddSubtractMultiplyDivide の役割を説明できる
  • Float で明るさ調整ができる
  • HDR Color の意味を説明できる
  • ガンマ空間とリニア空間の違いを説明できる
  • RGB と HSV で補間結果がどう変わるか説明できる

今回のまとめ

Shader Graph で色を扱う基本を押さえる

  • 今回は Shader Graph の基本を確認し、 色と明るさの扱いを踏まえて単色シェーダーを実装しました
  • マテリアルの設定を描画へ反映する流れを確認し、 プロパティの役割を学びました
  • 四則演算ノードで色、明るさ、UV、透明度などを 計算で加工できることを確認しました
  • さらにガンマ空間リニア空間の違いを通して 光のエネルギー量を扱う意味を学びました

おつかれさまでした!

次回予告 第03回 テクスチャーと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