From c96cb62f472221c0eb0f67b1ba201d62e733487d Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 24 Feb 2020 19:42:32 -0800 Subject: [PATCH] Factor out common functions used in tile alpha shaders --- resources/shaders/gl3/tile_alpha.fs.glsl | 44 ++++++++++++-- resources/shaders/gl3/tile_alpha_hsl.fs.glsl | 58 +++++++++++++------ resources/shaders/metal/tile_alpha.fs.metal | 17 ++++-- .../shaders/metal/tile_alpha_hsl.fs.metal | 51 ++++++++++------ shaders/Makefile | 1 + shaders/tile_alpha.fs.glsl | 18 ++---- shaders/tile_alpha_hsl.fs.glsl | 30 +++------- shaders/tile_alpha_sample.inc.glsl | 37 ++++++++++++ 8 files changed, 176 insertions(+), 80 deletions(-) create mode 100644 shaders/tile_alpha_sample.inc.glsl diff --git a/resources/shaders/gl3/tile_alpha.fs.glsl b/resources/shaders/gl3/tile_alpha.fs.glsl index 8c3253b7..eafe14f2 100644 --- a/resources/shaders/gl3/tile_alpha.fs.glsl +++ b/resources/shaders/gl3/tile_alpha.fs.glsl @@ -12,22 +12,54 @@ +#extension GL_GOOGLE_include_directive : enable + precision highp float; +out vec4 oFragColor; + + + + + + + + + + + + uniform sampler2D uStencilTexture; uniform sampler2D uPaintTexture; +uniform sampler2D uDest; uniform vec2 uFramebufferSize; in vec2 vColorTexCoord; in vec2 vMaskTexCoord; -out vec4 oFragColor; -void main(){ +vec4 sampleSrcColor(){ float coverage = texture(uStencilTexture, vMaskTexCoord). r; - vec4 color = texture(uPaintTexture, vColorTexCoord); - color . a *= coverage; - color . rgb *= color . a; - oFragColor = color; + vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord); + return vec4(srcRGBA . rgb, srcRGBA . a * coverage); +} + +vec4 sampleDestColor(){ + vec2 destTexCoord = gl_FragCoord . xy / uFramebufferSize; + return texture(uDest, destTexCoord); +} + + +vec4 blendColors(vec4 destRGBA, vec4 srcRGBA, vec3 blendedRGB){ + return vec4(srcRGBA . a *(1.0 - destRGBA . a)* srcRGBA . rgb + + srcRGBA . a * destRGBA . a * blendedRGB + + (1.0 - srcRGBA . a)* destRGBA . a * destRGBA . rgb, + 1.0); +} + + +void main(){ + vec4 srcRGBA = sampleSrcColor(); + oFragColor = vec4(srcRGBA . rgb * srcRGBA . a, srcRGBA . a); } diff --git a/resources/shaders/gl3/tile_alpha_hsl.fs.glsl b/resources/shaders/gl3/tile_alpha_hsl.fs.glsl index b8c8e2f9..1502c033 100644 --- a/resources/shaders/gl3/tile_alpha_hsl.fs.glsl +++ b/resources/shaders/gl3/tile_alpha_hsl.fs.glsl @@ -14,21 +14,54 @@ #extension GL_GOOGLE_include_directive : enable - - - precision highp float; +uniform ivec3 uBlendHSL; + +out vec4 oFragColor; + + + + + + + + + + + + uniform sampler2D uStencilTexture; uniform sampler2D uPaintTexture; uniform sampler2D uDest; -uniform ivec3 uBlendHSL; uniform vec2 uFramebufferSize; in vec2 vColorTexCoord; in vec2 vMaskTexCoord; -out vec4 oFragColor; + +vec4 sampleSrcColor(){ + float coverage = texture(uStencilTexture, vMaskTexCoord). r; + vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord); + return vec4(srcRGBA . rgb, srcRGBA . a * coverage); +} + +vec4 sampleDestColor(){ + vec2 destTexCoord = gl_FragCoord . xy / uFramebufferSize; + return texture(uDest, destTexCoord); +} + + +vec4 blendColors(vec4 destRGBA, vec4 srcRGBA, vec3 blendedRGB){ + return vec4(srcRGBA . a *(1.0 - destRGBA . a)* srcRGBA . rgb + + srcRGBA . a * destRGBA . a * blendedRGB + + (1.0 - srcRGBA . a)* destRGBA . a * destRGBA . rgb, + 1.0); +} + + + + @@ -65,12 +98,8 @@ vec3 convertRGBToHSL(vec3 rgb){ } void main(){ - float coverage = texture(uStencilTexture, vMaskTexCoord). r; - vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord); - srcRGBA . a *= coverage; - - vec2 destTexCoord = gl_FragCoord . xy / uFramebufferSize; - vec4 destRGBA = texture(uDest, destTexCoord); + vec4 srcRGBA = sampleSrcColor(); + vec4 destRGBA = sampleDestColor(); vec3 destHSL = convertRGBToHSL(destRGBA . rgb); vec3 srcHSL = convertRGBToHSL(srcRGBA . rgb); @@ -80,11 +109,6 @@ void main(){ blendDest . z ? destHSL . z : srcHSL . z); vec3 blendedRGB = convertHSLToRGB(blendedHSL); - - vec4 color = vec4(srcRGBA . a *(1.0 - destRGBA . a)* srcRGBA . rgb + - srcRGBA . a * destRGBA . a * blendedRGB + - (1.0 - srcRGBA . a)* destRGBA . a * destRGBA . rgb, - 1.0); - oFragColor = color; + oFragColor = blendColors(destRGBA, srcRGBA, blendedRGB); } diff --git a/resources/shaders/metal/tile_alpha.fs.metal b/resources/shaders/metal/tile_alpha.fs.metal index 7c54f4b7..600fa493 100644 --- a/resources/shaders/metal/tile_alpha.fs.metal +++ b/resources/shaders/metal/tile_alpha.fs.metal @@ -1,4 +1,6 @@ // Automatically generated from files in pathfinder/shaders/. Do not edit! +#pragma clang diagnostic ignored "-Wmissing-prototypes" + #include #include @@ -23,15 +25,18 @@ struct main0_in float2 vMaskTexCoord [[user(locn1)]]; }; +float4 sampleSrcColor(thread texture2d uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord) +{ + float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x; + float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord); + return float4(srcRGBA.xyz, srcRGBA.w * coverage); +} + fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]]) { main0_out out = {}; - float coverage = spvDescriptorSet0.uStencilTexture.sample(spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord).x; - float4 color = spvDescriptorSet0.uPaintTexture.sample(spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord); - color.w *= coverage; - float3 _41 = color.xyz * color.w; - color = float4(_41.x, _41.y, _41.z, color.w); - out.oFragColor = color; + float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord); + out.oFragColor = float4(srcRGBA.xyz * srcRGBA.w, srcRGBA.w); return out; } diff --git a/resources/shaders/metal/tile_alpha_hsl.fs.metal b/resources/shaders/metal/tile_alpha_hsl.fs.metal index 473c598b..bdd73bf8 100644 --- a/resources/shaders/metal/tile_alpha_hsl.fs.metal +++ b/resources/shaders/metal/tile_alpha_hsl.fs.metal @@ -36,6 +36,19 @@ Tx mod(Tx x, Ty y) return x - y * floor(x / y); } +float4 sampleSrcColor(thread texture2d uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord) +{ + float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x; + float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord); + return float4(srcRGBA.xyz, srcRGBA.w * coverage); +} + +float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d uDest, thread const sampler uDestSmplr) +{ + float2 destTexCoord = gl_FragCoord.xy / uFramebufferSize; + return uDest.sample(uDestSmplr, destTexCoord); +} + float3 convertRGBToHSL(thread const float3& rgb) { float v = fast::max(rgb.y, rgb.z); @@ -77,51 +90,55 @@ float3 convertHSLToRGB(thread const float3& hsl) return hsl.zzz - (fast::clamp(fast::min(ks - float3(3.0), float3(9.0) - ks), float3(-1.0), float3(1.0)) * a); } +float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA, thread const float3& blendedRGB) +{ + return float4(((srcRGBA.xyz * (srcRGBA.w * (1.0 - destRGBA.w))) + (blendedRGB * (srcRGBA.w * destRGBA.w))) + (destRGBA.xyz * ((1.0 - srcRGBA.w) * destRGBA.w)), 1.0); +} + fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], float4 gl_FragCoord [[position]]) { main0_out out = {}; - float coverage = spvDescriptorSet0.uStencilTexture.sample(spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord).x; - float4 srcRGBA = spvDescriptorSet0.uPaintTexture.sample(spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord); - srcRGBA.w *= coverage; - float2 destTexCoord = gl_FragCoord.xy / (*spvDescriptorSet0.uFramebufferSize); - float4 destRGBA = spvDescriptorSet0.uDest.sample(spvDescriptorSet0.uDestSmplr, destTexCoord); + float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord); + float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr); float3 param = destRGBA.xyz; float3 destHSL = convertRGBToHSL(param); float3 param_1 = srcRGBA.xyz; float3 srcHSL = convertRGBToHSL(param_1); bool3 blendDest = (*spvDescriptorSet0.uBlendHSL) == int3(0); - float _225; + float _281; if (blendDest.x) { - _225 = destHSL.x; + _281 = destHSL.x; } else { - _225 = srcHSL.x; + _281 = srcHSL.x; } - float _236; + float _292; if (blendDest.y) { - _236 = destHSL.y; + _292 = destHSL.y; } else { - _236 = srcHSL.y; + _292 = srcHSL.y; } - float _247; + float _303; if (blendDest.z) { - _247 = destHSL.z; + _303 = destHSL.z; } else { - _247 = srcHSL.z; + _303 = srcHSL.z; } - float3 blendedHSL = float3(_225, _236, _247); + float3 blendedHSL = float3(_281, _292, _303); float3 param_2 = blendedHSL; float3 blendedRGB = convertHSLToRGB(param_2); - float4 color = float4(((srcRGBA.xyz * (srcRGBA.w * (1.0 - destRGBA.w))) + (blendedRGB * (srcRGBA.w * destRGBA.w))) + (destRGBA.xyz * ((1.0 - srcRGBA.w) * destRGBA.w)), 1.0); - out.oFragColor = color; + float4 param_3 = destRGBA; + float4 param_4 = srcRGBA; + float3 param_5 = blendedRGB; + out.oFragColor = blendColors(param_3, param_4, param_5); return out; } diff --git a/shaders/Makefile b/shaders/Makefile index 68c1b1fe..4a27276c 100644 --- a/shaders/Makefile +++ b/shaders/Makefile @@ -33,6 +33,7 @@ SHADERS=\ INCLUDES=\ filter_text_convolve.inc.glsl \ filter_text_gamma_correct.inc.glsl \ + tile_alpha_sample.inc.glsl \ $(EMPTY) OUT=\ diff --git a/shaders/tile_alpha.fs.glsl b/shaders/tile_alpha.fs.glsl index 5ad53198..dbb498c4 100644 --- a/shaders/tile_alpha.fs.glsl +++ b/shaders/tile_alpha.fs.glsl @@ -10,21 +10,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#extension GL_GOOGLE_include_directive : enable + precision highp float; -uniform sampler2D uStencilTexture; -uniform sampler2D uPaintTexture; -uniform vec2 uFramebufferSize; - -in vec2 vColorTexCoord; -in vec2 vMaskTexCoord; - out vec4 oFragColor; +#include "tile_alpha_sample.inc.glsl" + void main() { - float coverage = texture(uStencilTexture, vMaskTexCoord).r; - vec4 color = texture(uPaintTexture, vColorTexCoord); - color.a *= coverage; - color.rgb *= color.a; - oFragColor = color; + vec4 srcRGBA = sampleSrcColor(); + oFragColor = vec4(srcRGBA.rgb * srcRGBA.a, srcRGBA.a); } diff --git a/shaders/tile_alpha_hsl.fs.glsl b/shaders/tile_alpha_hsl.fs.glsl index 2217e6ff..72f69206 100644 --- a/shaders/tile_alpha_hsl.fs.glsl +++ b/shaders/tile_alpha_hsl.fs.glsl @@ -12,26 +12,21 @@ #extension GL_GOOGLE_include_directive : enable -#define BLEND_TERM_DEST 0 -#define BLEND_TERM_SRC 1 - precision highp float; -uniform sampler2D uStencilTexture; -uniform sampler2D uPaintTexture; -uniform sampler2D uDest; uniform ivec3 uBlendHSL; -uniform vec2 uFramebufferSize; - -in vec2 vColorTexCoord; -in vec2 vMaskTexCoord; out vec4 oFragColor; +#include "tile_alpha_sample.inc.glsl" + #define PI_2 6.283185307179586 #define DEG_30_INV 1.9098593171027443 #define DEG_60 1.0471975511965976 +#define BLEND_TERM_DEST 0 +#define BLEND_TERM_SRC 1 + // https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB_alternative vec3 convertHSLToRGB(vec3 hsl) { float a = hsl.y * min(hsl.z, 1.0 - hsl.z); @@ -63,12 +58,8 @@ vec3 convertRGBToHSL(vec3 rgb) { } void main() { - float coverage = texture(uStencilTexture, vMaskTexCoord).r; - vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord); - srcRGBA.a *= coverage; - - vec2 destTexCoord = gl_FragCoord.xy / uFramebufferSize; - vec4 destRGBA = texture(uDest, destTexCoord); + vec4 srcRGBA = sampleSrcColor(); + vec4 destRGBA = sampleDestColor(); vec3 destHSL = convertRGBToHSL(destRGBA.rgb); vec3 srcHSL = convertRGBToHSL(srcRGBA.rgb); @@ -78,10 +69,5 @@ void main() { blendDest.z ? destHSL.z : srcHSL.z); vec3 blendedRGB = convertHSLToRGB(blendedHSL); - // FIXME(pcwalton): What should the output alpha be here? - vec4 color = vec4(srcRGBA.a * (1.0 - destRGBA.a) * srcRGBA.rgb + - srcRGBA.a * destRGBA.a * blendedRGB + - (1.0 - srcRGBA.a) * destRGBA.a * destRGBA.rgb, - 1.0); - oFragColor = color; + oFragColor = blendColors(destRGBA, srcRGBA, blendedRGB); } diff --git a/shaders/tile_alpha_sample.inc.glsl b/shaders/tile_alpha_sample.inc.glsl new file mode 100644 index 00000000..ae70ad71 --- /dev/null +++ b/shaders/tile_alpha_sample.inc.glsl @@ -0,0 +1,37 @@ +// pathfinder/shaders/tile_alpha_sample.inc.glsl +// +// Copyright © 2020 The Pathfinder Project Developers. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +uniform sampler2D uStencilTexture; +uniform sampler2D uPaintTexture; +uniform sampler2D uDest; +uniform vec2 uFramebufferSize; + +in vec2 vColorTexCoord; +in vec2 vMaskTexCoord; + +// NB: This does not premultiply. +vec4 sampleSrcColor() { + float coverage = texture(uStencilTexture, vMaskTexCoord).r; + vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord); + return vec4(srcRGBA.rgb, srcRGBA.a * coverage); +} + +vec4 sampleDestColor() { + vec2 destTexCoord = gl_FragCoord.xy / uFramebufferSize; + return texture(uDest, destTexCoord); +} + +// FIXME(pcwalton): What should the output alpha be here? +vec4 blendColors(vec4 destRGBA, vec4 srcRGBA, vec3 blendedRGB) { + return vec4(srcRGBA.a * (1.0 - destRGBA.a) * srcRGBA.rgb + + srcRGBA.a * destRGBA.a * blendedRGB + + (1.0 - srcRGBA.a) * destRGBA.a * destRGBA.rgb, + 1.0); +}