ゲーム作りは楽しい

なんか書く

レイヤー合成、計算式メモ

随時更新するかも

スクリーン

float screen(float dest, float src)
{
    return 1 - (1 - dest) * (1 - src);
}
float4 screen(float4 dest, float4 src)
{
    float4 color;
    color.r = screen(dest.r, src.r);
    color.g = screen(dest.g, src.g);
    color.b = screen(dest.b, src.b);
    color.a = 1.0;
    return color;
}

オーバーレイ

float overlay(float dest, float src)
{
    return dest < 0.5 ? 2.0 * dest * src : 1.0 - 2.0 * (1 - dest) * (1 - src);

}
float4 overlay(float4 dest, float4 src)
{
    float4 color;
    color.r = overlay(dest.r, src.r);
    color.g = overlay(dest.g, src.g);
    color.b = overlay(dest.b, src.b);
    color.a = 1.0;
    return color;
}

ソフトライト

float softlight(float dest, float src)
{
    return src < 0.5 ? 2.0 * dest * src + dest * dest * (1.0 - 2.0 * src) : 2.0 * dest * (1 - src) + sqrt(dest) * (2 * src - 1.0);
}
float4 softlight(float4 dest, float4 src)
{
    float4 color;
    color.r = softlight(dest.r, src.r);
    color.g = softlight(dest.g, src.g);
    color.b = softlight(dest.b, src.b);
    color.a = 1.0;
    return color;
}

or

float softlight(float dest, float src)
{
    return src < 0.5 ? pow(dest, 2.0 * (1.0- src)) :pow(dest, 1.0 / (2.0 * src)); 
}
float4 softlight(float4 dest, float4 src)
{
    float4 color;
    color.r = softlight(dest.r, src.r);
    color.g = softlight(dest.g, src.g);
    color.b = softlight(dest.b, src.b);
    color.a = 1.0;
    return color;
}

ハードライト

float hardLight(float dest, float src)
{
    return src < 0.5 ? dest * src * 2.0: 1 - 2 * (1 - dest) * (1 - src);
}
float4 hardLight(float4 dest, float4 src)
{
    float4 color;
    color.r = hardLight(dest.r, src.r);
    color.g = hardLight(dest.g, src.g);
    color.b = hardLight(dest.b, src.b);
    color.a = 1.0;
    return color;
}

焼きこみ

float colorBurn(float dest, float src)
{
    return src <= 0 ? 0 : 1 - (1 - dest) / src;
}
float4 colorBurn(float4 dest, float4 src)
{
    float4 color;
    color.r = colorBurn(dest.r, src.r);
    color.g = colorBurn(dest.g, src.g);
    color.b = colorBurn(dest.b, src.b);
    color.a = 1;
    return color;
}

覆い焼き

float colorDodge(float dest, float src)
{
    return src >= 1 ? 1 : dest / (1 - src);
}
float4 colorDodge(float4 dest, float4 src)
{
    float4 color;
    color.r = colorDodge(dest.r, src.r);
    color.g = colorDodge(dest.g, src.g);
    color.b = colorDodge(dest.b, src.b);
    color.a = 1;
    return color;
}

ビビッドライト

float vividLight(float dest, float src)
{
    return src < 0.5 ? colorBurn(dest, 2 * src) : colorDodge(dest, 2 * (src - 0.5));
}
float4 vividLight(float4 dest, float4 src)
{
    float4 color;
    color.r = vividLight(dest.r, src.r);
    color.g = vividLight(dest.g, src.g);
    color.b = vividLight(dest.b, src.b);
    color.a = 1.0;
    return color;
}

参考

osakana.factory - ブレンドモード詳説

[CG] 描画モードについて - CG/CG概論

Python3 & OpenCV で画像処理を学ぶ[5] 〜 AfterEffects/Photoshopにある描画モードを実装する - Optie研