📖

Unity ShaderGraph メモ

2024/07/19に公開

ノード

主な参照サイト

参照サイト参照サイト

Channel Mixer

各RGBごとに色を調整できる。

Contrast

コントラストを調整できる。

Hue

色相を変更できる。

Invert Colors

各RGBAを反転できる。

Replace Color

色を指定して変更できる。

Saturation

彩度を調整できる。

White Balance

色温度を調整できる。
Temperature は値を黄色あるいは青寄りに変化させる効果があり、Tint はピンクあるいは緑寄りに変化させる効果があります。

Blend

Photoshopなどにある描画モードを使用して、色を合成できる。
https://youtu.be/3yxcrlNrnK4
参照サイト参照サイト参照サイト参照サイト

Dither

ディザリングを適用できる。

参照サイト

Fade Transition

ノイズをインプットとして、FadeValueいじってアルファ抜きを行う。
公式ドキュメント見ると、LODの切り替わりの際のモデルの消失の時によく使われるみたい。
https://youtu.be/TQDkl2iUBuM

Channel Mask

入力値を、各RGBAのチャネルごとにマスクできる。

Color Mask

Mask Colorで色指定して、その色をマスクできる。

Fuzzinessできっぱりしたマスクじゃないようにできる。

Normal Blend

Normalを合成できる。

Normal From Height

ハイトマップをノーマルマップに変換する。

Normal From Texture

通常のbaseマップからノーマルマップに変換する。

Normal Reconstruct Z

生成された法線マップ用に正しい Z 値を算出すると公式ドキュメントに記載があったたが正直よくわからない。

Normal Strength

ノーマルマップの強さを調整できる。
Strengthが0.5

Strengthが5

Normal Unpack

Texture TypeがNormalMapで、Sample Texture 2DのTypeがDefaultでノーマルマップ表現しようとすると不自然になる。
なので、Normal Unpackをはさむことでこの不自然さを改善できる。
ただ、Sample Texture 2DのTypeをNormalにすればこの不自然さを解決できるので特に使用しなくてもよいノード。
Normal Unpackなし

Normal Unpackあり

Colorspace Conversion

色空間から別の色空間へ変換した結果を返す。
RGB、Linear、HSVへ変換できる。

Combine

入力値をもとに新しい各RGBAを作成する。
https://youtu.be/BJBjZSUw-6o

Flip

入力値をもとにチェックしたチャンネルを反転させる。

Split

入力値から一つのチャネルを出力する。

Swizzle

Maskに値を指定してMaskできるチャンネルを指定できる。
x→R
y→G
z→B
w→A

Self

公式ドキュメントにのっていない

Size

公式ドキュメントにのっていない

Slice Index/CubeMap Face

公式ドキュメントにのっていない

Light Texture

公式ドキュメントにのっていない

Boolean

有効なら1
無効なら0

Color

色を指定できる。

Constant

数学で用いられる定数を使用できる。
PI→円周率を表すπ
TAU→円周率を表すτ
PHI→黄金比(golden ratio)表すφ(ファイ)
E→自然対数の底であるネピア数
SQRT2→2の平方根

Float

Float型で値を調整できる。

Integer

Integer型で値を調整できる。

Slider

MinとMaxの値で調整できる。

Time

Timeを使用するとアニメーションできる。
Time→ひたすら加算される
Sine Time→Sin波
Cosine Time→Cos波
Delta Time→前フレームの経過時間
Smooth Delta→平滑化された前フレームの経過時間
実験してみたがDelta TimeとSmooth Delta以外は自分の想定している結果となった。
Delta TimeとSmooth Deltaは前フレームの経過時間なのでUVスクロールすると思ったが何故かしなかった。
https://youtu.be/Jam_3rH1iWY
UVスクロール以外に、色変えたり、フレネルのエフェクトを調整できる。
https://www.youtube.com/watch?v=p6hYVJqr5sQ
参照サイト

Vector 2/Vector 3/Vector 4

Vector型で値を調整できる。

Bitangent Vector

ノーマルマップで使用する従接線(従法線)の値を取得できる。
従接線(従法線)を求めるときは、通常は法線と接線の外積で求めるがそれをしなくても取得できるノード。
公式ドキュメントで従接線のこと従法線とも言うらしい。

参照サイト

Instance ID

GPUインスタンシングで使用するインスタンスIDを取得できる。

Normal Vector

法線を取得できる。

Position

座標を取得できる。

Screen Position

スクリーン座標を取得できる。
例えばDefalutだと画面左下から(0, 0)で、右と上にいくにしたがって値が増えていく。

Tangent Vector

接線を取得できる・

UV

UVを取得できる。

Vertex Color

頂点カラーを取得できる。

Vertex ID

頂点IDを取得できる。

参照サイト

View Direction

正規化された視線ベクトルを取得できる。

View Vector

正規化されていない視線ベクトルを取得できる。

Blackbody

黒体放射の効果をシュミレーションする色を指定できる。

Gradient

グラデーションの色を指定できる。

Sample Gradient

Timeの値に従ってGradientの色の指定できる。
範囲は0-1の間。
https://youtu.be/a8ZvynPGY3s
https://youtu.be/Yi1eRVXvVyg

Ambient

環境光を取得できる。
https://youtu.be/mZK08E4K0ts

Baked GI

ベイクしたライトマップを取得できる。

Main Light Direction

メインの指向性ライトのベクトルを取得できる。
メインの指向性ライトは、影を落とすライトのこと。 (影がある場合)。
影を落とさない場合は、影を落とさない最初の指向性ライトのベクトルを取得できる。

