ここでのパーティーには少し遅れましたが、私はあなたが探しているものを正確に実行するCSSカスタムフィルターを作成しました。すべてのコードは、GitHubのhttps://github.com/awgreenblatt/css-custom-filters/tree/master/duotoneにあります。
セキュリティ上の制限により、カスタムフィルターはピクセルを読み取ることができません。それらにのみ変換を適用できます。したがって、たとえば、フィルタは、ピクセルが黒の場合、それを赤に変更することを言うことができません。ただし、それを行う方法はまだあります。
各色成分の範囲は[0,1]です。ソース画像のすべての白いピクセルは(1、1、1、1)になり、ソース画像のすべての黒いピクセルは(0、0、0、1)になります。
黒をマップする色を(br、bg、bb、1)と呼び、白をマップする色を(wr、wg、wb、1)と呼びましょう。
フラグメントシェーダーで、ソース画像に変換を適用するcss_ColorMatrixを定義できます。ブレンドモードを「乗算」に設定すると、css_ColorMatrixは現在のソース画像の色で事前に乗算されます。
したがって、css_ColorMatrixを次のように設定します。
wr - br, 0, 0, 0,
0, wg - bg, 0, 0,
0, 0, wb - bb, 0,
br, bg, bb, 1
ソースピクセルが黒(0、0、0、1)の場合、乗算の結果は(br、bg、bb、1)になります。ソースピクセルが白(1、1、1、1)の場合、乗算の結果は次のようになります
((wr-br + br)、(wg-bg + bg)、(wb-bb + bb)、1)または(wr、wg、wb、1)
フラグメントシェーダーのソースは次のとおりです。
precision mediump float;
uniform vec3 black;
uniform vec3 white;
// Main
void main()
{
vec3 b = black / 255.0;
vec3 w = white / 255.0;
css_ColorMatrix = mat4(w.r-b.r, 0.0, 0.0, 0.0,
0.0, w.g - b.g, 0.0, 0.0,
0.0, 0.0, w.b - b.b, 0.0,
b.r, b.g, b.b, 1.0);
}
頂点シェーダーはデフォルトです。
precision mediump float;
// Built-in attributes
attribute vec4 a_position;
// Built-in uniforms
uniform mat4 u_projectionMatrix;
// Main
void main()
{
gl_Position = u_projectionMatrix * a_position;
}
そして、次のようにフィルターを適用します。
-webkit-filter: custom(url(duotone.vs) mix(url(duotone.fs) normal source-atop),
1 1 border-box, black 255 0 0, white 255 192 203);