Skip to content

Instantly share code, notes, and snippets.

@isuzu-shiranui
Created November 26, 2022 19:16
Show Gist options
  • Save isuzu-shiranui/2694e4367d5afcfc3e069f3187cc337d to your computer and use it in GitHub Desktop.
Save isuzu-shiranui/2694e4367d5afcfc3e069f3187cc337d to your computer and use it in GitHub Desktop.
PhotoShopのレイヤー合成モード
// -------------------- //
// Normal
// 通常
float3 BlendNormal(float3 a, float3 b)
{
return b;
}
// -------------------- //
// Darkening
// 比較(暗)
float3 BlendDarken(float3 a, float3 b)
{
return min(a, b);
}
// 乗算
float3 BlendMultiply(float3 a, float3 b)
{
return a * b;
}
float BlendColorBurn(float a, float b)
{
return a >= 1.0 ? 1.0 : b <= 0.0 ? 0.0 : 1.0 - min(1.0, (1.0 - a) / b);
}
// 焼きこみカラー
float3 BlendColorBurn(float3 a, float3 b)
{
return float3(BlendColorBurn(a.r, b.r),
BlendColorBurn(a.g, b.g),
BlendColorBurn(a.b, b.b));
}
// 焼きこみ(リニア)
float3 BlendLinearBurn(float3 a, float3 b)
{
return max(0.0, a + b - 1.0);
}
// カラー比較(暗)
float3 BlendDarkerColor(float3 a, float3 b)
{
return a.r + a.g + a.b < b.r + b.g + b.b ? a : b;
}
// -------------------- //
// Lightening
// 比較(明)
float3 BlendLighten(float3 a, float3 b)
{
return max(a, b);
}
// スクリーン
float3 BlendScreen(float3 a, float3 b)
{
return a + b - a * b;
}
float BlendColorDodge(float a, float b)
{
return a <= 0.0 ? 0.0 : b >= 1.0 ? 1.0 : min(1.0, a / (1.0 - b));
}
// 覆い焼きカラー
float3 BlendColorDodge(float3 a, float3 b)
{
return float3(BlendColorDodge(a.r, b.r),
BlendColorDodge(a.g, b.g),
BlendColorDodge(a.b, b.b));
}
// 覆い焼き(リニア) - 加算
float3 BlendLinearColorDodge(float3 a, float3 b)
{
return a + b;
}
// カラー比較(明)
float3 BlendLighterColor(float3 a, float3 b)
{
return a.r + a.g + a.b > b.r + b.g + b.b ? a : b;
}
// -------------------- //
// Contrast
float BlendOverlay(float a, float b)
{
return b < 0.5 ? 2.0 * a * b : 1.0 - 2.0 * (1.0 - a) * (1.0 - b);
}
// オーバーレイ
float3 BlendOverlay(float3 a, float3 b)
{
return float3(BlendOverlay(a.r, b.r),
BlendOverlay(a.g, b.g),
BlendOverlay(a.b, b.b));
}
float BlendSoftLight(float a, float b)
{
return a < 0.5 ? b - (1.0 - 2.0 * a) * b * (1.0 - b)
: b < 0.25 ? b + (2.0 * a - 1.0) * b * ((16.0 * b - 12.0) * b + 3.0)
: b + (2.0 * a - 1.0) * (sqrt(b) - b);
}
// ソフトライト
float3 BlendSoftLight(float3 a, float3 b)
{
return float3(BlendSoftLight(a.r, b.r),
BlendSoftLight(a.g, b.g),
BlendSoftLight(a.b, b.b));
}
float BlendHardLight(float a, float b)
{
return a < 0.5 ? 2.0 * a * b : 1.0 - 2.0 * (1.0 - a) * (1.0 - b);
}
// ハードライト
float3 BlendHardLight(float3 a, float3 b)
{
return float3(BlendHardLight(a.r, b.r),
BlendHardLight(a.g, b.g),
BlendHardLight(a.b, b.b));
}
float BlendVividLight(float a, float b)
{
return a < 0.5 ? 1.0 - (1.0 - b) / (2.0 * a) : b / (2.0 * (1.0 - a));
}
// ビビッドライト
float3 BlendVividLight(float3 a, float3 b)
{
return float3(BlendVividLight(a.r, b.r),
BlendVividLight(a.g, b.g),
BlendVividLight(a.b, b.b));
}
// リニアライト
float3 BlendLinearLight(float3 a, float3 b)
{
return 2.0 * a + b - 1.0;
}
float BlendPinLight(float a, float b)
{
return 2.0 * a - 1.0 > b ? 2.0 * a - 1.0 : a < 0.5 * b ? 2.0 * a : b;
}
// ピンライト
float3 BlendPinLight(float3 a, float3 b)
{
return float3(BlendPinLight(a.r, b.r),
BlendPinLight(a.g, b.g),
BlendPinLight(a.b, b.b));
}
// ハードミックス
float3 BlendHardMix(float3 a, float3 b)
{
return floor(a + b);
}
// -------------------- //
// Inversion
// 差の絶対値
float3 BlendDifference(float3 a, float3 b)
{
return abs(b - a);
}
// 除外
float3 BlendExclusion(float3 a, float3 b)
{
return a + b - 1.0 * a * b;
}
// Cancellation
// 減算
float3 BlendSubtract(float3 a, float3 b)
{
return a - b;
}
// 除算
float3 BlendDivide(float3 a, float3 b)
{
return a / b;
}
// -------------------- //
// Component
float3 HUEtoRGB(in float H)
{
float R = abs(H * 6 - 3) - 1;
float G = 2 - abs(H * 6 - 2);
float B = 2 - abs(H * 6 - 4);
return saturate(float3(R, G, B));
}
float3 RGBtoHCV(in float3 RGB)
{
float4 P = (RGB.g < RGB.b) ? float4(RGB.bg, -1.0, 2.0 / 3.0) : float4(RGB.gb, 0.0, -1.0 / 3.0);
float4 Q = (RGB.r < P.x) ? float4(P.xyw, RGB.r) : float4(RGB.r, P.yzx);
float C = Q.x - min(Q.w, Q.y);
float H = abs((Q.w - Q.y) / (6 * C + 1e-10) + Q.z);
return float3(H, C, Q.x);
}
float3 RGBtoHSV(in float3 RGB)
{
float3 HCV = RGBtoHCV(RGB);
float S = HCV.y / (HCV.z + 1e-10);
return float3(HCV.x, S, HCV.z);
}
float3 HSVtoRGB(in float3 HSV)
{
return ((HUEtoRGB(HSV.x) - 1) * HSV.y + 1) * HSV.z;
}
// 色相
float3 BlendHue(float3 a, float3 b)
{
b = RGBtoHSV(b);
b.r = RGBtoHSV(a).r;
return HSVtoRGB(b);
}
// 彩度
float3 BlendSaturation(float3 a, float3 b)
{
b = RGBtoHSV(b);
b.g = RGBtoHSV(a).g;
return HSVtoRGB(b);
}
// カラー
float3 BlendColor(float3 a, float3 b)
{
b = RGBtoHSV(b);
b.b = RGBtoHSV(a).b;
return HSVtoRGB(b);
}
// 輝度
float3 BlendLuminosity(float3 a, float3 b)
{
float dLum = dot(b, float3(0.3, 0.59, 0.11));
float sLum = dot(a, float3(0.3, 0.59, 0.11));
float lum = sLum - dLum;
float3 c = b + lum;
float minC = min(min(c.x, c.y), c.z);
float maxC = max(max(c.x, c.y), c.z);
if(minC < 0.0) return sLum + (c - sLum) * sLum / (sLum - minC);
if(maxC > 1.0) return sLum + (c - sLum) * (1.0 - sLum) / (maxC - sLum);
return c;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment