しののめ研究所

プログラムとかシェーダーとか本とかについて書いていきます

shaderでよく使う計算

自分用にまとめてます 思いついたら更新していく

よく使う計算

テクスチャカラーの値から小数点第一位のみ取得

テクスチャカラーの値なので 0 ~ 1 の幅という想定

float color.r = TextureColor.r;
color.r = floor(color.r * 10) / 10;

一度10倍してから整数のみを返すfloor関数を呼び出す その後、10で割る ゴリ押しなのでもっといい方法を知りたい

「0 ~ 1」 → 「-1 ~ 1」 に変換

x = y * 2 - 1
  • y = 0 の時
    • 0 * 2 - 1 = -1
  • y = 0.5の時
    • 0.5 * 2 - 1 = 0
  • y = 1の時
    • 1 * 2 - 1 = 1

他の値でも同じように置換したい場合は x = y * 2 - yの最大値 と考える

「-1 ~ 1」 → 「0 ~ 1」に変換

x = y * 0.5 + 0.5
  • y = -1の時
    • -1 * 0.5 + 0.5 = 0
  • y = 0 の時
    • 0 * 0.5 + 0.5 = 0.5
  • y = 1の時
    • 1 * 0.5 + 0.5 = 1

他の値でも同じように置換したい場合は x = y * 0.5 + (yの最大値 * 0.5) と考える

「 1 」に変換

x = y * 0 + 1.0f

全てのカラーを白にしたい場合

「 0 」に変換

x = y * 0

カラーを黒にしたい場合

頂点から入力されたUV座標を 「移動」 「拡大縮小」 する

uv = float2(
  (inputUV.x - uvPosition.x) * 0.5f / uvSize + 0.5f,
  (inputUV.y - uvPosition.y) * 0.5f / uvSize + 0.5f
);

色の平均値を求める

ただの平均の求め方 平均を求めてくれる関数があった気がするけど思い出せない

averageColor = (R + B + G) / 3

Flip処理

uv.x = abs(input.uv.x * 2 - 1);

UV座標を -1 ~ 1 に変換して絶対値を求める するとUV座標が 1 ~ 0 ~ 1 に変換されていく

テクスチャの着色

fixed lum = Luminance(outColor.rgb); 
outColor.rgb = lerp(_BlackColor.rgb, _WhiteColor.rgb, lum);

lumはグレースケール化しているだけなので 以下の計算方法でも同じカラーを取得できる

outColor.rgb = dot(outColor.rgb, fixed3(0.3, 0.6, 0.1));

よく使う関数

abs

絶対値を返す 割と使いやすい

y = abs(x)

sqrt

平方根を返す 極座標計算などで使える

y = sqrt(x)

sin

sin波を返す cosの方が使いやすい

y = sin(x)

cos

cos波を返す アルファフェードはこっちの方が使いやすい

y = cos(x)

wrapのrepeatを使わずにrepatする

入力された値に対して 1.0 で割った結果のうりあまりを返す

uv = frac(uv);

wrapのrepeatを使わずにrepatしながら間隔を一定に開けたい

x = 入れたい値 fmodでxの値で割ったあまりを返してくれる

uv = fmod(uv, x);

ブレンドモード

加算

OutColor = A + B

減算

OutColor = A - B

乗算

OutColor = A * B

スクリーン

OutColor = 1 - ((1 - A) * ( 1 - B))

マスク画像を元にAとBの画像をブレンド

OutColor = lerp(A, B, Mask);

マスク画像の特定のカラーチャンネルのみにスクリーン合成をベースに画像を合成

OutColor = lerp(A, 1 - ((1 - A) * ( 1 - B)), maskChannel)

アニメーション

uvスクロール

uv.x += _Time.y * uvScroll.x * uvVector.x
uv.y += _Time.y * uvScroll.y * uvVector.y

波形を利用したフェードインフェードアウト

sin波かcos波を利用してフェードアニメーションを行う sin波だと0スタートの[-1 ~ 1] cos波だと1スタートの[-1 ~ 1] y = x * 0.5f + 0.5f の計算式を利用して[0 ~ 1]に変換する

alpha *= cos(_Time.y * fadeTime) * 0.5f + 0.5f

簡易的にグラデーションをつくる

右へのグラデーション

color.rgb = uv.x;

左へのグラデーション

color.rgb = 1 - uv.x;

上へのグラデーション

color.rgb = uv.y;

下へのグラデーション

color.rgb = 1 - uv.y;