Reflection Probe

環境光のリフレクションを取得できる。

Matrix 2x2/Matrix 3x3/Matrix 4x4

指定した行列を設定できる。

Transformation Matrix

ビルトインのシェーダー変数を取得できる。
参照サイト参照サイト
Model→UNITY_MATRIX_M
InverseModel→UNITY_MATRIX_I_M
View→UNITY_MATRIX_V
InverseView→UNITY_MATRIX_I_V
Projection→UNITY_MATRIX_P
InverseProjection→UNITY_MATRIX_I_P
ViewProjection→UNITY_MATRIX_VP
InverseViewProjection→UNITY_MATRIX_I_VP

Compute Deformation

Dotsで使用する。
よくDots詳しくないのでよくわからない。

Linear Blend Skinning

Dotsで使用する。
よくDots詳しくないのでよくわからない。

Dielectric Specular

物質ごとのF0(フレネスゼロ)の値を取得できる。
PBRの時などに使用する。

Metal Reflectance

物質ごとの金属の反射率の値を取得できる。
PBRの時などに使用する。

Camera

Camera (カメラ) の各種パラメーターを取得できる。

以下がパラメータの内容である。

Eye Index

VRやXRでのステレオレンダリングで使用するEye Indexを取得できる。

Fog

Fogの色を取得できる。

Object

ワールド空間のオブジェクトの座標とスケールとバウンディングボックスのサイズと最大値・最小値を取得できる。

Scene Color

不透明オブジェクトまで描画した結果をテクスチャとして使用できる。

ただ、URPアセットのOpaqueTextureを有効にし、ShaderGraph側のSurfaceTypeをTransparentにしないと上手く描画されない。
以下がノードである

Scene Depth

現在のカメラの深度バッファを取得できる。
DepthTextureを有効にしないと取得できない。

色々な用途で使用するが下の例だとソフトパーティクルなどに使用できる。

Liner01
Near~Farが、0~1

Raw
Near~Farが、1~0

Eye
正規化されていない値

参照動画参照動画参照動画

Scene Depth Difference

ワールド空間座標と深度値の差を取得する。

Screen

画面の縦と横幅を取得できる。

Calculate Level Of Detail Texture 2D

このノードは、シェーダーでサンプリングする前にミップ レベルを変更する場合など、テクスチャのミップ レベルを知る必要がある状況で役立つ。

Gather Texture 2D

赤色をRRRRで出力する。
カスタム ブレンドを作成する場合など、ピクセル間の双線形補間を変更する場合に便利。

Sample Cubemap

CubeMapを設定できる。

なおCubemap Assetで指定できる。

Sample Reflected Cubemap

反射したCubeMapを設定できる。

なおCubemap Assetで指定できる。

Sample Texture 2D

テクスチャを指定する。

なおTexture 2D Assetで指定もできる。

Sample Texture 2D Array

2D Arrayのテクスチャをindexを指定して取得できる。
https://youtu.be/PR87aL16560
なおTexture 2D Array Assetでも指定できる。

Sample Texture 2D LOD

LODに応じてテクスチャの解像度を変えることができる。
なおこのノードは頂点シェーダーでも使用可能である。
Sample Texture 2Dは頂点シェーダーでは使用できない。

Sample Texture 3D

3Dテクスチャを指定する。

なおTexture 3D Assetで指定もできる。

Sample Virtual Texture

ストリーミング仮想テクスチャリング (SVT) のテクスチャを指定する。

Sampler State

FilterとWrapを指定できる。

Split Texture Transform

指定テクスチャのoffset、tillingを取得できる。
https://youtu.be/vF1h3Hsi7sU
参照サイト

Texture Size

テクスチャのサイズと、テクセルのサイズを取得できる。

URP Sample Buffer

画面の色、ワールド空間法線、モーションベクターを取得できる。

参照サイト参照サイト

Absolute

絶対値の返す。

Exponential

eのx乗または2のx乗を返す。

Length

ベクトルの大きさを返す。


カメラの距離に合わせて色々処理を分けることができる。
パーティクルのアルファや色を変えたり、ディザ透過、ソフトパーティクルをなどもできる。
https://zenn.dev/r_ngtm/books/shadergraph-cookbook/viewer/tips-particle-camera-distance

Log

対数を返す。

Modulo

入力 A を入力 B で割った剰余を返す。

Negate

入力値の符号を反対にする。

Normalize

大きさ1の正規化したベクトルを返す。
なお、方向は同じ。

Posterize

ポスタライズ化できる。

Reciprocal

1を入力値で割った値を返す。

Reciprocal Square Root

1を入力値の平方根で割った値を返す。

Add

2つの入力値を足す。

Divide

AをBで割った値を返す。
0で割る場合、パフォーマンス的に良くないので気を付けること。

Multiply

AとBを乗算する。

Power

AをB乗した結果を返す。

なお、Powerノードは負の値を入力した場合に、エラー(ピンク色)になる。

Square Root

入力値の平方根を返す。

Subtract

AからBを引く。

UVスクロールを逆にできる。

グラデーションの強いところから弱いところに向かってアニメーションもできる。
https://youtu.be/5Qbi0JexggE

DDX/DDY

DDXはX座標のピクセル間の差をベクトル型で取得する。
DDYはY座標のピクセル間の差をベクトル型で取得する。
これを利用して接線と従法線を求め、外積して法線を求めフラットシェーディングを表現できる。

参照サイト

DDXY

スクリーンスペースのXY座標のピクセル間の差をベクトル型で取得する。
下記サイト見る限り、アウトラインとアンチエイリアスを作成できるっぽい。

