Skip to content

Commit

Permalink
[Impeller] Move color-only blending functions and utilities into the …
Browse files Browse the repository at this point in the history
…shader library (flutter#35111)
  • Loading branch information
bdero authored Aug 3, 2022
1 parent a1e77ae commit bb862a2
Show file tree
Hide file tree
Showing 19 changed files with 230 additions and 144 deletions.
2 changes: 1 addition & 1 deletion ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ FILE: ../../../flutter/impeller/compiler/reflector.cc
FILE: ../../../flutter/impeller/compiler/reflector.h
FILE: ../../../flutter/impeller/compiler/runtime_stage_data.cc
FILE: ../../../flutter/impeller/compiler/runtime_stage_data.h
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/blending.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/branching.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/color.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/constants.glsl
Expand Down Expand Up @@ -614,7 +615,6 @@ FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_overlay.f
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_saturation.frag
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_screen.frag
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_softlight.frag
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_utils.glsl
FILE: ../../../flutter/impeller/entity/shaders/blending/blend.frag
FILE: ../../../flutter/impeller/entity/shaders/blending/blend.vert
FILE: ../../../flutter/impeller/entity/shaders/border_mask_blur.frag
Expand Down
193 changes: 193 additions & 0 deletions impeller/compiler/shader_lib/impeller/blending.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BLENDING_GLSL_
#define BLENDING_GLSL_

#include <impeller/branching.glsl>
#include <impeller/constants.glsl>

//------------------------------------------------------------------------------
/// HSV utilities.
///

float IPLuminosity(vec3 color) {
return color.r * 0.3 + color.g * 0.59 + color.b * 0.11;
}

/// Scales the color's luma by the amount necessary to place the color
/// components in a 1-0 range.
vec3 IPClipColor(vec3 color) {
float lum = IPLuminosity(color);
float mn = min(min(color.r, color.g), color.b);
float mx = max(max(color.r, color.g), color.b);
// `lum - mn` and `mx - lum` will always be >= 0 in the following conditions,
// so adding a tiny value is enough to make these divisions safe.
if (mn < 0) {
color = lum + (((color - lum) * lum) / (lum - mn + kEhCloseEnough));
}
if (mx > 1) {
color = lum + (((color - lum) * (1 - lum)) / (mx - lum + kEhCloseEnough));
}
return color;
}

vec3 IPSetLuminosity(vec3 color, float luminosity) {
float relative_lum = luminosity - IPLuminosity(color);
return IPClipColor(color + relative_lum);
}

float IPSaturation(vec3 color) {
return max(max(color.r, color.g), color.b) -
min(min(color.r, color.g), color.b);
}

vec3 IPSetSaturation(vec3 color, float saturation) {
float mn = min(min(color.r, color.g), color.b);
float mx = max(max(color.r, color.g), color.b);
return (mn < mx) ? ((color - mn) * saturation) / (mx - mn) : vec3(0);
}

//------------------------------------------------------------------------------
/// Color blend functions.
///
/// These routines take two unpremultiplied RGB colors and output a third color.
/// They can be combined with any alpha compositing operation. When these blend
/// functions are used for drawing Entities in Impeller, the output is always
/// applied to the destination using `SourceOver` alpha compositing.
///

vec3 IPBlendScreen(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingscreen
return dst + src - (dst * src);
}

vec3 IPBlendHardLight(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendinghardlight
return IPVec3Choose(dst * (2 * src), IPBlendScreen(dst, 2 * src - 1), src);
}

vec3 IPBlendOverlay(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingoverlay
// HardLight, but with reversed parameters.
return IPBlendHardLight(src, dst);
}

vec3 IPBlendDarken(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingdarken
return min(dst, src);
}

vec3 IPBlendLighten(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendinglighten
return max(dst, src);
}

vec3 IPBlendColorDodge(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingcolordodge

vec3 color = min(vec3(1), dst / (1 - src));

if (dst.r < kEhCloseEnough) {
color.r = 0;
}
if (dst.g < kEhCloseEnough) {
color.g = 0;
}
if (dst.b < kEhCloseEnough) {
color.b = 0;
}

if (1 - src.r < kEhCloseEnough) {
color.r = 1;
}
if (1 - src.g < kEhCloseEnough) {
color.g = 1;
}
if (1 - src.b < kEhCloseEnough) {
color.b = 1;
}

return color;
}

vec3 IPBlendColorBurn(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingcolorburn

vec3 color = 1 - min(vec3(1), (1 - dst) / src);

if (1 - dst.r < kEhCloseEnough) {
color.r = 1;
}
if (1 - dst.g < kEhCloseEnough) {
color.g = 1;
}
if (1 - dst.b < kEhCloseEnough) {
color.b = 1;
}

if (src.r < kEhCloseEnough) {
color.r = 0;
}
if (src.g < kEhCloseEnough) {
color.g = 0;
}
if (src.b < kEhCloseEnough) {
color.b = 0;
}

return color;
}

vec3 IPBlendSoftLight(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingsoftlight

vec3 D = IPVec3ChooseCutoff(((16 * dst - 12) * dst + 4) * dst, //
sqrt(dst), //
dst, //
0.25);

return IPVec3Choose(dst - (1 - 2 * src) * dst * (1 - dst), //
dst + (2 * src - 1) * (D - dst), //
src);
}

vec3 IPBlendDifference(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingdifference
return abs(dst - src);
}

vec3 IPBlendExclusion(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingexclusion
return dst + src - 2 * dst * src;
}

vec3 IPBlendMultiply(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingmultiply
return dst * src;
}

vec3 IPBlendHue(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendinghue
return IPSetLuminosity(IPSetSaturation(src, IPSaturation(dst)),
IPLuminosity(dst));
}

vec3 IPBlendSaturation(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingsaturation
return IPSetLuminosity(IPSetSaturation(dst, IPSaturation(src)),
IPLuminosity(dst));
}

vec3 IPBlendColor(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingcolor
return IPSetLuminosity(src, IPLuminosity(dst));
}

vec3 IPBlendLuminosity(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingluminosity
return IPSetLuminosity(dst, IPLuminosity(src));
}

#endif
2 changes: 1 addition & 1 deletion impeller/entity/shaders/blending/advanced_blend.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <impeller/branching.glsl>
#include <impeller/blending.glsl>
#include <impeller/color.glsl>
#include <impeller/texture.glsl>

Expand Down
5 changes: 2 additions & 3 deletions impeller/entity/shaders/blending/advanced_blend_color.frag
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "advanced_blend_utils.glsl"
#include <impeller/blending.glsl>

vec3 Blend(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingcolor
return SetLuminosity(src, Luminosity(dst));
return IPBlendColor(dst, src);
}

#include "advanced_blend.glsl"
24 changes: 2 additions & 22 deletions impeller/entity/shaders/blending/advanced_blend_colorburn.frag
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "advanced_blend_utils.glsl"
#include <impeller/blending.glsl>

vec3 Blend(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingcolorburn
vec3 color = 1 - min(vec3(1), (1 - dst) / src);
if (1 - dst.r < kEhCloseEnough) {
color.r = 1;
}
if (1 - dst.g < kEhCloseEnough) {
color.g = 1;
}
if (1 - dst.b < kEhCloseEnough) {
color.b = 1;
}
if (src.r < kEhCloseEnough) {
color.r = 0;
}
if (src.g < kEhCloseEnough) {
color.g = 0;
}
if (src.b < kEhCloseEnough) {
color.b = 0;
}
return color;
return IPBlendColorBurn(dst, src);
}

#include "advanced_blend.glsl"
24 changes: 2 additions & 22 deletions impeller/entity/shaders/blending/advanced_blend_colordodge.frag
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "advanced_blend_utils.glsl"
#include <impeller/blending.glsl>

vec3 Blend(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingcolordodge
vec3 color = min(vec3(1), dst / (1 - src));
if (dst.r < kEhCloseEnough) {
color.r = 0;
}
if (dst.g < kEhCloseEnough) {
color.g = 0;
}
if (dst.b < kEhCloseEnough) {
color.b = 0;
}
if (1 - src.r < kEhCloseEnough) {
color.r = 1;
}
if (1 - src.g < kEhCloseEnough) {
color.g = 1;
}
if (1 - src.b < kEhCloseEnough) {
color.b = 1;
}
return color;
return IPBlendColorDodge(dst, src);
}

#include "advanced_blend.glsl"
5 changes: 3 additions & 2 deletions impeller/entity/shaders/blending/advanced_blend_darken.frag
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <impeller/blending.glsl>

vec3 Blend(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingdarken
return min(dst, src);
return IPBlendDarken(dst, src);
}

#include "advanced_blend.glsl"
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <impeller/blending.glsl>

vec3 Blend(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingdifference
return abs(dst - src);
return IPBlendDifference(dst, src);
}

#include "advanced_blend.glsl"
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <impeller/blending.glsl>

vec3 Blend(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingexclusion
return dst + src - 2 * dst * src;
return IPBlendExclusion(dst, src);
}

#include "advanced_blend.glsl"
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "advanced_blend_utils.glsl"
#include <impeller/blending.glsl>

vec3 Blend(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendinghardlight
return BlendHardLight(dst, src);
return IPBlendHardLight(dst, src);
}

#include "advanced_blend.glsl"
5 changes: 2 additions & 3 deletions impeller/entity/shaders/blending/advanced_blend_hue.frag
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "advanced_blend_utils.glsl"
#include <impeller/blending.glsl>

vec3 Blend(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendinghue
return SetLuminosity(SetSaturation(src, Saturation(dst)), Luminosity(dst));
return IPBlendHue(dst, src);
}

#include "advanced_blend.glsl"
5 changes: 3 additions & 2 deletions impeller/entity/shaders/blending/advanced_blend_lighten.frag
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <impeller/blending.glsl>

vec3 Blend(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendinglighten
return max(dst, src);
return IPBlendLighten(dst, src);
}

#include "advanced_blend.glsl"
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "advanced_blend_utils.glsl"
#include <impeller/blending.glsl>

vec3 Blend(vec3 dst, vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingluminosity
return SetLuminosity(dst, Luminosity(src));
return IPBlendLuminosity(dst, src);
}

#include "advanced_blend.glsl"
Loading

0 comments on commit bb862a2

Please sign in to comment.