Remove unused blends.
This commit is contained in:
parent
b2baeb3882
commit
2701130dbf
1 changed files with 2 additions and 210 deletions
|
@ -66,214 +66,6 @@ proc `-`*(c: Color, v: float32): Color {.inline.} =
|
|||
result.b = c.b - v
|
||||
result.a = c.a - v
|
||||
|
||||
proc mix*(blendMode: BlendMode, target, blend: Color): Color =
|
||||
|
||||
if blendMode == bmMask:
|
||||
result.r = target.r
|
||||
result.g = target.g
|
||||
result.b = target.b
|
||||
result.a = min(target.a, blend.a)
|
||||
return
|
||||
elif blendMode == bmSubtractMask:
|
||||
result.r = target.r
|
||||
result.g = target.g
|
||||
result.b = target.b
|
||||
result.a = target.a * (1 - blend.a)
|
||||
return
|
||||
elif blendMode == bmIntersectMask:
|
||||
result.r = target.r
|
||||
result.g = target.g
|
||||
result.b = target.b
|
||||
result.a = target.a * blend.a
|
||||
return
|
||||
elif blendMode == bmExcludeMask:
|
||||
result.r = target.r
|
||||
result.g = target.g
|
||||
result.b = target.b
|
||||
result.a = abs(target.a - blend.a)
|
||||
return
|
||||
elif blendMode == bmOverwrite:
|
||||
result = blend
|
||||
return
|
||||
|
||||
proc multiply(Cb, Cs: float32): float32 =
|
||||
Cb * Cs
|
||||
|
||||
proc screen(Cb, Cs: float32): float32 =
|
||||
1 - (1 - Cb) * (1 - Cs)
|
||||
|
||||
proc hardLight(Cb, Cs: float32): float32 =
|
||||
if Cs <= 0.5: multiply(Cb, 2 * Cs)
|
||||
else: screen(Cb, 2 * Cs - 1)
|
||||
|
||||
# Here are 4 implementations of soft light, none of them are quite right.
|
||||
|
||||
# proc softLight(Cb, Cs: float32): float32 =
|
||||
# ## W3C
|
||||
# proc D(cb: float32): float32 =
|
||||
# if Cb <= 0.25:
|
||||
# ((16 * Cb - 12) * Cb + 4) * Cb
|
||||
# else:
|
||||
# sqrt(Cb)
|
||||
# if Cs <= 0.5:
|
||||
# return Cb - (1 - 2 * Cs) * Cb * (1 - Cb)
|
||||
# else:
|
||||
# return Cb + (2 * Cs - 1) * (D(Cb) - Cb)
|
||||
|
||||
# proc softLight(a, b: float32): float32 =
|
||||
# ## Photoshop
|
||||
# if b < 0.5:
|
||||
# 2 * a * b + a ^ 2 * (1 - 2 * b)
|
||||
# else:
|
||||
# 2 * a * (1 - b) + sqrt(a) * (2 * b - 1)
|
||||
|
||||
proc softLight(a, b: float32): float32 =
|
||||
## Pegtop
|
||||
(1 - 2 * b) * a ^ 2 + 2 * b * a
|
||||
|
||||
# proc softLight(a, b: float32): float32 =
|
||||
# ## Illusions.hu
|
||||
# pow(a, pow(2, (2 * (0.5 - b))))
|
||||
|
||||
proc Lum(C: Color): float32 =
|
||||
0.3 * C.r + 0.59 * C.g + 0.11 * C.b
|
||||
|
||||
proc ClipColor(C: Color): Color =
|
||||
let
|
||||
L = Lum(C)
|
||||
n = min([C.r, C.g, C.b])
|
||||
x = max([C.r, C.g, C.b])
|
||||
var
|
||||
C = C
|
||||
if n < 0:
|
||||
C = L + (((C - L) * L) / (L - n))
|
||||
if x > 1:
|
||||
C = L + (((C - L) * (1 - L)) / (x - L))
|
||||
return C
|
||||
|
||||
proc SetLum(C: Color, l: float32): Color =
|
||||
let
|
||||
d = l - Lum(C)
|
||||
result.r = C.r + d
|
||||
result.g = C.g + d
|
||||
result.b = C.b + d
|
||||
return ClipColor(result)
|
||||
|
||||
proc Sat(C: Color): float32 =
|
||||
max([C.r, C.g, C.b]) - min([C.r, C.g, C.b])
|
||||
|
||||
proc SetSat(C: Color, s: float32): Color =
|
||||
var arr = [(C.r, 0), (C.g, 1), (C.b, 2)]
|
||||
# TODO: Don't rely on sort.
|
||||
arr.sort()
|
||||
var
|
||||
Cmin = arr[0][0]
|
||||
Cmid = arr[1][0]
|
||||
Cmax = arr[2][0]
|
||||
if Cmax > Cmin:
|
||||
Cmid = (((Cmid - Cmin) * s) / (Cmax - Cmin))
|
||||
Cmax = s
|
||||
else:
|
||||
Cmid = 0
|
||||
Cmax = 0
|
||||
Cmin = 0
|
||||
|
||||
if arr[0][1] == 0:
|
||||
result.r = Cmin
|
||||
if arr[1][1] == 0:
|
||||
result.r = Cmid
|
||||
if arr[2][1] == 0:
|
||||
result.r = Cmax
|
||||
|
||||
if arr[0][1] == 1:
|
||||
result.g = Cmin
|
||||
if arr[1][1] == 1:
|
||||
result.g = Cmid
|
||||
if arr[2][1] == 1:
|
||||
result.g = Cmax
|
||||
|
||||
if arr[0][1] == 2:
|
||||
result.b = Cmin
|
||||
if arr[1][1] == 2:
|
||||
result.b = Cmid
|
||||
if arr[2][1] == 2:
|
||||
result.b = Cmax
|
||||
|
||||
proc blendChannel(blendMode: BlendMode, Cb, Cs: float32): float32 =
|
||||
result = case blendMode
|
||||
of bmNormal: Cs
|
||||
of bmDarken: min(Cb, Cs)
|
||||
of bmMultiply: multiply(Cb, Cs)
|
||||
of bmLinearBurn: Cb + Cs - 1
|
||||
of bmColorBurn:
|
||||
if Cb == 1: 1.0
|
||||
elif Cs == 0: 0.0
|
||||
else: 1.0 - min(1, (1 - Cb) / Cs)
|
||||
of bmLighten: max(Cb, Cs)
|
||||
of bmScreen: screen(Cb, Cs)
|
||||
of bmLinearDodge: Cb + Cs
|
||||
of bmColorDodge:
|
||||
if Cb == 0: 0.0
|
||||
elif Cs == 1: 1.0
|
||||
else: min(1, Cb / (1 - Cs))
|
||||
of bmOverlay: hardLight(Cs, Cb)
|
||||
of bmHardLight: hardLight(Cb, Cs)
|
||||
of bmSoftLight: softLight(Cb, Cs)
|
||||
of bmDifference: abs(Cb - Cs)
|
||||
of bmExclusion: Cb + Cs - 2 * Cb * Cs
|
||||
else: 0.0
|
||||
let Cb = target
|
||||
let Cs = blend
|
||||
|
||||
var mixed: Color
|
||||
if blendMode == bmColor:
|
||||
mixed = SetLum(Cs, Lum(Cb))
|
||||
elif blendMode == bmLuminosity:
|
||||
mixed = SetLum(Cb, Lum(Cs))
|
||||
elif blendMode == bmHue:
|
||||
mixed = SetLum(SetSat(Cs, Sat(Cb)), Lum(Cb))
|
||||
elif blendMode == bmSaturation:
|
||||
mixed = SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb))
|
||||
else:
|
||||
mixed.r = blendMode.blendChannel(Cb.r, Cs.r)
|
||||
mixed.g = blendMode.blendChannel(Cb.g, Cs.g)
|
||||
mixed.b = blendMode.blendChannel(Cb.b, Cs.b)
|
||||
|
||||
let ab = Cb.a
|
||||
let As = Cs.a
|
||||
result.r = As * (1 - ab) * Cs.r + As * ab * mixed.r + (1 - As) * ab * Cb.r
|
||||
result.g = As * (1 - ab) * Cs.g + As * ab * mixed.g + (1 - As) * ab * Cb.g
|
||||
result.b = As * (1 - ab) * Cs.b + As * ab * mixed.b + (1 - As) * ab * Cb.b
|
||||
|
||||
result.a = (blend.a + target.a * (1.0 - blend.a))
|
||||
result.r /= result.a
|
||||
result.g /= result.a
|
||||
result.b /= result.a
|
||||
|
||||
proc mix*(blendMode: BlendMode, dest, src: ColorRGBA): ColorRGBA {.inline.} =
|
||||
blendMode.mix(dest.color, src.color).rgba
|
||||
|
||||
# TODO: Fix fast paths
|
||||
# if blendMode == Normal:
|
||||
# # Fast pass
|
||||
# # target * (1 - blend.a) + blend * blend.a
|
||||
# if target.a == 0: return blend
|
||||
# let blendAComp = 255 - blend.a
|
||||
# result.r = ((target.r.uint16 * blendAComp + blend.r.uint16 * blend.a) div 255).uint8
|
||||
# result.g = ((target.g.uint16 * blendAComp + blend.g.uint16 * blend.a) div 255).uint8
|
||||
# result.b = ((target.b.uint16 * blendAComp + blend.b.uint16 * blend.a) div 255).uint8
|
||||
# result.a = (blend.a.uint16 + (target.a.uint16 * blendAComp) div 255).uint8
|
||||
# inc blendCount
|
||||
# elif blendMode == Mask:
|
||||
# result.r = target.r
|
||||
# result.g = target.g
|
||||
# result.b = target.b
|
||||
# result.a = min(target.a, blend.a)
|
||||
# elif blendMode == COPY:
|
||||
# result = target
|
||||
# else:
|
||||
# return blendMode.mix(target.color, blend.color).rgba
|
||||
|
||||
proc screen(Cb, Cs: float32): float32 {.inline.} =
|
||||
1 - (1 - Cb) * (1 - Cs)
|
||||
|
||||
|
@ -501,7 +293,7 @@ proc blendExcludeMask(target, blend: Color): Color {.inline.} =
|
|||
proc blendOverwrite(target, blend: Color): Color {.inline.} =
|
||||
result = blend
|
||||
|
||||
proc mix2*(blendMode: BlendMode, dest, src: Color): Color {.inline.} =
|
||||
proc mix*(blendMode: BlendMode, dest, src: Color): Color {.inline.} =
|
||||
case blendMode
|
||||
of bmNormal: blendNormal(dest, src)
|
||||
of bmDarken: blendDarken(dest, src)
|
||||
|
@ -619,7 +411,7 @@ proc blendExcludeMask*(a, b: ColorRGBA): ColorRGBA =
|
|||
proc blendOverwrite*(a, b: ColorRGBA): ColorRGBA =
|
||||
blendOverwrite(a.color, b.color).rgba
|
||||
|
||||
proc mix2*(blendMode: BlendMode, dest, src: ColorRGBA): ColorRGBA {.inline.} =
|
||||
proc mix*(blendMode: BlendMode, dest, src: ColorRGBA): ColorRGBA {.inline.} =
|
||||
case blendMode
|
||||
of bmNormal: blendNormal(dest, src)
|
||||
of bmDarken: blendDarken(dest, src)
|
||||
|
|
Loading…
Reference in a new issue