https://youtu.be/_M-4s4nbBWg?feature=shared
https://aitarai.hateblo.jp/entry/2021/04/30/175628

Lerp

AとBは線形補間する。
(1-T)A+TB


https://youtu.be/pGoBK-t4hhk

Inverse Lerp

Inverse Lerpは、Lerpの逆演算。
(T - A)/(B - A)
いまいち使いづらい

Smoothstep

Inの値によって、違う結果を返す。
Stepと違って二値化にはならない。
・In≦Edge1
→0
・In≧Edge1
→1
・Edge1<In<Edge2
→3In^2-2In^3

アニメーションを加えた例
https://youtu.be/dn3y5KVxylQ?feature=shared&t=500

Matrix Construction

M0、M1、M2、M3 の 4 つの入力ベクトルから正方行列を作成できる。

Matrix Determinant

入力 In で定義される行列の行列式を返します。

Matrix Split

入力 In で定義される正方行列をベクトルに分割する。

Matrix Transpose

入力 In で定義される行列を転置した値を返す。

Clamp

Min、Maxを指定して入力値の制限を行う。
・In≦Min
→Min
・Min<In<Max
→In
・In≧Max
​→Max
Powerの入力値はマイナスだとピンク色になるのでエラーを解消している。

Fraction

少数部分を返す。
グラデーションを連続して作成できる。

スキャンラインなどの表現もできる。
https://youtu.be/H7EXq7erFUw

Maximum/Minimum

AとBのうち最大・最小値を返す。
https://youtu.be/rLJTaBGpu6I

One Minus

1から入力値を引いた値を返す。

Random Range

入力 Min で定義される最小値と入力 Max で定義される最大値の間の範囲にある入力 Seed に基づいた、疑似乱数値を返します。
入力 Seed の値が同じ場合は出力値も必ず同じになりますが、出力値自体はランダムであるように見えます。
https://youtu.be/aKDfeBUZfjY

Remap

入力値のIn Min MaxをOut Min Maxに変換する。

Saturate

入力値を0-1の範囲で制限する。
・In≦0
→0
・0<In<1
→In
・In≧1
​→1
Powerの入力値はマイナスだとピンク色になるのでエラーを解消している。

拡散反射光を求める際、法線と光線ベクトルを内積して求めるがその際cosΘが-1~1の値をとるので、Saturateを使用して0-1にする。

アルファなどの0~1以外の値が入って欲しくない場合に使用したりする。

Ceiling

入力 In の値以上で最小の整数値を返す。
https://youtu.be/vuZkU02SJUk

Floor

入力 In の値以下で最大の整数値を返す。
コマ送りアニメーションなどで使える。
https://youtu.be/3oRLnzmGYMQ
参照サイト

Round

入力値に対して四捨五入する。

Sign

Inの値によって、違う結果を返す。
・In<0
→-1
・In=0
→0
・In>1
​→1

Step

二値化を行う。
・In≧Edge
→1
・In<Edge
→0
https://youtu.be/0Nvrm0USw6M

Truncate

入力 In の値の整数部分を返す。

Arccosine

アークコサインを利用できる。

Arcsine

アークサインを利用できる。

Arctangent

アークタンジェントを利用できる。

Arctangent2

アークタンジェント2を利用できる。

Cosine

コサインを利用できる。
色を明滅させたり、座標を動かしたり、waveっぽい表現などができる。
https://youtu.be/IFyZNSyjyFA?feature=shared&t=235

Degrees To Radians

度数からラジアンに変換する。

Hyperbolic Cosine

ハイパボリックコサインを返す。

Hyperbolic Sine

ハイパボリックコサインを返す。

Hyperbolic Tangent

ハイパボリックタンジェントを返す。

Radians To Degrees

ラジアンから度数に変換する。

Sine

サインを利用できる。
Sinxのxの値が大きいほどグラフの周期が大きくなるのでこれを利用して縞々みたいな表現などができる。


また色を明滅させたり、座標を動かしたり、waveっぽい表現などができる。
https://youtu.be/IFyZNSyjyFA?feature=shared&t=235
https://zenn.dev/r_ngtm/books/shadergraph-cookbook/viewer/tips-vertex-shader

Tangent

タンジェントを利用できる。

Cross Product

外積を利用できる。
https://zenn.dev/r_ngtm/books/shadergraph-cookbook/viewer/node-cross-product

Distance

AとBの距離を返す。
https://youtu.be/vFqfJk_0Y9Q

Dot Product

AとBの内積を返す。
Lambert反射の拡散反射光を実装してみる。
まず、メインライトのカラーと光線ベクトルをhlslに定義し、それをCustom Functionで使用する。
(メインライトのカラーはノードでは存在しないため。光線ベクトルは存在する。)

#ifndef CUSTOM_LIGHTING_INCLUDED
#define CUSTOM_LIGHTING_INCLUDED

#ifndef SHADERGRAPH_PREVIEW
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#endif

void MainLight_float(out float3 Direction, out float3 Color)
{
    #ifdef SHADERGRAPH_PREVIEW
    Direction = float3(0.5, 0.5, 0);
    Color = 1;
    #else
    Light mainLight = GetMainLight();
    Direction = mainLight.direction;
    Color = mainLight.color;
    #endif
}

#endif

ノードである。

実際の結果である。

また、内積を使用するとNTSC加重平均法でグレースケールにできる。

また、以下のようなノードも作成できる。

参照サイト参照サイト

Fresnel Effect

フレネルエフェクトを実装できる。

Projection

入力Aの値を入力Bの値に平行な直線上に投影した結果を返す。

