前回の記事で使用したPhotoshop のカラー合成の式をHLSL化したコードを使用していましたが
記事が長すぎてその部分の解説ができませんでした。
現在コードが掲載されていたリンク先が落ちてしまっているようなのでコードだけ転載します。
もとがライブラリ.hファイルなので 下の方の関数は上のほうを参照していますので Shader内に記述するときは
上から下への並びを入れ替えずに書き加えて下さい。
デザイナーさんからPhotoshopと同じカラー合成モードの見た目をお願いされることも多々あると思いますので
そんな場面にも使用してみるといいかと思います。
●ソースリンク先
http://www.pegtop.net/delphi/articles/blendmodes/
http://blog.mouaif.org/2009/01/05/photoshop-math-with-glsl-shaders/
■ Desaturate (彩度を下げる)
| float4 Desaturate(float3 color, float Desaturation) { float3 grayXfer = float3(0.3, 0.59, 0.11); float grayf = dot(grayXfer, color); float3 gray = float3(grayf, grayf, grayf); return float4(lerp(color, gray, Desaturation), 1.0); } |
■ RGBToHSL (RGB値 からHSL値(色相・彩度・明度)に変換)
| float3 RGBToHSL(float3 color) hsl.z = (fmax + fmin) / 2.0; // Luminance if (delta == 0.0) //This is a gray, no chroma... if (color.r == fmax ) if (hsl.x < 0.0) return hsl; |
■ HueToRGB(色相からRGB値を計算)
| float HueToRGB(float f1, float f2, float hue) |
■ HSLToRGB(HSL値 からRGBに変換)
| float3 HSLToRGB(float3 hsl) |
■コントラスト・彩度・明度 の調整
| float3 ContrastSaturationBrightness(float3 color, float brt, float sat, float con) { // Increase or decrease theese values to adjust r, g and b color channels seperately const float AvgLumR = 0.5; const float AvgLumG = 0.5; const float AvgLumB = 0.5; const float3 LumCoeff = float3(0.2125, 0.7154, 0.0721); float3 AvgLumin = float3(AvgLumR, AvgLumG, AvgLumB); float3 brtColor = color * brt; float intensityf = dot(brtColor, LumCoeff); float3 intensity = float3(intensityf, intensityf, intensityf); float3 satColor = lerp(intensity, brtColor, sat); float3 conColor = lerp(AvgLumin, satColor, con); return conColor; } |
■ カラー合成モードいろいろ
1. Photoshopのカラー合成モードを再現した式のファンクション定義
| #define BlendLinearDodgef BlendAddf #define BlendLinearBurnf BlendSubstractf #define BlendAddf(base, blend) min(base + blend, 1.0) #define BlendSubstractf(base, blend) max(base + blend - 1.0, 0.0) #define BlendLightenf(base, blend) max(blend, base) #define BlendDarkenf(base, blend) min(blend, base) #define BlendLinearLightf(base, blend) (blend < 0.5 ? BlendLinearBurnf(base, (2.0 * blend)) : BlendLinearDodgef(base, (2.0 * (blend - 0.5)))) #define BlendScreenf(base, blend) (1.0 - ((1.0 - base) * (1.0 - blend))) #define BlendOverlayf(base, blend) (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend))) #define BlendSoftLightf(base, blend) ((blend < 0.5) ? (2.0 * base * blend + base * base * (1.0 - 2.0 * blend)) : (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend))) #define BlendColorDodgef(base, blend) ((blend == 1.0) ? blend : min(base / (1.0 - blend), 1.0)) #define BlendColorBurnf(base, blend) ((blend == 0.0) ? blend : max((1.0 - ((1.0 - base) / blend)), 0.0)) #define BlendVividLightf(base, blend) ((blend < 0.5) ? BlendColorBurnf(base, (2.0 * blend)) : BlendColorDodgef(base, (2.0 * (blend - 0.5)))) #define BlendPinLightf(base, blend) ((blend < 0.5) ? BlendDarkenf(base, (2.0 * blend)) : BlendLightenf(base, (2.0 *(blend - 0.5)))) #define BlendHardMixf(base, blend) ((BlendVividLightf(base, blend) < 0.5) ? 0.0 : 1.0) #define BlendReflectf(base, blend) ((blend == 1.0) ? blend : min(base * base / (1.0 - blend), 1.0)) |
2. 1を使用したカラーブレンド式の定義 Shader式に組み込むにはこちらをつかいます
| #define Blend(base, blend, funcf) float3(funcf(base.r, blend.r), funcf(base.g, blend.g), funcf(base.b, blend.b)) #define BlendNormal(base, blend) (base) #define BlendLinearLight(base, blend) Blend(base, blend, BlendLinearLightf) #define BlendVividLight(base, blend) Blend(base, blend, BlendVividLightf) |
■色相のブレンド
| float3 BlendHue(float3 base, float3 blend) { float3 baseHSL = RGBToHSL(base); return HSLToRGB(float3(RGBToHSL(blend).r, baseHSL.g, baseHSL.b)); } |
■彩度のブレンド
| float3 BlendSaturation(float3 base, float3 blend) { float3 baseHSL = RGBToHSL(base); return HSLToRGB(float3(baseHSL.r, RGBToHSL(blend).g, baseHSL.b)); } |
■カラーのブレンド
| float3 BlendColor(float3 base, float3 blend) { float3 blendHSL = RGBToHSL(blend); return HSLToRGB(float3(blendHSL.r, blendHSL.g, RGBToHSL(base).b)); } |
■明度のブレンド
| float3 BlendLuminosity(float3 base, float3 blend) { float3 baseHSL = RGBToHSL(base); return HSLToRGB(float3(baseHSL.r, baseHSL.g, RGBToHSL(blend).b)); } |