[gtk+] vulkan: Implement nonseparable blendmodes
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] vulkan: Implement nonseparable blendmodes
- Date: Sat, 23 Sep 2017 13:17:08 +0000 (UTC)
commit 3c98b90fc61de21efd22cc37bf8a1e64c5142835
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Sep 23 08:59:06 2017 -0400
vulkan: Implement nonseparable blendmodes
This is a directly-from-the-spec, unoptimized implementation.
gsk/gskvulkanrenderpass.c | 5 -
.../vulkan/blendmode-clip-rounded.frag.spv | Bin 22744 -> 32700 bytes
gsk/resources/vulkan/blendmode-clip.frag.spv | Bin 15972 -> 25928 bytes
gsk/resources/vulkan/blendmode.frag | 127 +++++++++++++++++++-
gsk/resources/vulkan/blendmode.frag.spv | Bin 15972 -> 25928 bytes
5 files changed, 125 insertions(+), 7 deletions(-)
---
diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c
index 3f9c7aa..fe11872 100644
--- a/gsk/gskvulkanrenderpass.c
+++ b/gsk/gskvulkanrenderpass.c
@@ -186,11 +186,6 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
FALLBACK ("Unsupported node '%s'\n", node->node_class->type_name);
case GSK_BLEND_NODE:
- if (gsk_blend_node_get_blend_mode (node) == GSK_BLEND_MODE_COLOR ||
- gsk_blend_node_get_blend_mode (node) == GSK_BLEND_MODE_HUE ||
- gsk_blend_node_get_blend_mode (node) == GSK_BLEND_MODE_SATURATION ||
- gsk_blend_node_get_blend_mode (node) == GSK_BLEND_MODE_LUMINOSITY)
- FALLBACK ("Nonseparable blend modes not implemented\n");
if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds))
pipeline_type = GSK_VULKAN_PIPELINE_BLEND_MODE;
else if (constants->clip.type == GSK_VULKAN_CLIP_RECT)
diff --git a/gsk/resources/vulkan/blendmode-clip-rounded.frag.spv
b/gsk/resources/vulkan/blendmode-clip-rounded.frag.spv
index 4ede20e..b204175 100644
Binary files a/gsk/resources/vulkan/blendmode-clip-rounded.frag.spv and
b/gsk/resources/vulkan/blendmode-clip-rounded.frag.spv differ
diff --git a/gsk/resources/vulkan/blendmode-clip.frag.spv b/gsk/resources/vulkan/blendmode-clip.frag.spv
index 21484c8..e3e681d 100644
Binary files a/gsk/resources/vulkan/blendmode-clip.frag.spv and
b/gsk/resources/vulkan/blendmode-clip.frag.spv differ
diff --git a/gsk/resources/vulkan/blendmode.frag b/gsk/resources/vulkan/blendmode.frag
index 803a538..4e448ac 100644
--- a/gsk/resources/vulkan/blendmode.frag
+++ b/gsk/resources/vulkan/blendmode.frag
@@ -10,7 +10,7 @@ layout(location = 3) flat in uint inBlendMode;
layout(set = 0, binding = 0) uniform sampler2D startTexture;
layout(set = 1, binding = 0) uniform sampler2D endTexture;
-layout(location = 0) out vec4 color;
+layout(location = 0) out vec4 outColor;
vec3
multiply (vec3 source, vec3 backdrop, float opacity)
@@ -135,6 +135,121 @@ exclusion (vec3 source, vec3 backdrop, float opacity)
}
float
+lum (vec3 c)
+{
+ return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;
+}
+
+vec3
+clip_color (vec3 c)
+{
+ float l = lum (c);
+ float n = min (c.r, min (c.g, c.b));
+ float x = max (c.r, max (c.g, c.b));
+ if (n < 0) c = l + (((c - l) * l) / (l - n));
+ if (x > 1) c = l + (((c - l) * (1 - l)) / (x - l));
+ return c;
+}
+
+vec3
+set_lum (vec3 c, float l)
+{
+ float d = l - lum (c);
+ return clip_color (vec3 (c.r + d, c.g + d, c.b + d));
+}
+
+float
+sat (vec3 c)
+{
+ return max (c.r, max (c.g, c.b)) - min (c.r, min (c.g, c.b));
+}
+
+vec3
+set_sat (vec3 c, float s)
+{
+ float cmin = min (c.r, min (c.g, c.b));
+ float cmax = max (c.r, max (c.g, c.b));
+ vec3 res;
+
+ if (cmax == cmin)
+ res = vec3 (0, 0, 0);
+ else
+ {
+ if (c.r == cmax)
+ {
+ if (c.g == cmin)
+ {
+ res.b = ((c.b - cmin) * s) / (cmax - cmin);
+ res.g = 0;
+ }
+ else
+ {
+ res.g = ((c.g - cmin) * s) / (cmax - cmin);
+ res.b = 0;
+ }
+ res.r = s;
+ }
+ else if (c.g == cmax)
+ {
+ if (c.r == cmin)
+ {
+ res.b = ((c.b - cmin) * s) / (cmax - cmin);
+ res.r = 0;
+ }
+ else
+ {
+ res.r = ((c.r - cmin) * s) / (cmax - cmin);
+ res.b = 0;
+ }
+ res.g = s;
+ }
+ else
+ {
+ if (c.r == cmin)
+ {
+ res.g = ((c.g - cmin) * s) / (cmax - cmin);
+ res.r = 0;
+ }
+ else
+ {
+ res.r = ((c.r - cmin) * s) / (cmax - cmin);
+ res.g = 0;
+ }
+ res.b = s;
+ }
+ }
+ return res;
+}
+
+vec3
+color (vec3 source, vec3 backdrop, float opacity)
+{
+ vec3 result = set_lum (source, lum (backdrop));
+ return mix (source, result, opacity);
+}
+
+vec3
+hue (vec3 source, vec3 backdrop, float opacity)
+{
+ vec3 result = set_lum (set_sat (source, sat (backdrop)), lum (backdrop));
+ return mix (source, result, opacity);
+}
+
+vec3
+saturation (vec3 source, vec3 backdrop, float opacity)
+{
+ vec3 result = set_lum (set_sat (backdrop, sat (source)), lum (backdrop));
+ return mix (source, result, opacity);
+}
+
+vec3
+luminosity (vec3 source, vec3 backdrop, float opacity)
+{
+ vec3 result = set_lum (backdrop, lum (source));
+ return mix (source, result, opacity);
+}
+
+float
combine (float source, float backdrop)
{
return source + backdrop * (1 - source);
@@ -176,8 +291,16 @@ void main()
rgb = difference (source.rgb, backdrop.rgb, backdrop.a);
else if (inBlendMode == 11)
rgb = exclusion (source.rgb, backdrop.rgb, backdrop.a);
+ else if (inBlendMode == 12)
+ rgb = color (source.rgb, backdrop.rgb, backdrop.a);
+ else if (inBlendMode == 13)
+ rgb = hue (source.rgb, backdrop.rgb, backdrop.a);
+ else if (inBlendMode == 14)
+ rgb = saturation (source.rgb, backdrop.rgb, backdrop.a);
+ else if (inBlendMode == 15)
+ rgb = luminosity (source.rgb, backdrop.rgb, backdrop.a);
else
discard;
- color = clip (inPos, vec4 (rgb, a));
+ outColor = clip (inPos, vec4 (rgb, a));
}
diff --git a/gsk/resources/vulkan/blendmode.frag.spv b/gsk/resources/vulkan/blendmode.frag.spv
index 21484c8..e3e681d 100644
Binary files a/gsk/resources/vulkan/blendmode.frag.spv and b/gsk/resources/vulkan/blendmode.frag.spv differ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]