イメージは以下である。

参照サイト

Reflection

反射ベクトルを求めることができる。

キューブマップから環境光を反映。

他にも鏡面反射光でもこの反射ベクトルが必要である。
参照サイト

Refract

屈折効果を与えることができる。

Rejection

入力Aの値を入力Bの値に直交する平面に投影した結果を返す。

イメージは以下である。

参照サイト

Rotate About Axis

入力ベクトルIn を軸Axisを中心にRotationの値だけ回転する。

https://youtu.be/Nb5i4YBL5L4

Sphere Mask

球のマスクを指定できる。
下記動画のように球上のオブジェクトにマスクをかけることができる。
詳しいノードは参照サイトを参照。
https://youtu.be/hTJqo1HeEOs?feature=shared&t=513

Transform

座標、方向、法線をオブジェクト空間、ビュー空間、ワールド空間、接線、絶対ワールド、スクリーン空間に変換できる。

Noise Sine Wave/Sawtooth Wave/Square Wave/Triangle Wave

Timeの拡張版のノード。
ノードのグラフイメージは以下。

挙動は動画を参照。
https://youtu.be/yTo5sKwVu6k
参照サイト参照サイト

Bacteria~Zig Zagノードはサンプルをダウンロードする

Bacteria, Brick, Dots, Grid, Herringbone, Hex Lattice, Houndstooth, Smooth Wave, Spiral, Stripes, Truchet, Whirl, Zig ZagはPackManegerからダウンロードする。

Bacteria

以下のようなノードである。

https://youtu.be/AwncFJnsUNc

Herringbone

以下のようなノードである。
https://youtu.be/2KZ6du8BJNU

Hex Lattice

以下のようなノードである。
https://youtu.be/R5Xnu8A582k

Houndstooth

以下のようなノードである。
https://youtu.be/m54yJMvlLgU

Spiral

以下のようなノードである。
https://youtu.be/87QYYR9TZlE

Truchet

以下のようなノードである。
https://youtu.be/N2CVPVqbp28

Whirl

以下のようなノードである。
https://youtu.be/Fha5Jk9EKTQ

Zig Zag

以下のようなノードである。
https://youtu.be/sx1a3QhFqZ4

Brick

以下のようなノードである。
https://youtu.be/m0Pq_mbZse8

Dots

以下のようなノードである。
https://youtu.be/sUc4wSTruLc

Grid

以下のようなノードである。
https://youtu.be/HGlBHK0JtA0

Stripes

https://youtu.be/8HmaPzkcPcY

Checkerboard

市松模様を利用できる。

Gradient Noise

Gradient Noiseを利用できる。

Simple Noise

Simple Noiseを利用できる

Voronoi

Voronoi を利用できる

Ellipse

円のシェイプを作成できる。

Polygon

多角形のシェイプを作成できる。

Rectangle

四角形のシェイプを作成できる。

Rounded Polygon

角がまるまった多角形のシェイプを作成できる。

Rounded Rectangle

角がまるまった四角形のシェイプを作成できる。

SpeedTree8Billboard

SpeedTreeはあまり使用しないで一旦はパス

SpeedTree8ColorAlpha

SpeedTreeはあまり使用しないで一旦はパス

SpeedTree8InterpolatedNormals

SpeedTreeはあまり使用しないで一旦はパス

SpeedTree8Wind

SpeedTreeはあまり使用しないで一旦はパス

Custom Function

Custom Functionはシェーダーコードを実際に書いて自前のノードとして使用できる機能である。

#ifndef CUSTOM_LIGHTING_INCLUDED
#define CUSTOM_LIGHTING_INCLUDED

#ifndef SHADERGRAPH_PREVIEW
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#endif

void MainLight_float(out float3 Direction, out float3 Color)
{
    #ifdef SHADERGRAPH_PREVIEW
    Direction = float3(0.5, 0.5, 0);
    Color = 1;
    #else
    Light mainLight = GetMainLight();
    Direction = mainLight.direction;
    Color = mainLight.color;
    #endif
}

#endif

ノードである。

実際の結果である。

参照サイト参照サイト

Preview

入力のノードの確認をできる。

All

一つでも0があればfalse(0)。
0がなければtrue(1)。

And

AとBが0以外であればtrue(1)。
それ以外はfalse(0)。
https://youtu.be/b6pJcddBwvo

Any

どれか一つでも0以外がある場合true(1)。
全て0の場合false(0)。

Branch

PredicateがTure(1)の場合、True(1)
PredicateがFalse(0)の場合、False(0)

Comparison

条件式を指定して、true(1)とfalse(0)を決める。

Is Front Face

前面レンダリングしている場合はTrue。
背面レンダリングしている場合はFalse。
https://youtu.be/lvZIwlrX1tA

Is Infinite

無限(Inf)の場合true(1)。
それ以外はfalse(0)。

なお、無限になる場合は公式ドキュメントだと以下のように記載されている。

いずれかの数字を 0 で割ると Inf が発生します (あるベクトルを長さ 0 で正規化するなど)。
シェーダー操作とは別に、初期化されていないメモリーも NaN または Inf が含まれたり生成されたりします。プラットフォームの中には、新たに作成された レンダーテクスチャ 状のピクセル値が、0 の値では初期化されないものがあります。つまり、書き込んだり消去する前に新しい Render Textures にアクセスすると、NaN/Inf が生成される場合があるということになります。一般的なルールとして、 Render Textures を常に消去してから使うか、読みたいすべての値に書き込みを行ってから読むようにしてください。

Is NaN

NaNの場合true(1)。
それ以外はfalse(0)。

なお、NaNになる場合は公式ドキュメントだと以下のように記載されている。

平方根 (sqrt) または対数 (log/log2) をマイナス値で実行すると NaN が発生します。
A が無限または B が 0 のモジュロ演算、A % B を実行すると NaN が発生します。
シェーダー操作とは別に、初期化されていないメモリーも NaN または Inf が含まれたり生成されたりします。プラットフォームの中には、新たに作成された レンダーテクスチャ 状のピクセル値が、0 の値では初期化されないものがあります。つまり、書き込んだり消去する前に新しい Render Textures にアクセスすると、NaN/Inf が生成される場合があるということになります。一般的なルールとして、 Render Textures を常に消去してから使うか、読みたいすべての値に書き込みを行ってから読むようにしてください。

Nand

どれか一つでも0がある場合true(1)。
それ以外はfalse(0)。

Not

true(1)とfalse(0)を逆にする。

Flipbook

連番アニメーションを行える。
https://youtu.be/MHLQCKIm3QY
参照サイト

Polar Coordinates

極座標に変換できる。





参照サイト

Radial Shear

トルネードっぽい表現ができる。
https://youtu.be/_8awz18pE5o
参照サイト

Rotate

UVを回転させることができる。
https://youtu.be/attNJAjhjX8

Spherize

魚眼レンズっぽい表現ができる。

Tiling And Offset

タイリングとオフセットができる。

Triplanar

Triplanar Mappingをできる。
Node

実際の結果
左がTriplanar Mapping、右が普通のテクスチャマッピング
Triplanar MappingはUVに依存していないのでモデルに貼られたテクスチャのサイズが均一であることが分かる。
一方で、普通のテクスチャマッピングはUVに依存しているのでモデルによってテクスチャのサイズ感がばらばらであることが分かる。

参照サイト参照サイト参照サイト

Twirl

ツイストしている表現ができる。

参照サイト

Parallax Mapping

視差マッピングを実装できる。

Parallax Occlusion Mapping

視差遮蔽マッピングを実装できる。

画像の一部分の色を変える

PhotoShopでマスクの画像を作成する。
作成方法は下記動画を参照。
https://youtu.be/QpgUq4Vujss
ShaderGraphで以下のノードを作成すると画像の一部分の色を変えることができる。

ただ、上の画像だとマスクした箇所の色が少し残っている状態なので丸々指定した色にしたい場合は以下のノードを組む。

参照サイト

バウンディングボックスの影響でテクスチャを上手くデフォームできないとき

UVをいじるのではなく、頂点シェーダーで頂点を動かす。
https://www.youtube.com/live/3TXHMS8xFJ0?feature=shared&t=1856

画像の一部にモザイクをかける


参照サイト

画像全体に指定した色を反映させる

画像全体に指定した色を反映させるには、一度画像をグレースケールにするとよい。
画像をグレースケールにした場合

画像をグレースケールにしない場合

参照サイト

帯電を浴びたエフェクト

以下の動画の解説。
https://www.youtube.com/live/eJqFLsjPWcY?feature=shared

DotProductする理由


赤枠のDotProductする理由は、グレースケールにするためである。
ntsc加重平均法というもので、グレースケールにしたい画像と、指定した値(RGBにそれぞれに0.29、0.58、0.11)を内積をするとグレースケールになる。

Remapする理由


赤枠のDotProductする理由は、頂点アニメーションの不自然さをなくすためである。
以下の動画みると、Remapしていないと頂点アニメーションが不自然であることが分かる。
https://youtu.be/STXIXkrmI4k

プリミティブのQuadではなく、頂点数の多いQuadを作成した理由

プリミティブのQuadだと頂点数が4つしかないので、頂点アニメーションしてもあまり頂点アニメーションしないため。
https://youtu.be/Ec4lm9ny5Vw

Absoluteすると縁が黒くなる理由


Remapで-50にしてところがAbsoluteにすると50になるので、黒い箇所は0であるため。

Saturateする理由


赤枠のSaturateする理由は、Addした際に値が1~-49の取りその結果Addで合成した際に黒くなるため。
Saturateしない場合、以下のように黒くなる。

逆方向のUVスクロールを追加する理由(Remapを2にする理由)


逆方向のUVスクロールを追加する理由は、帯電っぽい表現をしたいためである。
一つの方向だと下記動画のようにただのUVスクロールしているだけで帯電っぽくないが逆方向のUVスクロール入れてやることで帯電っぽい表現になる。
Remapを2にする理由は、逆方向のUVスクロールを追加するとMaxが2になるため。
https://youtu.be/p23_MhP3Dms

UVではなくPostion(World)を使用する理由

UVだと回転によって向きが変わるのでスキャンラインも傾きにそってアニメーションされる。
Postion(World)だとワールドだとオブジェクトを回転させてもスキャンラインの向きはワールドに従ってアニメーションされる。(なおPositionがObjectだとオブジェクトの向きに沿ってアニメーションされる。)
https://youtu.be/nqcCGETNwwc

スキャンラインをSquareWaveではなくFranction使用する理由


SquareWaveを使用すると、ボーダーが1:1になるため

Divideする理由


画像の大きさが30Unitなのでそれを30で割ってStepで調整すれば消失エフェクトができる。
https://youtu.be/XfPUYLnkAuI

消失エフェクトの端の作り方

Custom Interpolatorでフラグメントシェーダでやっていた処理を頂点シェーダーで行い、処理負荷を削減する。

フラグメントシェーダだとピクセル単体で処理が行われるので重い処理だとその分負荷が増してしまう。
なので、Custom Interpolatorを使用すると頂点単位で処理が行われるのでその分負荷がかからない。

参照サイト参照サイト

SubGraphで同じようなノードをまとめて共通ノードとすることで、エディタを見やすくしたり保守性を高める。

SubGraph使用することで、エディタを見やすくしたり保守性を高めることができる。
https://youtu.be/_AnFB7OMPp0

Branch On Input Connection Nodeでデフォルトのノード設定する。

以下のようなBranch On Input Connectionを組む。
その際、Use Custom BindingをチェックしないとInputに差し込めない。

inputにノードが刺さってないと、NotConnectedのノードが適用される。

逆にinputにノードが刺さっていると、そのノードが適用される。

参照サイト

Allow Material Overrideを有効にすると、マテリアルごとにSurfaceOptionsの値を変更できる。


参照サイト

Multplyを使用した累乗と、Powerを使用した累乗は、Multplyの方が速度が速い。


参照サイト

0から1にする場合、SaturateとClampはSaturateの方が一部のGPUでは何かの処理についでにやっており早いため、なるべくSaturateを使用する方が良い。


参照サイト

Swizzleを使用すると簡素的にノードを書ける

以下の結果は同じで、Swizzleの方が簡単にノードを書ける

参照サイト

ノードの値を数値化して確認する

まずこちらのGithubをダウンロードをする。
Float to Labelというノードを検索する。Valueに確認したいノードを入力すると数値を確認できる。

参照サイト

ShaderGraphでキャラクターシェーダを作成する

BaseMap、拡散反射光(ノーマルマップと頂点の法線をブレンドした結果と光線ベクトルの内積)、落ち影のカラー、ライトのカラー、環境光の反映。
https://youtu.be/H3msD0eiQ_4?feature=shared&t=582
SmoothStepを使用した簡易的なトゥーン表現。
https://youtu.be/H3msD0eiQ_4?feature=shared&t=994
Saturateではなく、Remapを使用して陰影をソフトにする。
(Saturateだと0より小さい値は0になるが、Remapだと-0.5でも0にはならないので陰影がソフトになる)
https://youtu.be/H3msD0eiQ_4?feature=shared&t=1042
陰影をつけずに、周りのライティングに浮かないようにする方法。
https://youtu.be/H3msD0eiQ_4?feature=shared&t=1113
落ち影の不自然さとライトの強度が高いことによる白飛びを防ぐ。
https://youtu.be/H3msD0eiQ_4?feature=shared&t=1170

RedenrFutureとSahderGraphを使用してCustom Post Effectを作成する

ポストエフェクトのシェーダー作成する際、動画だとUnliShaderで作成しているが、2022.3.19だと上手く反映できていなかった。
FullScreenShaderGraphで試したところ上手くできた。

Custom Post Effect作成

https://youtu.be/H3msD0eiQ_4?feature=shared&t=1371
_CameraColorTextureでポストエフェクトがかかる前のカメラに写っているテクスチャを取得し、ポスタライザ化しているポストエフェクト

スクリーンスペース座標の1テクセルずらしたものと、もとの距離を求めてそれをOneMinusを使用してアウトラインを作成している。

画用紙に書いたハッチングテクスチャをUnityArtEngineでシームレステクスチャにする

https://youtu.be/H3msD0eiQ_4?feature=shared&t=1983

エナジーボールとトルネードを作成する

ソフトパーティクルの接触判定 エナジーボール

https://youtu.be/7ToExWKVZW0?feature=shared&t=384
EyeのScene Depthは正規化されていない深度バッファ。
RawのScreen Postionのw成分は、マテリアルをアタッチしているオブジェクトまでの距離。
Scene DepthからScreen Postion引けばオブジェクト同士が接触しているところは黒くなる。

黒くなる

グレー



このあたりの考え方は、水のシェーダを作成するときにも使用する。
https://zenn.dev/clay_andromeda/articles/clay-water-shader-series-01

Fresnel Effectノードを使用せずにフレネス表現を実装 エナジーボール

https://youtu.be/7ToExWKVZW0?feature=shared&t=753
まず法線と視線ベクトルの内積を求める

その際注意することは、絶対値(Absolute)にしてからOneMinusで行わないと両面描画しているのでうまくフレネス表現できない。
絶対値処理なし

絶対値処理あり

Fresnel Effectノードは両面描画を考慮されていないので、以下のようになるため今回は使用していない。

模様をつける エナジーボール

https://youtu.be/7ToExWKVZW0?feature=shared&t=1053

歪みをつける エナジーボール

https://youtu.be/7ToExWKVZW0?feature=shared&t=1200
OpaqueTextureを有効にして、不透明オブジェクトの描画結果のテクスチャ取得し、これを歪ませる。

ShaderGraphでOpaqueTexture使用する際は、Refrenceに_CameraOpaqueTextureを入力すると取得できる。

ScreenPositionとTwirlとSample Texture 2Dを使用することである程度歪みの表現はできる。

実際のエフェクトでは、GradientNoiseをとTimeとTilling And Offsetを利用して歪みを与えている。
https://youtu.be/N2uT7eFdS2k
なお、ShaderGraphは2パス以上かけないので、Materailを複数アタッチして歪みを表現する。

歪みの表現は、
すりがらすや、クリスタル、水流
蜃気楼やポータル
武器をスイングしたときの空間の歪み
などいろいろな表現方法で使用できる
また、ノーマルマップと組み合わせることも可能。

UVスクロール トルネード

https://youtu.be/7ToExWKVZW0?feature=shared&t=1706
CheckerboardでUVの状態を確認できる。

Alpha Clip Threshoudを調整してUVスクロールを行う。
https://youtu.be/H0JigIb6-ww
ただ、上だけUVスクロールさせたいので以下のノードを追加
https://youtu.be/YzXYkFM-Ygo

Vertex Colorのアルファを取得して、Color over LifeTimeに沿って描画のタイミング調整 トルネード

https://youtu.be/7ToExWKVZW0?feature=shared&t=1948
Partclesystemで設定したColorは、Vertex Colorノードで取得できるので、これを利用してColor over LifeTimeに沿って描画のタイミング調整する。
https://youtu.be/nSzkXZqGaRc

ノイズを与える トルネード

https://youtu.be/7ToExWKVZW0?feature=shared&t=2021

Gradient NoiseとSimple NoiseとVoronoiはシームレステクスチャでない トルネード

https://youtu.be/7ToExWKVZW0?feature=shared&t=2103
シームレステクスチャにするには以下の記事を参考にするとよい。
https://qiita.com/yuji_yasuhara/items/c593d402b88f9ffa14a7

頂点アニメーションで動きを加える トルネード

https://youtu.be/7ToExWKVZW0?feature=shared&t=2263
アニメーションパターン1
SineとCosineを合成するパターンとしないパターンを比較してみた。
合成した方がたつまきっぽさがあるように思える。
https://youtu.be/L_HRu8s1BOg
赤枠のY軸のワールド座標にしている理由について述べる。

以下の動画みると、Y軸のワールド座標は常に一定なのでどの頂点も同じ動きする。
もし、X軸のワールド座標にすると座標がばらばらなのでばらばらな動きになる。
https://youtu.be/YbXkE6290m4
赤枠のUVとワールド空間のPositionの挙動の違い

UVの場合オブジェクトの角度が変わっても同じ動きをするが、ワールド空間のPositionだと角度が変わるとアニメーション挙動が変わっていることが分かる。
ワールド空間のPositionだと角度が変わるとPositionが変わるためである。
UVだと角度変わってもUVの値を参照するためアニメーション変わらない。
https://youtu.be/pHUTCTfKGqA
アニメーションパターン2
NormalVectorの値を使用して頂点アニメーションしているのがみそ。
https://youtu.be/9Y1pzRBN9Ig

カスタムエフェクトを作成する

https://www.youtube.com/watch?v=AQGgwgo51lo&t=0s
https://www.youtube.com/watch?v=Ylq2y6Qez3s&t=0s
https://www.youtube.com/watch?v=E_oDKQU3e94&t=0s
https://www.youtube.com/watch?v=7x-NM_QIoeY&t=0s

ScriptableRenderPassとScriptableRendererFeatureのコードを書く

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

namespace UrpTestbed
{

    sealed class PostEffectPass : ScriptableRenderPass
    {
        public Material material;

        //実際に処理を実行。
        //具体的には、すべてレンダリングした後に、マテリアル(シェーダ)の処理を行った後、その結果をRTに描きこみ画面に表示する
        public override void Execute
          (ScriptableRenderContext context, ref RenderingData data)
        {
            if (material == null) return;
            // コマンドバッファの生成(Frame DebuggerでPostEffectのパスが表示される)
            var cmd = CommandBufferPool.Get("PostEffect");
            /*URP12から追加されたSwapBuffer機能で、
            以前は一時的なレンダーテクスチャなどが必要であったがこれのおかげで簡単にBlitの処理ができるようになった。
            */
            Blit(cmd, ref data, material, 0);
            // コマンドバッファを実行
            context.ExecuteCommandBuffer(cmd);
            // コマンドバッファを解放
            CommandBufferPool.Release(cmd);
        }
    }

    public sealed class PostEffectFeature : ScriptableRendererFeature
    {
        public Material material;

        PostEffectPass _pass;

        // パスを生成する
        public override void Create()
        {
            // すべてレンダリングした後に指定したマテリアルを適用
            _pass = new PostEffectPass
            {
                material = material,
                renderPassEvent = RenderPassEvent.AfterRendering
            };
        }

        // パスをレンダリングパイプラインに追加
        public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData data)
        {   
            renderer.EnqueuePass(_pass);
        }

    }
}

参照サイト

上のRendererFeatureを追加し、カスタムエフェクトのマテリアルをアタッチする

ネガのポストエフェクト

実際の結果

全体のノード

ポストエフェクトをかける前の画面に描画されているレンダーテクスチャは、Referenceで_MainTexと記載することで取得できる。

なお、Colorspace Conversionで色空間の処理がないと以下のように白飛びしたようになる。

この処理についてあまり自信がないが、
Linear→RGBの処理は、RTは画面に描画されるものなので人間の目で見たものなのでリニアではなく、sRGBにする必要がある。(Color SpaceがLiner)
RGB→Linearの処理は、逆ガンマ補正かけないと明るくのでこの処理を入れていると思われる。

モノクロのポストエフェクト

実際の結果
https://youtu.be/zfS0-umOtPg

VHSノイズのポストエフェクト

実際の結果
https://youtu.be/e_5Crepovqo
RTのUVをずらしてあげればVHSのエフェクトが作成できる。

Gradient NoiseにUVのG成分をUVとして接続すれば横の縞々ができるので、これをTime使用してAddしていくことで横にノイズっぽい表現できる。
https://youtu.be/jFJsz3GA8oo
ただ、これだとノイズが強すぎるので、Gradient Noiseを使用してノイズの強度を調整していく。
その際、累乗を行うことでたまにノイズが入るようになり緩急が出てVHSっぽさを出すことができる。
https://youtu.be/pWuT5ezgk1c

場面転換のポストエフェクト

実際の結果
https://youtu.be/gmLQC8PaSxs

フルスクリーンエフェクト

ポストエフェクトなどか作成するときは、上の例ようにScriptableRenderPassとScriptableRendererFeatureのコードを書く必要があったが、フルスクリーンエフェクトはその必要がなくなった。
https://www.youtube.com/watch?v=7Cd7kQl6N50

FullScreenのShaderGraphを用意する


URPSampleBufferでRTのテクスチャを取得できる

Renderer FutureにFull Screen Pass Renderer Featureを追加する

実際の結果

UIシェーダを作成

https://www.youtube.com/watch?v=PV195gBqxKA

Canvas Shader Graphを作成

注意点

・頂点シェーダーを使用できない
・ライティングができない
・UIアニメーションする際は、スクリプトを使用するかサードパーティー製を使用する。
スクリプトの場合は、IMaterialModifierを継承してGetModifiedMaterialメソッドでプロパティのReferenceを変更する。
サードパーティー製は以下を使用するのがおすすめ。
https://assetstore.unity.com/packages/2d/gui/animate-ui-materials-253197

パワーゲージUI作成

https://youtu.be/9OP6s5RFNkQ?feature=shared&t=1642

PhotoShopなどでグラデーションの画像作成する

ShaderGraphでゲージ処理を実装

現在の状態だと、Floatの値が大きくなるにつれてゲージがなくなっていくのでそれを逆にする。

Remapで1-0にすれば解決する。

ただ、Stepだと下記のようにジャギるのでSmoothStepを使用する。

SmoothStepを使用した結果。ジャギがなくなっている。

PhotoShopなどでカラーグラデーションの画像作成する

PhotoShopでゲージにカラーつけるテクスチャを作成する。

ShaderGraphでゲージのカラーをつける

https://youtu.be/8Uf46IDXhS4

PhotoShopなどでブラーやアウトラインのある画像を作成する

ShaderGraphでブラーやアウトライン画像を合成する

Addで合成を行う。

プロパティにカテゴリーをつける

ShaderGraph

マテリアル

Use Tilling and offsetでTillingとOffset機能を追加する

ShaderGraph

マテリアル

ディストーションのしくみ

何も手を加えていないチェッカーテクスチャ

ディストーションの効果あり

グラデーションマップが中央にいくにつれて、値が大きくなり、その分UVが多く足されていくので

実際の見た目も真ん中がよく歪んでいることが分かる。

sRGBオンオフによるディストーションマップなどの違い

リニア空間(Color SpaceがLiner)の時は、ディストーションマップなどデータとしてエフェクトの挙動変える場合、sRGBを無効にした方が正しい挙動になる。
sRGB無効

sRGB有効

上の例は、グラデーションのテクスチャを使用してuvを変化させディストーションの効果を出している。sRGB有効の場合は、ガンマ補正がかかるため正しい見た目になっていない。
なので、エフェクトで使用するテクスチャはsRGBを無効にしたほうが正しい挙動になる。
ただ、ガンマ空間(Color SpaceがGanma)の場合は、sRGB有効無効でもシェーダ計算後にガンマ補正がかかるのでどちらの設定でも変わらない。
sRGB無効

sRGB有効

Absoluteを使用して、テクスチャのマイナスの箇所を特定する

ノーマルマップは-1~1の範囲を取る。
Absoluteの黒から白くなった部分はもともとマイナスだった部分である。

画面のオブジェクトを歪ませる


事前準備として
・Opaque Textureを有効
・SurfaceTypeをTransparentにする
Scene Colorで不透明のオブジェクトが描画された後のテクスチャを取得して、法線マップによって歪ませている。

テクスチャのパーツごとに色を分ける

以下のように、シェーダのプロパティでテクスチャのパーツごとに色を分ける。
https://youtu.be/A_Orfihc9Ok
まず、PhotoShopやAEなどで、テクスチャのパーツごとにRGBに分ける。

シェーダー側で、RGBごとに取得して合成する。

モデルの境界値を境に頂点アニメーションを行う

参照サイトのp497
モデルの原点から0.75まので距離を境に頂点アニメーションしている。
https://youtu.be/jgHWeuX6DGw

テクスチャのWrap ModeのよるRepeatとClampの違い

https://youtu.be/xgG61ti4W58

Vector3でパターンを切り替える

https://youtu.be/NynRAsimu98
なお、以下のようにSplitすり理由は

Patternを(0,1,0)にすると、値がキャストされxのみが値がに反映されて意図しない結果になる。
なので、Splitで分けてそれをAddすることでVector3でパターンを切り替えることができる。

Tilling And Offsetでノイズテクスチャを引き延ばす

ノイズテクスチャ

Tilling And Offsetでノイズテクスチャを引き延ばす

UVごとのUVアニメーションの違い

https://youtu.be/vE-3ihhCNZk

頂点アルファを適用させる

頂点アルファをいじったモデル

Shader側の対応

Node接続あり

Node接続なし

Node接続ありだと、モデルの端が頂点アルファの影響で薄くなっていることがわかる。

Unity Grenobleでタイリング可能なシームレステクスチャ作成可能

参照サイト参照サイト

LerpやElipseやNormal from Heightなどを駆使して目玉作成する

https://youtu.be/wxmmfyiK46c

頂点カラーで頂点アニメーションを制御する

https://youtu.be/0Lt0LkuhZXs

頂点カラーで色を制御する

https://youtu.be/-hrhnljPNDE

Discussion