From 3ce6c84b1b45efa6a079d5ae23a69f0e308918f7 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 12 Oct 2017 15:55:31 +0800 Subject: [PATCH] Pretty to convert vsh and fsh file to swift. --- .../Shaders/ConvertedShaders_GL.swift | 4245 +++++++++++++++- .../Shaders/ConvertedShaders_GLES.swift | 4325 ++++++++++++++++- .../Operations/Shaders/ShaderConverter.sh | 8 +- 3 files changed, 8285 insertions(+), 293 deletions(-) diff --git a/framework/Source/Operations/Shaders/ConvertedShaders_GL.swift b/framework/Source/Operations/Shaders/ConvertedShaders_GL.swift index 7eb18a5e..4c892a72 100644 --- a/framework/Source/Operations/Shaders/ConvertedShaders_GL.swift +++ b/framework/Source/Operations/Shaders/ConvertedShaders_GL.swift @@ -1,144 +1,4101 @@ -public let AdaptiveThresholdFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n float blurredInput = texture2D(inputImageTexture, textureCoordinate).r;\n float localLuminance = texture2D(inputImageTexture2, textureCoordinate2).r;\n float thresholdResult = step(blurredInput - 0.05, localLuminance);\n \n gl_FragColor = vec4(vec3(thresholdResult), 1.0);\n }\n " -public let AddBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 base = texture2D(inputImageTexture, textureCoordinate);\n vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n float r;\n if (overlay.r * base.a + base.r * overlay.a >= overlay.a * base.a) {\n r = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n } else {\n r = overlay.r + base.r;\n }\n \n float g;\n if (overlay.g * base.a + base.g * overlay.a >= overlay.a * base.a) {\n g = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n } else {\n g = overlay.g + base.g;\n }\n \n float b;\n if (overlay.b * base.a + base.b * overlay.a >= overlay.a * base.a) {\n b = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n } else {\n b = overlay.b + base.b;\n }\n \n float a = overlay.a + base.a - overlay.a * base.a;\n \n gl_FragColor = vec4(r, g, b, a);\n }\n " -public let AlphaBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform float mixturePercent;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(mix(textureColor.rgb, textureColor2.rgb, textureColor2.a * mixturePercent), textureColor.a);\n }\n " -public let AlphaTestFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n vec4 color = texture2D(inputImageTexture, textureCoordinate);\n if (color.a < 0.5) \n {\n discard;\n } \n else\n {\n gl_FragColor = color;\n }\n }\n " -public let AverageColorVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n uniform float texelWidth;\n uniform float texelHeight;\n \n varying vec2 upperLeftInputTextureCoordinate;\n varying vec2 upperRightInputTextureCoordinate;\n varying vec2 lowerLeftInputTextureCoordinate;\n varying vec2 lowerRightInputTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n upperLeftInputTextureCoordinate = inputTextureCoordinate.xy + vec2(-texelWidth, -texelHeight);\n upperRightInputTextureCoordinate = inputTextureCoordinate.xy + vec2(texelWidth, -texelHeight);\n lowerLeftInputTextureCoordinate = inputTextureCoordinate.xy + vec2(-texelWidth, texelHeight);\n lowerRightInputTextureCoordinate = inputTextureCoordinate.xy + vec2(texelWidth, texelHeight);\n }\n " -public let AverageColorFragmentShader = "uniform sampler2D inputImageTexture;\n \n varying vec2 outputTextureCoordinate;\n \n varying vec2 upperLeftInputTextureCoordinate;\n varying vec2 upperRightInputTextureCoordinate;\n varying vec2 lowerLeftInputTextureCoordinate;\n varying vec2 lowerRightInputTextureCoordinate;\n \n void main()\n {\n vec4 upperLeftColor = texture2D(inputImageTexture, upperLeftInputTextureCoordinate);\n vec4 upperRightColor = texture2D(inputImageTexture, upperRightInputTextureCoordinate);\n vec4 lowerLeftColor = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate);\n vec4 lowerRightColor = texture2D(inputImageTexture, lowerRightInputTextureCoordinate);\n \n gl_FragColor = 0.25 * (upperLeftColor + upperRightColor + lowerLeftColor + lowerRightColor);\n }\n " -public let AverageLuminanceFragmentShader = "uniform sampler2D inputImageTexture;\n \n varying vec2 outputTextureCoordinate;\n \n varying vec2 upperLeftInputTextureCoordinate;\n varying vec2 upperRightInputTextureCoordinate;\n varying vec2 lowerLeftInputTextureCoordinate;\n varying vec2 lowerRightInputTextureCoordinate;\n \n void main()\n {\n float upperLeftLuminance = texture2D(inputImageTexture, upperLeftInputTextureCoordinate).r;\n float upperRightLuminance = texture2D(inputImageTexture, upperRightInputTextureCoordinate).r;\n float lowerLeftLuminance = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate).r;\n float lowerRightLuminance = texture2D(inputImageTexture, lowerRightInputTextureCoordinate).r;\n \n float luminosity = 0.25 * (upperLeftLuminance + upperRightLuminance + lowerLeftLuminance + lowerRightLuminance);\n gl_FragColor = vec4(luminosity, luminosity, luminosity, 1.0);\n }\n " -public let BilateralBlurVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n const int GAUSSIAN_SAMPLES = 9;\n \n uniform float texelWidth;\n uniform float texelHeight;\n \n varying vec2 textureCoordinate;\n varying vec2 blurCoordinates[GAUSSIAN_SAMPLES];\n \n void main()\n {\n gl_Position = position;\n textureCoordinate = inputTextureCoordinate.xy;\n \n // Calculate the positions for the blur\n int multiplier = 0;\n vec2 blurStep;\n vec2 singleStepOffset = vec2(texelWidth, texelHeight);\n \n for (int i = 0; i < GAUSSIAN_SAMPLES; i++)\n {\n multiplier = (i - ((GAUSSIAN_SAMPLES - 1) / 2));\n // Blur in x (horizontal)\n blurStep = float(multiplier) * singleStepOffset;\n blurCoordinates[i] = inputTextureCoordinate.xy + blurStep;\n }\n }\n " -public let BilateralBlurFragmentShader = "uniform sampler2D inputImageTexture;\n \n const int GAUSSIAN_SAMPLES = 9;\n \n varying vec2 textureCoordinate;\n varying vec2 blurCoordinates[GAUSSIAN_SAMPLES];\n \n uniform float distanceNormalizationFactor;\n \n void main()\n {\n vec4 centralColor;\n float gaussianWeightTotal;\n vec4 sum;\n vec4 sampleColor;\n float distanceFromCentralColor;\n float gaussianWeight;\n \n centralColor = texture2D(inputImageTexture, blurCoordinates[4]);\n gaussianWeightTotal = 0.18;\n sum = centralColor * 0.18;\n \n sampleColor = texture2D(inputImageTexture, blurCoordinates[0]);\n distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n gaussianWeight = 0.05 * (1.0 - distanceFromCentralColor);\n gaussianWeightTotal += gaussianWeight;\n sum += sampleColor * gaussianWeight;\n \n sampleColor = texture2D(inputImageTexture, blurCoordinates[1]);\n distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n gaussianWeight = 0.09 * (1.0 - distanceFromCentralColor);\n gaussianWeightTotal += gaussianWeight;\n sum += sampleColor * gaussianWeight;\n \n sampleColor = texture2D(inputImageTexture, blurCoordinates[2]);\n distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n gaussianWeight = 0.12 * (1.0 - distanceFromCentralColor);\n gaussianWeightTotal += gaussianWeight;\n sum += sampleColor * gaussianWeight;\n \n sampleColor = texture2D(inputImageTexture, blurCoordinates[3]);\n distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n gaussianWeight = 0.15 * (1.0 - distanceFromCentralColor);\n gaussianWeightTotal += gaussianWeight;\n sum += sampleColor * gaussianWeight;\n \n sampleColor = texture2D(inputImageTexture, blurCoordinates[5]);\n distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n gaussianWeight = 0.15 * (1.0 - distanceFromCentralColor);\n gaussianWeightTotal += gaussianWeight;\n sum += sampleColor * gaussianWeight;\n \n sampleColor = texture2D(inputImageTexture, blurCoordinates[6]);\n distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n gaussianWeight = 0.12 * (1.0 - distanceFromCentralColor);\n gaussianWeightTotal += gaussianWeight;\n sum += sampleColor * gaussianWeight;\n \n sampleColor = texture2D(inputImageTexture, blurCoordinates[7]);\n distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n gaussianWeight = 0.09 * (1.0 - distanceFromCentralColor);\n gaussianWeightTotal += gaussianWeight;\n sum += sampleColor * gaussianWeight;\n \n sampleColor = texture2D(inputImageTexture, blurCoordinates[8]);\n distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n gaussianWeight = 0.05 * (1.0 - distanceFromCentralColor);\n gaussianWeightTotal += gaussianWeight;\n sum += sampleColor * gaussianWeight;\n \n gl_FragColor = sum / gaussianWeightTotal;\n }\n " -public let BrightnessFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float brightness;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = vec4((textureColor.rgb + vec3(brightness)), textureColor.w);\n }\n " -public let BulgeDistortionFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform float aspectRatio;\n uniform vec2 center;\n uniform float radius;\n uniform float scale;\n \n void main()\n {\n vec2 textureCoordinateToUse = vec2(textureCoordinate.x, ((textureCoordinate.y - center.y) * aspectRatio) + center.y);\n float dist = distance(center, textureCoordinateToUse);\n textureCoordinateToUse = textureCoordinate;\n \n if (dist < radius)\n {\n textureCoordinateToUse -= center;\n float percent = 1.0 - ((radius - dist) / radius) * scale;\n percent = percent * percent;\n \n textureCoordinateToUse = textureCoordinateToUse * percent;\n textureCoordinateToUse += center;\n }\n \n gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse );\n }\n " -public let CGAColorspaceFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n vec2 sampleDivisor = vec2(1.0 / 200.0, 1.0 / 320.0);\n //highp vec4 colorDivisor = vec4(colorDepth);\n \n vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor);\n vec4 color = texture2D(inputImageTexture, samplePos );\n \n //gl_FragColor = texture2D(inputImageTexture, samplePos );\n vec4 colorCyan = vec4(85.0 / 255.0, 1.0, 1.0, 1.0);\n vec4 colorMagenta = vec4(1.0, 85.0 / 255.0, 1.0, 1.0);\n vec4 colorWhite = vec4(1.0, 1.0, 1.0, 1.0);\n vec4 colorBlack = vec4(0.0, 0.0, 0.0, 1.0);\n \n vec4 endColor;\n float blackDistance = distance(color, colorBlack);\n float whiteDistance = distance(color, colorWhite);\n float magentaDistance = distance(color, colorMagenta);\n float cyanDistance = distance(color, colorCyan);\n \n vec4 finalColor;\n \n float colorDistance = min(magentaDistance, cyanDistance);\n colorDistance = min(colorDistance, whiteDistance);\n colorDistance = min(colorDistance, blackDistance);\n \n if (colorDistance == blackDistance) {\n finalColor = colorBlack;\n } else if (colorDistance == whiteDistance) {\n finalColor = colorWhite;\n } else if (colorDistance == cyanDistance) {\n finalColor = colorCyan;\n } else {\n finalColor = colorMagenta;\n }\n \n gl_FragColor = finalColor;\n }\n " -public let ChromaKeyBlendFragmentShader = "// Shader code based on Apple's CIChromaKeyFilter example: https://developer.apple.com/library/mac/#samplecode/CIChromaKeyFilter/Introduction/Intro.html\n \n varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform float thresholdSensitivity;\n uniform float smoothing;\n uniform vec3 colorToReplace;\n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n \n float maskY = 0.2989 * colorToReplace.r + 0.5866 * colorToReplace.g + 0.1145 * colorToReplace.b;\n float maskCr = 0.7132 * (colorToReplace.r - maskY);\n float maskCb = 0.5647 * (colorToReplace.b - maskY);\n \n float Y = 0.2989 * textureColor.r + 0.5866 * textureColor.g + 0.1145 * textureColor.b;\n float Cr = 0.7132 * (textureColor.r - Y);\n float Cb = 0.5647 * (textureColor.b - Y);\n \n // float blendValue = 1.0 - smoothstep(thresholdSensitivity - smoothing, thresholdSensitivity , abs(Cr - maskCr) + abs(Cb - maskCb));\n float blendValue = 1.0 - smoothstep(thresholdSensitivity, thresholdSensitivity + smoothing, distance(vec2(Cr, Cb), vec2(maskCr, maskCb)));\n gl_FragColor = mix(textureColor, textureColor2, blendValue);\n }\n " -public let ChromaKeyFragmentShader = "// Shader code based on Apple's CIChromaKeyFilter example: https://developer.apple.com/library/mac/#samplecode/CIChromaKeyFilter/Introduction/Intro.html\n \n varying vec2 textureCoordinate;\n \n uniform float thresholdSensitivity;\n uniform float smoothing;\n uniform vec3 colorToReplace;\n uniform sampler2D inputImageTexture;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n float maskY = 0.2989 * colorToReplace.r + 0.5866 * colorToReplace.g + 0.1145 * colorToReplace.b;\n float maskCr = 0.7132 * (colorToReplace.r - maskY);\n float maskCb = 0.5647 * (colorToReplace.b - maskY);\n \n float Y = 0.2989 * textureColor.r + 0.5866 * textureColor.g + 0.1145 * textureColor.b;\n float Cr = 0.7132 * (textureColor.r - Y);\n float Cb = 0.5647 * (textureColor.b - Y);\n \n // float blendValue = 1.0 - smoothstep(thresholdSensitivity - smoothing, thresholdSensitivity , abs(Cr - maskCr) + abs(Cb - maskCb));\n float blendValue = smoothstep(thresholdSensitivity, thresholdSensitivity + smoothing, distance(vec2(Cr, Cb), vec2(maskCr, maskCb)));\n gl_FragColor = vec4(textureColor.rgb, textureColor.a * blendValue);\n }\n " -public let CircleVertexShader = "attribute vec4 position;\n varying vec2 currentPosition;\n uniform float aspectRatio;\n \n void main()\n {\n currentPosition = vec2(position.x, position.y * aspectRatio);\n gl_Position = position;\n }\n " -public let CircleFragmentShader = "uniform vec4 circleColor;\n uniform vec4 backgroundColor;\n uniform vec2 center;\n uniform float radius;\n \n varying vec2 currentPosition;\n \n void main()\n {\n float distanceFromCenter = distance(center, currentPosition);\n float checkForPresenceWithinCircle = step(distanceFromCenter, radius);\n \n gl_FragColor = mix(backgroundColor, circleColor, checkForPresenceWithinCircle);\n }\n " -public let ColorBlendFragmentShader = "// Color blend mode based upon pseudo code from the PDF specification.\n \n varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n float lum(vec3 c) {\n return dot(c, vec3(0.3, 0.59, 0.11));\n }\n \n vec3 clipcolor(vec3 c) {\n float l = lum(c);\n float n = min(min(c.r, c.g), c.b);\n float x = max(max(c.r, c.g), c.b);\n \n if (n < 0.0) {\n c.r = l + ((c.r - l) * l) / (l - n);\n c.g = l + ((c.g - l) * l) / (l - n);\n c.b = l + ((c.b - l) * l) / (l - n);\n }\n if (x > 1.0) {\n c.r = l + ((c.r - l) * (1.0 - l)) / (x - l);\n c.g = l + ((c.g - l) * (1.0 - l)) / (x - l);\n c.b = l + ((c.b - l) * (1.0 - l)) / (x - l);\n }\n \n return c;\n }\n \n vec3 setlum(vec3 c, float l) {\n float d = l - lum(c);\n c = c + vec3(d);\n return clipcolor(c);\n }\n \n void main()\n {\n vec4 baseColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(overlayColor.rgb, lum(baseColor.rgb)) * overlayColor.a, baseColor.a);\n }\n " -public let ColorBurnBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n vec4 whiteColor = vec4(1.0);\n gl_FragColor = whiteColor - (whiteColor - textureColor) / textureColor2;\n }\n " -public let ColorDodgeBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 base = texture2D(inputImageTexture, textureCoordinate);\n vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n vec3 baseOverlayAlphaProduct = vec3(overlay.a * base.a);\n vec3 rightHandProduct = overlay.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlay.a);\n \n vec3 firstBlendColor = baseOverlayAlphaProduct + rightHandProduct;\n vec3 overlayRGB = clamp((overlay.rgb / clamp(overlay.a, 0.01, 1.0)) * step(0.0, overlay.a), 0.0, 0.99);\n \n vec3 secondBlendColor = (base.rgb * overlay.a) / (1.0 - overlayRGB) + rightHandProduct;\n \n vec3 colorChoice = step((overlay.rgb * base.a + base.rgb * overlay.a), baseOverlayAlphaProduct);\n \n gl_FragColor = vec4(mix(firstBlendColor, secondBlendColor, colorChoice), 1.0);\n }\n " -public let ColorInvertFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = vec4((1.0 - textureColor.rgb), textureColor.w);\n }\n " -public let ColorLocalBinaryPatternFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n vec3 centerColor = texture2D(inputImageTexture, textureCoordinate).rgb;\n vec3 bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb;\n vec3 topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).rgb;\n vec3 topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb;\n vec3 bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb;\n vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb;\n vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb;\n vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;\n vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb;\n \n float redByteTally = 1.0 / 255.0 * step(centerColor.r, topRightColor.r);\n redByteTally += 2.0 / 255.0 * step(centerColor.r, topColor.r);\n redByteTally += 4.0 / 255.0 * step(centerColor.r, topLeftColor.r);\n redByteTally += 8.0 / 255.0 * step(centerColor.r, leftColor.r);\n redByteTally += 16.0 / 255.0 * step(centerColor.r, bottomLeftColor.r);\n redByteTally += 32.0 / 255.0 * step(centerColor.r, bottomColor.r);\n redByteTally += 64.0 / 255.0 * step(centerColor.r, bottomRightColor.r);\n redByteTally += 128.0 / 255.0 * step(centerColor.r, rightColor.r);\n \n float blueByteTally = 1.0 / 255.0 * step(centerColor.b, topRightColor.b);\n blueByteTally += 2.0 / 255.0 * step(centerColor.b, topColor.b);\n blueByteTally += 4.0 / 255.0 * step(centerColor.b, topLeftColor.b);\n blueByteTally += 8.0 / 255.0 * step(centerColor.b, leftColor.b);\n blueByteTally += 16.0 / 255.0 * step(centerColor.b, bottomLeftColor.b);\n blueByteTally += 32.0 / 255.0 * step(centerColor.b, bottomColor.b);\n blueByteTally += 64.0 / 255.0 * step(centerColor.b, bottomRightColor.b);\n blueByteTally += 128.0 / 255.0 * step(centerColor.b, rightColor.b);\n \n float greenByteTally = 1.0 / 255.0 * step(centerColor.g, topRightColor.g);\n greenByteTally += 2.0 / 255.0 * step(centerColor.g, topColor.g);\n greenByteTally += 4.0 / 255.0 * step(centerColor.g, topLeftColor.g);\n greenByteTally += 8.0 / 255.0 * step(centerColor.g, leftColor.g);\n greenByteTally += 16.0 / 255.0 * step(centerColor.g, bottomLeftColor.g);\n greenByteTally += 32.0 / 255.0 * step(centerColor.g, bottomColor.g);\n greenByteTally += 64.0 / 255.0 * step(centerColor.g, bottomRightColor.g);\n greenByteTally += 128.0 / 255.0 * step(centerColor.g, rightColor.g);\n \n // TODO: Replace the above with a dot product and two vec4s\n // TODO: Apply step to a matrix, rather than individually\n \n gl_FragColor = vec4(redByteTally, blueByteTally, greenByteTally, 1.0);\n }\n " -public let ColorMatrixFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform mat4 colorMatrix;\n uniform float intensity;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 outputColor = textureColor * colorMatrix;\n \n gl_FragColor = (intensity * outputColor) + ((1.0 - intensity) * textureColor);\n }\n " -public let ColorSwizzlingFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n gl_FragColor = texture2D(inputImageTexture, textureCoordinate).bgra;\n }\n " -public let ColourFASTDecriptorVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n attribute vec4 inputTextureCoordinate2;\n \n uniform float texelWidth;\n uniform float texelHeight;\n \n varying vec2 textureCoordinate;\n varying vec2 pointATextureCoordinate;\n varying vec2 pointBTextureCoordinate;\n varying vec2 pointCTextureCoordinate;\n varying vec2 pointDTextureCoordinate;\n varying vec2 pointETextureCoordinate;\n varying vec2 pointFTextureCoordinate;\n varying vec2 pointGTextureCoordinate;\n varying vec2 pointHTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n float tripleTexelWidth = 3.0 * texelWidth;\n float tripleTexelHeight = 3.0 * texelHeight;\n \n textureCoordinate = inputTextureCoordinate.xy;\n \n pointATextureCoordinate = vec2(inputTextureCoordinate2.x + tripleTexelWidth, textureCoordinate.y + texelHeight);\n pointBTextureCoordinate = vec2(inputTextureCoordinate2.x + texelWidth, textureCoordinate.y + tripleTexelHeight);\n pointCTextureCoordinate = vec2(inputTextureCoordinate2.x - texelWidth, textureCoordinate.y + tripleTexelHeight);\n pointDTextureCoordinate = vec2(inputTextureCoordinate2.x - tripleTexelWidth, textureCoordinate.y + texelHeight);\n pointETextureCoordinate = vec2(inputTextureCoordinate2.x - tripleTexelWidth, textureCoordinate.y - texelHeight);\n pointFTextureCoordinate = vec2(inputTextureCoordinate2.x - texelWidth, textureCoordinate.y - tripleTexelHeight);\n pointGTextureCoordinate = vec2(inputTextureCoordinate2.x + texelWidth, textureCoordinate.y - tripleTexelHeight);\n pointHTextureCoordinate = vec2(inputTextureCoordinate2.x + tripleTexelWidth, textureCoordinate.y - texelHeight);\n }\n " -public let ColourFASTDecriptorFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 pointATextureCoordinate;\n varying vec2 pointBTextureCoordinate;\n varying vec2 pointCTextureCoordinate;\n varying vec2 pointDTextureCoordinate;\n varying vec2 pointETextureCoordinate;\n varying vec2 pointFTextureCoordinate;\n varying vec2 pointGTextureCoordinate;\n varying vec2 pointHTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n const float PITwo = 6.2832;\n const float PI = 3.1416;\n void main()\n {\n vec3 centerColor = texture2D(inputImageTexture, textureCoordinate).rgb;\n \n vec3 pointAColor = texture2D(inputImageTexture2, pointATextureCoordinate).rgb;\n vec3 pointBColor = texture2D(inputImageTexture2, pointBTextureCoordinate).rgb;\n vec3 pointCColor = texture2D(inputImageTexture2, pointCTextureCoordinate).rgb;\n vec3 pointDColor = texture2D(inputImageTexture2, pointDTextureCoordinate).rgb;\n vec3 pointEColor = texture2D(inputImageTexture2, pointETextureCoordinate).rgb;\n vec3 pointFColor = texture2D(inputImageTexture2, pointFTextureCoordinate).rgb;\n vec3 pointGColor = texture2D(inputImageTexture2, pointGTextureCoordinate).rgb;\n vec3 pointHColor = texture2D(inputImageTexture2, pointHTextureCoordinate).rgb;\n \n vec3 colorComparison = ((pointAColor + pointBColor + pointCColor + pointDColor + pointEColor + pointFColor + pointGColor + pointHColor) * 0.125) - centerColor;\n \n // Direction calculation drawn from Appendix B of Seth Hall's Ph.D. thesis\n \n vec3 dirX = (pointAColor*0.94868) + (pointBColor*0.316227) - (pointCColor*0.316227) - (pointDColor*0.94868) - (pointEColor*0.94868) - (pointFColor*0.316227) + (pointGColor*0.316227) + (pointHColor*0.94868);\n vec3 dirY = (pointAColor*0.316227) + (pointBColor*0.94868) + (pointCColor*0.94868) + (pointDColor*0.316227) - (pointEColor*0.316227) - (pointFColor*0.94868) - (pointGColor*0.94868) - (pointHColor*0.316227);\n vec3 absoluteDifference = abs(colorComparison);\n float componentLength = length(colorComparison);\n float avgX = dot(absoluteDifference, dirX) / componentLength;\n float avgY = dot(absoluteDifference, dirY) / componentLength;\n float angle = atan(avgY, avgX);\n \n vec3 normalizedColorComparison = (colorComparison + 1.0) * 0.5;\n \n gl_FragColor = vec4(normalizedColorComparison, (angle+PI)/PITwo);\n }\n " -public let ContrastFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float contrast;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = vec4(((textureColor.rgb - vec3(0.5)) * contrast + vec3(0.5)), textureColor.w);\n }\n " -public let Convolution3x3FragmentShader = "uniform sampler2D inputImageTexture;\n \n uniform mat3 convolutionMatrix;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n void main()\n {\n vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;\n vec3 bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb;\n vec3 bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb;\n vec4 centerColor = texture2D(inputImageTexture, textureCoordinate);\n vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb;\n vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb;\n vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb;\n vec3 topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).rgb;\n vec3 topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb;\n \n vec3 resultColor = topLeftColor * convolutionMatrix[0][0] + topColor * convolutionMatrix[0][1] + topRightColor * convolutionMatrix[0][2];\n resultColor += leftColor * convolutionMatrix[1][0] + centerColor.rgb * convolutionMatrix[1][1] + rightColor * convolutionMatrix[1][2];\n resultColor += bottomLeftColor * convolutionMatrix[2][0] + bottomColor * convolutionMatrix[2][1] + bottomRightColor * convolutionMatrix[2][2];\n \n gl_FragColor = vec4(resultColor, centerColor.a);\n }\n " -public let CrosshairVertexShader = "attribute vec4 position;\n \n uniform float crosshairWidth;\n \n varying vec2 centerLocation;\n varying float pointSpacing;\n \n void main()\n {\n gl_Position = vec4(((position.xy * 2.0) - 1.0), 0.0, 1.0);\n gl_PointSize = crosshairWidth + 1.0;\n pointSpacing = 1.0 / crosshairWidth;\n centerLocation = vec2(pointSpacing * ceil(crosshairWidth / 2.0), pointSpacing * ceil(crosshairWidth / 2.0));\n }\n " -public let CrosshairFragmentShader = "#version 120\n \n uniform vec3 crosshairColor;\n \n varying vec2 centerLocation;\n varying float pointSpacing;\n \n void main()\n {\n vec2 distanceFromCenter = abs(centerLocation - gl_PointCoord.xy);\n float axisTest = step(pointSpacing, gl_PointCoord.y) * step(distanceFromCenter.x, 0.09) + step(pointSpacing, gl_PointCoord.x) * step(distanceFromCenter.y, 0.09);\n \n gl_FragColor = vec4(crosshairColor * axisTest, axisTest);\n // gl_FragColor = vec4(distanceFromCenterInX, distanceFromCenterInY, 0.0, 1.0);\n }\n " -public let CrosshatchFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform float crossHatchSpacing;\n uniform float lineWidth;\n \n const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n float luminance = dot(texture2D(inputImageTexture, textureCoordinate).rgb, W);\n \n vec4 colorToDisplay = vec4(1.0, 1.0, 1.0, 1.0);\n if (luminance < 1.00)\n {\n if (mod(textureCoordinate.x + textureCoordinate.y, crossHatchSpacing) <= lineWidth)\n {\n colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);\n }\n }\n if (luminance < 0.75)\n {\n if (mod(textureCoordinate.x - textureCoordinate.y, crossHatchSpacing) <= lineWidth)\n {\n colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);\n }\n }\n if (luminance < 0.50)\n {\n if (mod(textureCoordinate.x + textureCoordinate.y - (crossHatchSpacing / 2.0), crossHatchSpacing) <= lineWidth)\n {\n colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);\n }\n }\n if (luminance < 0.3)\n {\n if (mod(textureCoordinate.x - textureCoordinate.y - (crossHatchSpacing / 2.0), crossHatchSpacing) <= lineWidth)\n {\n colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);\n }\n }\n \n gl_FragColor = colorToDisplay;\n }\n " -public let DarkenBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 base = texture2D(inputImageTexture, textureCoordinate);\n vec4 overlayer = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(min(overlayer.rgb * base.a, base.rgb * overlayer.a) + overlayer.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlayer.a), 1.0);\n }\n " -public let DifferenceBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n gl_FragColor = vec4(abs(textureColor2.rgb - textureColor.rgb), textureColor.a);\n }\n " -public let Dilation1FragmentShader = "varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n \n vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity);\n \n gl_FragColor = max(maxValue, oneStepNegativeIntensity);\n }\n " -public let Dilation2FragmentShader = "varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate);\n vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate);\n \n vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity);\n maxValue = max(maxValue, oneStepNegativeIntensity);\n maxValue = max(maxValue, twoStepsPositiveIntensity);\n maxValue = max(maxValue, twoStepsNegativeIntensity);\n \n gl_FragColor = max(maxValue, twoStepsNegativeIntensity);\n }\n " -public let Dilation3FragmentShader = "varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n varying vec2 threeStepsPositiveTextureCoordinate;\n varying vec2 threeStepsNegativeTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate);\n vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate);\n vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate);\n vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate);\n \n vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity);\n maxValue = max(maxValue, oneStepNegativeIntensity);\n maxValue = max(maxValue, twoStepsPositiveIntensity);\n maxValue = max(maxValue, twoStepsNegativeIntensity);\n maxValue = max(maxValue, threeStepsPositiveIntensity);\n \n gl_FragColor = max(maxValue, threeStepsNegativeIntensity);\n }\n " -public let Dilation4FragmentShader = "varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n varying vec2 threeStepsPositiveTextureCoordinate;\n varying vec2 threeStepsNegativeTextureCoordinate;\n varying vec2 fourStepsPositiveTextureCoordinate;\n varying vec2 fourStepsNegativeTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate);\n vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate);\n vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate);\n vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate);\n vec4 fourStepsPositiveIntensity = texture2D(inputImageTexture, fourStepsPositiveTextureCoordinate);\n vec4 fourStepsNegativeIntensity = texture2D(inputImageTexture, fourStepsNegativeTextureCoordinate);\n \n vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity);\n maxValue = max(maxValue, oneStepNegativeIntensity);\n maxValue = max(maxValue, twoStepsPositiveIntensity);\n maxValue = max(maxValue, twoStepsNegativeIntensity);\n maxValue = max(maxValue, threeStepsPositiveIntensity);\n maxValue = max(maxValue, threeStepsNegativeIntensity);\n maxValue = max(maxValue, fourStepsPositiveIntensity);\n \n gl_FragColor = max(maxValue, fourStepsNegativeIntensity);\n }\n " -public let DirectionalNonMaximumSuppressionFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float texelWidth;\n uniform float texelHeight;\n uniform float upperThreshold;\n uniform float lowerThreshold;\n \n void main()\n {\n vec3 currentGradientAndDirection = texture2D(inputImageTexture, textureCoordinate).rgb;\n vec2 gradientDirection = ((currentGradientAndDirection.gb * 2.0) - 1.0) * vec2(texelWidth, texelHeight);\n \n float firstSampledGradientMagnitude = texture2D(inputImageTexture, textureCoordinate + gradientDirection).r;\n float secondSampledGradientMagnitude = texture2D(inputImageTexture, textureCoordinate - gradientDirection).r;\n \n float multiplier = step(firstSampledGradientMagnitude, currentGradientAndDirection.r);\n multiplier = multiplier * step(secondSampledGradientMagnitude, currentGradientAndDirection.r);\n \n float thresholdCompliance = smoothstep(lowerThreshold, upperThreshold, currentGradientAndDirection.r);\n multiplier = multiplier * thresholdCompliance;\n \n gl_FragColor = vec4(multiplier, multiplier, multiplier, 1.0);\n }\n " -public let DirectionalSobelEdgeDetectionFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n \n vec2 gradientDirection;\n gradientDirection.x = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n gradientDirection.y = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n \n float gradientMagnitude = length(gradientDirection);\n vec2 normalizedDirection = normalize(gradientDirection);\n normalizedDirection = sign(normalizedDirection) * floor(abs(normalizedDirection) + 0.617316); // Offset by 1-sin(pi/8) to set to 0 if near axis, 1 if away\n normalizedDirection = (normalizedDirection + 1.0) * 0.5; // Place -1.0 - 1.0 within 0 - 1.0\n \n gl_FragColor = vec4(gradientMagnitude, normalizedDirection.x, normalizedDirection.y, 1.0);\n }\n " -public let DissolveBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n uniform float mixturePercent;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = mix(textureColor, textureColor2, mixturePercent);\n }\n " -public let DivideBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 base = texture2D(inputImageTexture, textureCoordinate);\n vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n float ra;\n if (overlay.a == 0.0 || ((base.r / overlay.r) > (base.a / overlay.a)))\n ra = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n else\n ra = (base.r * overlay.a * overlay.a) / overlay.r + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n \n \n float ga;\n if (overlay.a == 0.0 || ((base.g / overlay.g) > (base.a / overlay.a)))\n ga = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n else\n ga = (base.g * overlay.a * overlay.a) / overlay.g + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n \n \n float ba;\n if (overlay.a == 0.0 || ((base.b / overlay.b) > (base.a / overlay.a)))\n ba = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n else\n ba = (base.b * overlay.a * overlay.a) / overlay.b + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n \n float a = overlay.a + base.a - overlay.a * base.a;\n \n gl_FragColor = vec4(ra, ga, ba, a);\n }\n " -public let Erosion1FragmentShader = "varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n \n vec4 minValue = min(centerIntensity, oneStepPositiveIntensity);\n \n gl_FragColor = min(minValue, oneStepNegativeIntensity);\n }\n " -public let Erosion2FragmentShader = "varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate);\n vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate);\n \n vec4 minValue = min(centerIntensity, oneStepPositiveIntensity);\n minValue = min(minValue, oneStepNegativeIntensity);\n minValue = min(minValue, twoStepsPositiveIntensity);\n \n gl_FragColor = min(minValue, twoStepsNegativeIntensity);\n }\n " -public let Erosion3FragmentShader = "varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n varying vec2 threeStepsPositiveTextureCoordinate;\n varying vec2 threeStepsNegativeTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate);\n vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate);\n vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate);\n vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate);\n \n vec4 minValue = min(centerIntensity, oneStepPositiveIntensity);\n minValue = min(minValue, oneStepNegativeIntensity);\n minValue = min(minValue, twoStepsPositiveIntensity);\n minValue = min(minValue, twoStepsNegativeIntensity);\n minValue = min(minValue, threeStepsPositiveIntensity);\n \n gl_FragColor = min(minValue, threeStepsNegativeIntensity);\n }\n " -public let Erosion4FragmentShader = "varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n varying vec2 threeStepsPositiveTextureCoordinate;\n varying vec2 threeStepsNegativeTextureCoordinate;\n varying vec2 fourStepsPositiveTextureCoordinate;\n varying vec2 fourStepsNegativeTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate);\n vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate);\n vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate);\n vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate);\n vec4 fourStepsPositiveIntensity = texture2D(inputImageTexture, fourStepsPositiveTextureCoordinate);\n vec4 fourStepsNegativeIntensity = texture2D(inputImageTexture, fourStepsNegativeTextureCoordinate);\n \n vec4 minValue = min(centerIntensity, oneStepPositiveIntensity);\n minValue = min(minValue, oneStepNegativeIntensity);\n minValue = min(minValue, twoStepsPositiveIntensity);\n minValue = min(minValue, twoStepsNegativeIntensity);\n minValue = min(minValue, threeStepsPositiveIntensity);\n minValue = min(minValue, threeStepsNegativeIntensity);\n minValue = min(minValue, fourStepsPositiveIntensity);\n \n gl_FragColor = min(minValue, fourStepsNegativeIntensity);\n }\n " -public let ErosionDilation1VertexShader = "attribute vec4 position;\n attribute vec2 inputTextureCoordinate;\n \n uniform float texelWidth; \n uniform float texelHeight; \n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n vec2 offset = vec2(texelWidth, texelHeight);\n \n centerTextureCoordinate = inputTextureCoordinate;\n oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;\n oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;\n }\n " -public let ErosionDilation2VertexShader = "attribute vec4 position;\n attribute vec2 inputTextureCoordinate;\n \n uniform float texelWidth;\n uniform float texelHeight;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n vec2 offset = vec2(texelWidth, texelHeight);\n \n centerTextureCoordinate = inputTextureCoordinate;\n oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;\n oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;\n twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0);\n twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0);\n }\n " -public let ErosionDilation3VertexShader = "attribute vec4 position;\n attribute vec2 inputTextureCoordinate;\n \n uniform float texelWidth;\n uniform float texelHeight;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n varying vec2 threeStepsPositiveTextureCoordinate;\n varying vec2 threeStepsNegativeTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n vec2 offset = vec2(texelWidth, texelHeight);\n \n centerTextureCoordinate = inputTextureCoordinate;\n oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;\n oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;\n twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0);\n twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0);\n threeStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 3.0);\n threeStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 3.0);\n }\n " -public let ErosionDilation4VertexShader = "attribute vec4 position;\n attribute vec2 inputTextureCoordinate;\n \n uniform float texelWidth;\n uniform float texelHeight;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n varying vec2 threeStepsPositiveTextureCoordinate;\n varying vec2 threeStepsNegativeTextureCoordinate;\n varying vec2 fourStepsPositiveTextureCoordinate;\n varying vec2 fourStepsNegativeTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n vec2 offset = vec2(texelWidth, texelHeight);\n \n centerTextureCoordinate = inputTextureCoordinate;\n oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;\n oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;\n twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0);\n twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0);\n threeStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 3.0);\n threeStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 3.0);\n fourStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 4.0);\n fourStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 4.0);\n }\n " -public let ExclusionBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 base = texture2D(inputImageTexture, textureCoordinate);\n vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n // Dca = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa)\n \n gl_FragColor = vec4((overlay.rgb * base.a + base.rgb * overlay.a - 2.0 * overlay.rgb * base.rgb) + overlay.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlay.a), base.a);\n }\n " -public let ExposureFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float exposure;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = vec4(textureColor.rgb * pow(2.0, exposure), textureColor.w);\n }\n " -public let FalseColorFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float intensity;\n uniform vec3 firstColor;\n uniform vec3 secondColor;\n \n const vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n float luminance = dot(textureColor.rgb, luminanceWeighting);\n \n gl_FragColor = vec4( mix(firstColor.rgb, secondColor.rgb, luminance), textureColor.a);\n }\n " -public let FiveInputVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n attribute vec4 inputTextureCoordinate2;\n attribute vec4 inputTextureCoordinate3;\n attribute vec4 inputTextureCoordinate4;\n attribute vec4 inputTextureCoordinate5;\n \n varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n varying vec2 textureCoordinate3;\n varying vec2 textureCoordinate4;\n varying vec2 textureCoordinate5;\n \n void main()\n {\n gl_Position = position;\n textureCoordinate = inputTextureCoordinate.xy;\n textureCoordinate2 = inputTextureCoordinate2.xy;\n textureCoordinate3 = inputTextureCoordinate3.xy;\n textureCoordinate4 = inputTextureCoordinate4.xy;\n textureCoordinate5 = inputTextureCoordinate5.xy;\n }\n " -public let FourInputVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n attribute vec4 inputTextureCoordinate2;\n attribute vec4 inputTextureCoordinate3;\n attribute vec4 inputTextureCoordinate4;\n \n varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n varying vec2 textureCoordinate3;\n varying vec2 textureCoordinate4;\n \n void main()\n {\n gl_Position = position;\n textureCoordinate = inputTextureCoordinate.xy;\n textureCoordinate2 = inputTextureCoordinate2.xy;\n textureCoordinate3 = inputTextureCoordinate3.xy;\n textureCoordinate4 = inputTextureCoordinate4.xy;\n }\n " -public let GammaFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float gamma;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = vec4(pow(textureColor.rgb, vec3(gamma)), textureColor.w);\n }\n " -public let GlassSphereFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform vec2 center;\n uniform float radius;\n uniform float aspectRatio;\n uniform float refractiveIndex;\n // uniform vec3 lightPosition;\n const vec3 lightPosition = vec3(-0.5, 0.5, 1.0);\n const vec3 ambientLightPosition = vec3(0.0, 0.0, 1.0);\n \n void main()\n {\n vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n float distanceFromCenter = distance(center, textureCoordinateToUse);\n float checkForPresenceWithinSphere = step(distanceFromCenter, radius);\n \n distanceFromCenter = distanceFromCenter / radius;\n \n float normalizedDepth = radius * sqrt(1.0 - distanceFromCenter * distanceFromCenter);\n vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - center, normalizedDepth));\n \n vec3 refractedVector = 2.0 * refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex);\n refractedVector.xy = -refractedVector.xy;\n \n vec3 finalSphereColor = texture2D(inputImageTexture, (refractedVector.xy + 1.0) * 0.5).rgb;\n \n // Grazing angle lighting\n float lightingIntensity = 2.5 * (1.0 - pow(clamp(dot(ambientLightPosition, sphereNormal), 0.0, 1.0), 0.25));\n finalSphereColor += lightingIntensity;\n \n // Specular lighting\n lightingIntensity = clamp(dot(normalize(lightPosition), sphereNormal), 0.0, 1.0);\n lightingIntensity = pow(lightingIntensity, 15.0);\n finalSphereColor += vec3(0.8, 0.8, 0.8) * lightingIntensity;\n \n gl_FragColor = vec4(finalSphereColor, 1.0) * checkForPresenceWithinSphere;\n }\n " -public let HalftoneFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform float fractionalWidthOfPixel;\n uniform float aspectRatio;\n \n const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n vec2 sampleDivisor = vec2(fractionalWidthOfPixel, fractionalWidthOfPixel / aspectRatio);\n \n vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor) + 0.5 * sampleDivisor;\n vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n vec2 adjustedSamplePos = vec2(samplePos.x, (samplePos.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n float distanceFromSamplePoint = distance(adjustedSamplePos, textureCoordinateToUse);\n \n vec3 sampledColor = texture2D(inputImageTexture, samplePos ).rgb;\n float dotScaling = 1.0 - dot(sampledColor, W);\n \n float checkForPresenceWithinDot = 1.0 - step(distanceFromSamplePoint, (fractionalWidthOfPixel * 0.5) * dotScaling);\n \n gl_FragColor = vec4(vec3(checkForPresenceWithinDot), 1.0);\n }\n " -public let HardLightBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n vec4 base = texture2D(inputImageTexture, textureCoordinate);\n vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n float ra;\n if (2.0 * overlay.r < overlay.a) {\n ra = 2.0 * overlay.r * base.r + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n } else {\n ra = overlay.a * base.a - 2.0 * (base.a - base.r) * (overlay.a - overlay.r) + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n }\n \n float ga;\n if (2.0 * overlay.g < overlay.a) {\n ga = 2.0 * overlay.g * base.g + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n } else {\n ga = overlay.a * base.a - 2.0 * (base.a - base.g) * (overlay.a - overlay.g) + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n }\n \n float ba;\n if (2.0 * overlay.b < overlay.a) {\n ba = 2.0 * overlay.b * base.b + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n } else {\n ba = overlay.a * base.a - 2.0 * (base.a - base.b) * (overlay.a - overlay.b) + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n }\n \n gl_FragColor = vec4(ra, ga, ba, 1.0);\n }\n " -public let HarrisCornerDetectorFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float sensitivity;\n \n const float harrisConstant = 0.04;\n \n void main()\n {\n vec3 derivativeElements = texture2D(inputImageTexture, textureCoordinate).rgb;\n \n float derivativeSum = derivativeElements.x + derivativeElements.y;\n \n float zElement = (derivativeElements.z * 2.0) - 1.0;\n \n // R = Ix^2 * Iy^2 - Ixy * Ixy - k * (Ix^2 + Iy^2)^2\n float cornerness = derivativeElements.x * derivativeElements.y - (zElement * zElement) - harrisConstant * derivativeSum * derivativeSum;\n \n gl_FragColor = vec4(vec3(cornerness * sensitivity), 1.0);\n }\n " -public let HazeFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform float hazeDistance;\n uniform float slope;\n \n void main()\n {\n //todo reconsider precision modifiers\n vec4 color = vec4(1.0);//todo reimplement as a parameter\n \n float d = textureCoordinate.y * slope + hazeDistance;\n \n vec4 c = texture2D(inputImageTexture, textureCoordinate) ; // consider using unpremultiply\n \n c = (c - d * color) / (1.0 -d);\n \n gl_FragColor = c; //consider using premultiply(c);\n }\n " -public let HighlightShadowTintFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float shadowTintIntensity;\n uniform float highlightTintIntensity;\n uniform vec3 shadowTintColor;\n uniform vec3 highlightTintColor;\n \n const vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n float luminance = dot(textureColor.rgb, luminanceWeighting);\n \n vec4 shadowResult = mix(textureColor, max(textureColor, vec4( mix(shadowTintColor, textureColor.rgb, luminance), textureColor.a)), shadowTintIntensity);\n vec4 highlightResult = mix(textureColor, min(shadowResult, vec4( mix(shadowResult.rgb, highlightTintColor.rgb, luminance), textureColor.a)), highlightTintIntensity);\n \n gl_FragColor = vec4( mix(shadowResult.rgb, highlightResult.rgb, luminance), textureColor.a);\n }\n " -public let HighlightShadowFragmentShader = "uniform sampler2D inputImageTexture;\n varying vec2 textureCoordinate;\n \n uniform float shadows;\n uniform float highlights;\n \n const vec3 luminanceWeighting = vec3(0.3, 0.3, 0.3);\n \n void main()\n {\n vec4 source = texture2D(inputImageTexture, textureCoordinate);\n float luminance = dot(source.rgb, luminanceWeighting);\n \n float shadow = clamp((pow(luminance, 1.0/(shadows+1.0)) + (-0.76)*pow(luminance, 2.0/(shadows+1.0))) - luminance, 0.0, 1.0);\n float highlight = clamp((1.0 - (pow(1.0-luminance, 1.0/(2.0-highlights)) + (-0.8)*pow(1.0-luminance, 2.0/(2.0-highlights)))) - luminance, -1.0, 0.0);\n vec3 result = vec3(0.0, 0.0, 0.0) + ((luminance + shadow + highlight) - 0.0) * ((source.rgb - vec3(0.0, 0.0, 0.0))/(luminance - 0.0));\n \n gl_FragColor = vec4(result.rgb, source.a);\n }\n " -public let HistogramAccumulationFragmentShader = "const float scalingFactor = 1.0 / 256.0;\n \n varying vec3 colorFactor;\n \n void main()\n {\n gl_FragColor = vec4(colorFactor * scalingFactor , 1.0);\n }\n " -public let HistogramBlueSamplingVertexShader = "attribute vec4 position;\n \n varying vec3 colorFactor;\n \n void main()\n {\n colorFactor = vec3(0.0, 0.0, 1.0);\n gl_Position = vec4(-1.0 + (position.z * 0.0078125), 0.0, 0.0, 1.0);\n gl_PointSize = 1.0;\n }\n " -public let HistogramDisplayVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n varying vec2 textureCoordinate;\n varying float height;\n \n void main()\n {\n gl_Position = position;\n textureCoordinate = vec2(inputTextureCoordinate.x, 0.5);\n height = 1.0 - inputTextureCoordinate.y;\n }\n " -public let HistogramDisplayFragmentShader = "varying vec2 textureCoordinate;\n varying float height;\n \n uniform sampler2D inputImageTexture;\n vec4 backgroundColor = vec4(0.0, 0.0, 0.0, 0.0);\n \n void main()\n {\n vec3 colorChannels = texture2D(inputImageTexture, textureCoordinate).rgb;\n vec4 heightTest = vec4(step(height, colorChannels), 1.0);\n gl_FragColor = mix(backgroundColor, heightTest, heightTest.r + heightTest.g + heightTest.b);\n }\n " -public let HistogramEqualizationBlueFragmentShader = "varying vec2 textureCoordinate;\n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n float blueCurveValue = texture2D(inputImageTexture2, vec2(textureColor.b, 0.0)).b;\n \n gl_FragColor = vec4(textureColor.r, textureColor.g, blueCurveValue, textureColor.a);\n }\n " -public let HistogramEqualizationGreenFragmentShader = "varying vec2 textureCoordinate;\n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n float greenCurveValue = texture2D(inputImageTexture2, vec2(textureColor.g, 0.0)).g;\n \n gl_FragColor = vec4(textureColor.r, greenCurveValue, textureColor.b, textureColor.a);\n }\n " -public let HistogramEqualizationLuminanceFragmentShader = "varying vec2 textureCoordinate;\n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n float luminance = dot(textureColor.rgb, W);\n float newLuminance = texture2D(inputImageTexture2, vec2(luminance, 0.0)).r;\n float deltaLuminance = newLuminance - luminance;\n \n float red = clamp(textureColor.r + deltaLuminance, 0.0, 1.0);\n float green = clamp(textureColor.g + deltaLuminance, 0.0, 1.0);\n float blue = clamp(textureColor.b + deltaLuminance, 0.0, 1.0);\n \n gl_FragColor = vec4(red, green, blue, textureColor.a);\n }\n " -public let HistogramEqualizationRGBFragmentShader = "varying vec2 textureCoordinate;\n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n float redCurveValue = texture2D(inputImageTexture2, vec2(textureColor.r, 0.0)).r;\n float greenCurveValue = texture2D(inputImageTexture2, vec2(textureColor.g, 0.0)).g;\n float blueCurveValue = texture2D(inputImageTexture2, vec2(textureColor.b, 0.0)).b;\n \n gl_FragColor = vec4(redCurveValue, greenCurveValue, blueCurveValue, textureColor.a);\n }\n " -public let HistogramEqualizationRedFragmentShader = "varying vec2 textureCoordinate;\n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n float redCurveValue = texture2D(inputImageTexture2, vec2(textureColor.r, 0.0)).r;\n \n gl_FragColor = vec4(redCurveValue, textureColor.g, textureColor.b, textureColor.a);\n }\n " -public let HistogramGreenSamplingVertexShader = "attribute vec4 position;\n \n varying vec3 colorFactor;\n \n void main()\n {\n colorFactor = vec3(0.0, 1.0, 0.0);\n gl_Position = vec4(-1.0 + (position.y * 0.0078125), 0.0, 0.0, 1.0);\n gl_PointSize = 1.0;\n }\n " -public let HistogramLuminanceSamplingVertexShader = "attribute vec4 position;\n \n varying vec3 colorFactor;\n \n const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n float luminance = dot(position.xyz, W);\n \n colorFactor = vec3(1.0, 1.0, 1.0);\n gl_Position = vec4(-1.0 + (luminance * 0.0078125), 0.0, 0.0, 1.0);\n gl_PointSize = 1.0;\n }\n " -public let HistogramRedSamplingVertexShader = "attribute vec4 position;\n \n varying vec3 colorFactor;\n \n void main()\n {\n colorFactor = vec3(1.0, 0.0, 0.0);\n gl_Position = vec4(-1.0 + (position.x * 0.0078125), 0.0, 0.0, 1.0);\n gl_PointSize = 1.0;\n }\n " -public let HueBlendFragmentShader = "// Hue blend mode based upon pseudo code from the PDF specification.\n \n varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n float lum(vec3 c) {\n return dot(c, vec3(0.3, 0.59, 0.11));\n }\n \n vec3 clipcolor(vec3 c) {\n float l = lum(c);\n float n = min(min(c.r, c.g), c.b);\n float x = max(max(c.r, c.g), c.b);\n \n if (n < 0.0) {\n c.r = l + ((c.r - l) * l) / (l - n);\n c.g = l + ((c.g - l) * l) / (l - n);\n c.b = l + ((c.b - l) * l) / (l - n);\n }\n if (x > 1.0) {\n c.r = l + ((c.r - l) * (1.0 - l)) / (x - l);\n c.g = l + ((c.g - l) * (1.0 - l)) / (x - l);\n c.b = l + ((c.b - l) * (1.0 - l)) / (x - l);\n }\n \n return c;\n }\n \n vec3 setlum(vec3 c, float l) {\n float d = l - lum(c);\n c = c + vec3(d);\n return clipcolor(c);\n }\n \n float sat(vec3 c) {\n float n = min(min(c.r, c.g), c.b);\n float x = max(max(c.r, c.g), c.b);\n return x - n;\n }\n \n float mid(float cmin, float cmid, float cmax, float s) {\n return ((cmid - cmin) * s) / (cmax - cmin);\n }\n \n vec3 setsat(vec3 c, float s) {\n if (c.r > c.g) {\n if (c.r > c.b) {\n if (c.g > c.b) {\n /* g is mid, b is min */\n c.g = mid(c.b, c.g, c.r, s);\n c.b = 0.0;\n } else {\n /* b is mid, g is min */\n c.b = mid(c.g, c.b, c.r, s);\n c.g = 0.0;\n }\n c.r = s;\n } else {\n /* b is max, r is mid, g is min */\n c.r = mid(c.g, c.r, c.b, s);\n c.b = s;\n c.r = 0.0;\n }\n } else if (c.r > c.b) {\n /* g is max, r is mid, b is min */\n c.r = mid(c.b, c.r, c.g, s);\n c.g = s;\n c.b = 0.0;\n } else if (c.g > c.b) {\n /* g is max, b is mid, r is min */\n c.b = mid(c.r, c.b, c.g, s);\n c.g = s;\n c.r = 0.0;\n } else if (c.b > c.g) {\n /* b is max, g is mid, r is min */\n c.g = mid(c.r, c.g, c.b, s);\n c.b = s;\n c.r = 0.0;\n } else {\n c = vec3(0.0);\n }\n return c;\n }\n \n void main()\n {\n vec4 baseColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(setsat(overlayColor.rgb, sat(baseColor.rgb)), lum(baseColor.rgb)) * overlayColor.a, baseColor.a);\n }\n " -public let HueFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float hueAdjust;\n const vec4 kRGBToYPrime = vec4 (0.299, 0.587, 0.114, 0.0);\n const vec4 kRGBToI = vec4 (0.595716, -0.274453, -0.321263, 0.0);\n const vec4 kRGBToQ = vec4 (0.211456, -0.522591, 0.31135, 0.0);\n \n const vec4 kYIQToR = vec4 (1.0, 0.9563, 0.6210, 0.0);\n const vec4 kYIQToG = vec4 (1.0, -0.2721, -0.6474, 0.0);\n const vec4 kYIQToB = vec4 (1.0, -1.1070, 1.7046, 0.0);\n \n void main ()\n {\n // Sample the input pixel\n vec4 color = texture2D(inputImageTexture, textureCoordinate);\n \n // Convert to YIQ\n float YPrime = dot (color, kRGBToYPrime);\n float I = dot (color, kRGBToI);\n float Q = dot (color, kRGBToQ);\n \n // Calculate the hue and chroma\n float hue = atan (Q, I);\n float chroma = sqrt (I * I + Q * Q);\n \n // Make the user's adjustments\n hue += (-hueAdjust); //why negative rotation?\n \n // Convert back to YIQ\n Q = chroma * sin (hue);\n I = chroma * cos (hue);\n \n // Convert back to RGB\n vec4 yIQ = vec4 (YPrime, I, Q, 0.0);\n color.r = dot (yIQ, kYIQToR);\n color.g = dot (yIQ, kYIQToG);\n color.b = dot (yIQ, kYIQToB);\n \n // Save the result\n gl_FragColor = color;\n }\n " -public let KuwaharaRadius3FragmentShader = "// Sourced from Kyprianidis, J. E., Kang, H., and Doellner, J. \"Anisotropic Kuwahara Filtering on the GPU,\" GPU Pro p.247 (2010).\n // \n // Original header:\n // \n // Anisotropic Kuwahara Filtering on the GPU\n // by Jan Eric Kyprianidis \n \n varying vec2 textureCoordinate;\n uniform sampler2D inputImageTexture;\n \n const vec2 src_size = vec2 (1.0 / 768.0, 1.0 / 1024.0);\n \n void main (void)\n {\n vec2 uv = textureCoordinate;\n float n = float(16); // radius is assumed to be 3\n vec3 m0 = vec3(0.0); vec3 m1 = vec3(0.0); vec3 m2 = vec3(0.0); vec3 m3 = vec3(0.0);\n vec3 s0 = vec3(0.0); vec3 s1 = vec3(0.0); vec3 s2 = vec3(0.0); vec3 s3 = vec3(0.0);\n vec3 c;\n vec3 cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(-3,-3) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-3,-2) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-3,-1) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-3,0) * src_size).rgb;\n cSq = c * c;\n m0 += c;\n s0 += cSq;\n m1 += c;\n s1 += cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(-2,-3) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-2,-2) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-2,-1) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-2,0) * src_size).rgb;\n cSq = c * c;\n m0 += c;\n s0 += cSq;\n m1 += c;\n s1 += cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(-1,-3) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-1,-2) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-1,-1) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-1,0) * src_size).rgb;\n cSq = c * c;\n m0 += c;\n s0 += cSq;\n m1 += c;\n s1 += cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(0,-3) * src_size).rgb;\n cSq = c * c;\n m0 += c;\n s0 += cSq;\n m3 += c;\n s3 += cSq;\n c = texture2D(inputImageTexture, uv + vec2(0,-2) * src_size).rgb;\n cSq = c * c;\n m0 += c;\n s0 += cSq;\n m3 += c;\n s3 += cSq;\n c = texture2D(inputImageTexture, uv + vec2(0,-1) * src_size).rgb;\n cSq = c * c;\n m0 += c;\n s0 += cSq;\n m3 += c;\n s3 += cSq;\n c = texture2D(inputImageTexture, uv + vec2(0,0) * src_size).rgb;\n cSq = c * c;\n m0 += c;\n s0 += cSq;\n m1 += c;\n s1 += cSq;\n m2 += c;\n s2 += cSq;\n m3 += c;\n s3 += cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(-3,3) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-3,2) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-3,1) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n \n c = texture2D(inputImageTexture, uv + vec2(-2,3) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-2,2) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-2,1) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n \n c = texture2D(inputImageTexture, uv + vec2(-1,3) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-1,2) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-1,1) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n \n c = texture2D(inputImageTexture, uv + vec2(0,3) * src_size).rgb;\n cSq = c * c;\n m1 += c;\n s1 += cSq;\n m2 += c;\n s2 += cSq;\n c = texture2D(inputImageTexture, uv + vec2(0,2) * src_size).rgb;\n cSq = c * c;\n m1 += c;\n s1 += cSq;\n m2 += c;\n s2 += cSq;\n c = texture2D(inputImageTexture, uv + vec2(0,1) * src_size).rgb;\n cSq = c * c;\n m1 += c;\n s1 += cSq;\n m2 += c;\n s2 += cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(3,3) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(3,2) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(3,1) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(3,0) * src_size).rgb;\n cSq = c * c;\n m2 += c;\n s2 += cSq;\n m3 += c;\n s3 += cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(2,3) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(2,2) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(2,1) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(2,0) * src_size).rgb;\n cSq = c * c;\n m2 += c;\n s2 += cSq;\n m3 += c;\n s3 += cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(1,3) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(1,2) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(1,1) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(1,0) * src_size).rgb;\n cSq = c * c;\n m2 += c;\n s2 += cSq;\n m3 += c;\n s3 += cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(3,-3) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(3,-2) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(3,-1) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n \n c = texture2D(inputImageTexture, uv + vec2(2,-3) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(2,-2) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(2,-1) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n \n c = texture2D(inputImageTexture, uv + vec2(1,-3) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(1,-2) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(1,-1) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n \n float min_sigma2 = 1e+2;\n m0 /= n;\n s0 = abs(s0 / n - m0 * m0);\n \n float sigma2 = s0.r + s0.g + s0.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n gl_FragColor = vec4(m0, 1.0);\n }\n \n m1 /= n;\n s1 = abs(s1 / n - m1 * m1);\n \n sigma2 = s1.r + s1.g + s1.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n gl_FragColor = vec4(m1, 1.0);\n }\n \n m2 /= n;\n s2 = abs(s2 / n - m2 * m2);\n \n sigma2 = s2.r + s2.g + s2.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n gl_FragColor = vec4(m2, 1.0);\n }\n \n m3 /= n;\n s3 = abs(s3 / n - m3 * m3);\n \n sigma2 = s3.r + s3.g + s3.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n gl_FragColor = vec4(m3, 1.0);\n }\n }\n " -public let KuwaharaFragmentShader = "// Sourced from Kyprianidis, J. E., Kang, H., and Doellner, J. \"Anisotropic Kuwahara Filtering on the GPU,\" GPU Pro p.247 (2010).\n // \n // Original header:\n // \n // Anisotropic Kuwahara Filtering on the GPU\n // by Jan Eric Kyprianidis \n \n varying vec2 textureCoordinate;\n uniform sampler2D inputImageTexture;\n uniform int radius;\n \n const vec2 src_size = vec2 (1.0 / 768.0, 1.0 / 1024.0);\n \n void main (void)\n {\n vec2 uv = textureCoordinate;\n float n = float((radius + 1) * (radius + 1));\n int i; int j;\n vec3 m0 = vec3(0.0); vec3 m1 = vec3(0.0); vec3 m2 = vec3(0.0); vec3 m3 = vec3(0.0);\n vec3 s0 = vec3(0.0); vec3 s1 = vec3(0.0); vec3 s2 = vec3(0.0); vec3 s3 = vec3(0.0);\n vec3 c;\n \n for (j = -radius; j <= 0; ++j) {\n for (i = -radius; i <= 0; ++i) {\n c = texture2D(inputImageTexture, uv + vec2(i,j) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n }\n }\n \n for (j = -radius; j <= 0; ++j) {\n for (i = 0; i <= radius; ++i) {\n c = texture2D(inputImageTexture, uv + vec2(i,j) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n }\n }\n \n for (j = 0; j <= radius; ++j) {\n for (i = 0; i <= radius; ++i) {\n c = texture2D(inputImageTexture, uv + vec2(i,j) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n }\n }\n \n for (j = 0; j <= radius; ++j) {\n for (i = -radius; i <= 0; ++i) {\n c = texture2D(inputImageTexture, uv + vec2(i,j) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n }\n }\n \n \n float min_sigma2 = 1e+2;\n m0 /= n;\n s0 = abs(s0 / n - m0 * m0);\n \n float sigma2 = s0.r + s0.g + s0.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n gl_FragColor = vec4(m0, 1.0);\n }\n \n m1 /= n;\n s1 = abs(s1 / n - m1 * m1);\n \n sigma2 = s1.r + s1.g + s1.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n gl_FragColor = vec4(m1, 1.0);\n }\n \n m2 /= n;\n s2 = abs(s2 / n - m2 * m2);\n \n sigma2 = s2.r + s2.g + s2.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n gl_FragColor = vec4(m2, 1.0);\n }\n \n m3 /= n;\n s3 = abs(s3 / n - m3 * m3);\n \n sigma2 = s3.r + s3.g + s3.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n gl_FragColor = vec4(m3, 1.0);\n }\n }\n " -public let LanczosResamplingVertexShader = "attribute vec4 position;\n attribute vec2 inputTextureCoordinate;\n \n uniform float texelWidth;\n uniform float texelHeight;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepLeftTextureCoordinate;\n varying vec2 twoStepsLeftTextureCoordinate;\n varying vec2 threeStepsLeftTextureCoordinate;\n varying vec2 fourStepsLeftTextureCoordinate;\n varying vec2 oneStepRightTextureCoordinate;\n varying vec2 twoStepsRightTextureCoordinate;\n varying vec2 threeStepsRightTextureCoordinate;\n varying vec2 fourStepsRightTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n vec2 firstOffset = vec2(texelWidth, texelHeight);\n vec2 secondOffset = vec2(2.0 * texelWidth, 2.0 * texelHeight);\n vec2 thirdOffset = vec2(3.0 * texelWidth, 3.0 * texelHeight);\n vec2 fourthOffset = vec2(4.0 * texelWidth, 4.0 * texelHeight);\n \n centerTextureCoordinate = inputTextureCoordinate;\n oneStepLeftTextureCoordinate = inputTextureCoordinate - firstOffset;\n twoStepsLeftTextureCoordinate = inputTextureCoordinate - secondOffset;\n threeStepsLeftTextureCoordinate = inputTextureCoordinate - thirdOffset;\n fourStepsLeftTextureCoordinate = inputTextureCoordinate - fourthOffset;\n oneStepRightTextureCoordinate = inputTextureCoordinate + firstOffset;\n twoStepsRightTextureCoordinate = inputTextureCoordinate + secondOffset;\n threeStepsRightTextureCoordinate = inputTextureCoordinate + thirdOffset;\n fourStepsRightTextureCoordinate = inputTextureCoordinate + fourthOffset;\n }\n " -public let LanczosResamplingFragmentShader = "uniform sampler2D inputImageTexture;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepLeftTextureCoordinate;\n varying vec2 twoStepsLeftTextureCoordinate;\n varying vec2 threeStepsLeftTextureCoordinate;\n varying vec2 fourStepsLeftTextureCoordinate;\n varying vec2 oneStepRightTextureCoordinate;\n varying vec2 twoStepsRightTextureCoordinate;\n varying vec2 threeStepsRightTextureCoordinate;\n varying vec2 fourStepsRightTextureCoordinate;\n \n // sinc(x) * sinc(x/a) = (a * sin(pi * x) * sin(pi * x / a)) / (pi^2 * x^2)\n // Assuming a Lanczos constant of 2.0, and scaling values to max out at x = +/- 1.5\n \n void main()\n {\n vec4 fragmentColor = texture2D(inputImageTexture, centerTextureCoordinate) * 0.38026;\n \n fragmentColor += texture2D(inputImageTexture, oneStepLeftTextureCoordinate) * 0.27667;\n fragmentColor += texture2D(inputImageTexture, oneStepRightTextureCoordinate) * 0.27667;\n \n fragmentColor += texture2D(inputImageTexture, twoStepsLeftTextureCoordinate) * 0.08074;\n fragmentColor += texture2D(inputImageTexture, twoStepsRightTextureCoordinate) * 0.08074;\n \n fragmentColor += texture2D(inputImageTexture, threeStepsLeftTextureCoordinate) * -0.02612;\n fragmentColor += texture2D(inputImageTexture, threeStepsRightTextureCoordinate) * -0.02612;\n \n fragmentColor += texture2D(inputImageTexture, fourStepsLeftTextureCoordinate) * -0.02143;\n fragmentColor += texture2D(inputImageTexture, fourStepsRightTextureCoordinate) * -0.02143;\n \n gl_FragColor = fragmentColor;\n }\n " -public let LaplacianFragmentShader = "uniform sampler2D inputImageTexture;\n \n uniform mat3 convolutionMatrix;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n void main()\n {\n vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;\n vec3 bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb;\n vec3 bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb;\n vec4 centerColor = texture2D(inputImageTexture, textureCoordinate);\n vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb;\n vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb;\n vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb;\n vec3 topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).rgb;\n vec3 topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb;\n \n vec3 resultColor = topLeftColor * 0.5 + topColor * 1.0 + topRightColor * 0.5;\n resultColor += leftColor * 1.0 + centerColor.rgb * (-6.0) + rightColor * 1.0;\n resultColor += bottomLeftColor * 0.5 + bottomColor * 1.0 + bottomRightColor * 0.5;\n \n // Normalize the results to allow for negative gradients in the 0.0-1.0 colorspace\n resultColor = resultColor + 0.5;\n \n gl_FragColor = vec4(resultColor, centerColor.a);\n }\n " -public let LevelsFragmentShader = "/*\n ** Gamma correction\n ** Details: http://blog.mouaif.org/2009/01/22/photoshop-gamma-correction-shader/\n */\n \n #define GammaCorrection(color, gamma) pow(color, 1.0 / gamma)\n \n /*\n ** Levels control (input (+gamma), output)\n ** Details: http://blog.mouaif.org/2009/01/28/levels-control-shader/\n */\n \n #define LevelsControlInputRange(color, minInput, maxInput) min(max(color - minInput, vec3(0.0)) / (maxInput - minInput), vec3(1.0))\n #define LevelsControlInput(color, minInput, gamma, maxInput) GammaCorrection(LevelsControlInputRange(color, minInput, maxInput), gamma)\n #define LevelsControlOutputRange(color, minOutput, maxOutput) mix(minOutput, maxOutput, color)\n #define LevelsControl(color, minInput, gamma, maxInput, minOutput, maxOutput) LevelsControlOutputRange(LevelsControlInput(color, minInput, gamma, maxInput), minOutput, maxOutput)\n \n varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform vec3 levelMinimum;\n uniform vec3 levelMiddle;\n uniform vec3 levelMaximum;\n uniform vec3 minOutput;\n uniform vec3 maxOutput;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = vec4(LevelsControl(textureColor.rgb, levelMinimum, levelMiddle, levelMaximum, minOutput, maxOutput), textureColor.a);\n }\n " -public let LightenBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = max(textureColor, textureColor2);\n }\n " -public let LineVertexShader = "attribute vec4 position;\n \n void main()\n {\n gl_Position = position;\n }\n " -public let LineFragmentShader = "uniform vec3 lineColor;\n \n void main()\n {\n gl_FragColor = vec4(lineColor, 1.0);\n }\n " -public let LinearBurnBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(clamp(textureColor.rgb + textureColor2.rgb - vec3(1.0), vec3(0.0), vec3(1.0)), textureColor.a);\n }\n " -public let LocalBinaryPatternFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n float centerIntensity = texture2D(inputImageTexture, textureCoordinate).r;\n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n \n float byteTally = 1.0 / 255.0 * step(centerIntensity, topRightIntensity);\n byteTally += 2.0 / 255.0 * step(centerIntensity, topIntensity);\n byteTally += 4.0 / 255.0 * step(centerIntensity, topLeftIntensity);\n byteTally += 8.0 / 255.0 * step(centerIntensity, leftIntensity);\n byteTally += 16.0 / 255.0 * step(centerIntensity, bottomLeftIntensity);\n byteTally += 32.0 / 255.0 * step(centerIntensity, bottomIntensity);\n byteTally += 64.0 / 255.0 * step(centerIntensity, bottomRightIntensity);\n byteTally += 128.0 / 255.0 * step(centerIntensity, rightIntensity);\n \n // TODO: Replace the above with a dot product and two vec4s\n // TODO: Apply step to a matrix, rather than individually\n \n gl_FragColor = vec4(byteTally, byteTally, byteTally, 1.0);\n }\n " -public let LookupFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2; // lookup texture\n \n uniform float intensity;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n float blueColor = textureColor.b * 63.0;\n \n vec2 quad1;\n quad1.y = floor(floor(blueColor) / 8.0);\n quad1.x = floor(blueColor) - (quad1.y * 8.0);\n \n vec2 quad2;\n quad2.y = floor(ceil(blueColor) / 8.0);\n quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n \n vec2 texPos1;\n texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);\n texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);\n \n vec2 texPos2;\n texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);\n texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);\n \n vec4 newColor1 = texture2D(inputImageTexture2, texPos1);\n vec4 newColor2 = texture2D(inputImageTexture2, texPos2);\n \n vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n gl_FragColor = mix(textureColor, vec4(newColor.rgb, textureColor.w), intensity);\n }\n " -public let LuminanceRangeFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float rangeReduction;\n \n // Values from \"Graphics Shaders: Theory and Practice\" by Bailey and Cunningham\n const vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n float luminance = dot(textureColor.rgb, luminanceWeighting);\n float luminanceRatio = ((0.5 - luminance) * rangeReduction);\n \n gl_FragColor = vec4((textureColor.rgb) + (luminanceRatio), textureColor.w);\n }\n " -public let LuminanceThresholdFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float threshold;\n \n const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n float luminance = dot(textureColor.rgb, W);\n float thresholdResult = step(threshold, luminance);\n \n gl_FragColor = vec4(vec3(thresholdResult), textureColor.w);\n }\n " -public let LuminanceFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n // Values from \"Graphics Shaders: Theory and Practice\" by Bailey and Cunningham\n const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n float luminance = dot(textureColor.rgb, W);\n \n gl_FragColor = vec4(vec3(luminance), textureColor.a);\n }\n " -public let LuminosityBlendFragmentShader = "// Luminosity blend mode based upon pseudo code from the PDF specification.\n \n varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n float lum(vec3 c) {\n return dot(c, vec3(0.3, 0.59, 0.11));\n }\n \n vec3 clipcolor(vec3 c) {\n float l = lum(c);\n float n = min(min(c.r, c.g), c.b);\n float x = max(max(c.r, c.g), c.b);\n \n if (n < 0.0) {\n c.r = l + ((c.r - l) * l) / (l - n);\n c.g = l + ((c.g - l) * l) / (l - n);\n c.b = l + ((c.b - l) * l) / (l - n);\n }\n if (x > 1.0) {\n c.r = l + ((c.r - l) * (1.0 - l)) / (x - l);\n c.g = l + ((c.g - l) * (1.0 - l)) / (x - l);\n c.b = l + ((c.b - l) * (1.0 - l)) / (x - l);\n }\n \n return c;\n }\n \n vec3 setlum(vec3 c, float l) {\n float d = l - lum(c);\n c = c + vec3(d);\n return clipcolor(c);\n }\n \n void main()\n {\n vec4 baseColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(baseColor.rgb, lum(overlayColor.rgb)) * overlayColor.a, baseColor.a);\n }\n " -public let MedianFragmentShader = "/*\n 3x3 median filter, adapted from \"A Fast, Small-Radius GPU Median Filter\" by Morgan McGuire in ShaderX6\n http://graphics.cs.williams.edu/papers/MedianShaderX6/\n \n Morgan McGuire and Kyle Whitson\n Williams College\n \n Register allocation tips by Victor Huang Xiaohuang\n University of Illinois at Urbana-Champaign\n \n http://graphics.cs.williams.edu\n \n \n Copyright (c) Morgan McGuire and Williams College, 2006\n All rights reserved.\n \n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are\n met:\n \n Redistributions of source code must retain the above copyright notice,\n this list of conditions and the following disclaimer.\n \n Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in the\n documentation and/or other materials provided with the distribution.\n \n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n #define s2(a, b) temp = a; a = min(a, b); b = max(temp, b);\n #define mn3(a, b, c) s2(a, b); s2(a, c);\n #define mx3(a, b, c) s2(b, c); s2(a, c);\n \n #define mnmx3(a, b, c) mx3(a, b, c); s2(a, b); // 3 exchanges\n #define mnmx4(a, b, c, d) s2(a, b); s2(c, d); s2(a, c); s2(b, d); // 4 exchanges\n #define mnmx5(a, b, c, d, e) s2(a, b); s2(c, d); mn3(a, c, e); mx3(b, d, e); // 6 exchanges\n #define mnmx6(a, b, c, d, e, f) s2(a, d); s2(b, e); s2(c, f); mn3(a, b, c); mx3(d, e, f); // 7 exchanges\n \n void main()\n {\n vec3 v[6];\n \n v[0] = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb;\n v[1] = texture2D(inputImageTexture, topRightTextureCoordinate).rgb;\n v[2] = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb;\n v[3] = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb;\n v[4] = texture2D(inputImageTexture, leftTextureCoordinate).rgb;\n v[5] = texture2D(inputImageTexture, rightTextureCoordinate).rgb;\n // v[6] = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;\n // v[7] = texture2D(inputImageTexture, topTextureCoordinate).rgb;\n vec3 temp;\n \n mnmx6(v[0], v[1], v[2], v[3], v[4], v[5]);\n \n v[5] = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;\n \n mnmx5(v[1], v[2], v[3], v[4], v[5]);\n \n v[5] = texture2D(inputImageTexture, topTextureCoordinate).rgb;\n \n mnmx4(v[2], v[3], v[4], v[5]);\n \n v[5] = texture2D(inputImageTexture, textureCoordinate).rgb;\n \n mnmx3(v[3], v[4], v[5]);\n \n gl_FragColor = vec4(v[4], 1.0);\n }\n " -public let MonochromeFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float intensity;\n uniform vec3 filterColor;\n \n const vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n //desat, then apply overlay blend\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n float luminance = dot(textureColor.rgb, luminanceWeighting);\n \n vec4 desat = vec4(vec3(luminance), 1.0);\n \n //overlay\n vec4 outputColor = vec4(\n (desat.r < 0.5 ? (2.0 * desat.r * filterColor.r) : (1.0 - 2.0 * (1.0 - desat.r) * (1.0 - filterColor.r))),\n (desat.g < 0.5 ? (2.0 * desat.g * filterColor.g) : (1.0 - 2.0 * (1.0 - desat.g) * (1.0 - filterColor.g))),\n (desat.b < 0.5 ? (2.0 * desat.b * filterColor.b) : (1.0 - 2.0 * (1.0 - desat.b) * (1.0 - filterColor.b))),\n 1.0\n );\n \n //which is better, or are they equal?\n gl_FragColor = vec4( mix(textureColor.rgb, outputColor.rgb, intensity), textureColor.a);\n }\n " -public let MotionBlurVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n uniform vec2 directionalTexelStep;\n \n varying vec2 textureCoordinate;\n varying vec2 oneStepBackTextureCoordinate;\n varying vec2 twoStepsBackTextureCoordinate;\n varying vec2 threeStepsBackTextureCoordinate;\n varying vec2 fourStepsBackTextureCoordinate;\n varying vec2 oneStepForwardTextureCoordinate;\n varying vec2 twoStepsForwardTextureCoordinate;\n varying vec2 threeStepsForwardTextureCoordinate;\n varying vec2 fourStepsForwardTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n textureCoordinate = inputTextureCoordinate.xy;\n oneStepBackTextureCoordinate = inputTextureCoordinate.xy - directionalTexelStep;\n twoStepsBackTextureCoordinate = inputTextureCoordinate.xy - 2.0 * directionalTexelStep;\n threeStepsBackTextureCoordinate = inputTextureCoordinate.xy - 3.0 * directionalTexelStep;\n fourStepsBackTextureCoordinate = inputTextureCoordinate.xy - 4.0 * directionalTexelStep;\n oneStepForwardTextureCoordinate = inputTextureCoordinate.xy + directionalTexelStep;\n twoStepsForwardTextureCoordinate = inputTextureCoordinate.xy + 2.0 * directionalTexelStep;\n threeStepsForwardTextureCoordinate = inputTextureCoordinate.xy + 3.0 * directionalTexelStep;\n fourStepsForwardTextureCoordinate = inputTextureCoordinate.xy + 4.0 * directionalTexelStep;\n }\n " -public let MotionBlurFragmentShader = "uniform sampler2D inputImageTexture;\n \n varying vec2 textureCoordinate;\n varying vec2 oneStepBackTextureCoordinate;\n varying vec2 twoStepsBackTextureCoordinate;\n varying vec2 threeStepsBackTextureCoordinate;\n varying vec2 fourStepsBackTextureCoordinate;\n varying vec2 oneStepForwardTextureCoordinate;\n varying vec2 twoStepsForwardTextureCoordinate;\n varying vec2 threeStepsForwardTextureCoordinate;\n varying vec2 fourStepsForwardTextureCoordinate;\n \n void main()\n {\n vec4 fragmentColor = texture2D(inputImageTexture, textureCoordinate) * 0.18;\n fragmentColor += texture2D(inputImageTexture, oneStepBackTextureCoordinate) * 0.15;\n fragmentColor += texture2D(inputImageTexture, twoStepsBackTextureCoordinate) * 0.12;\n fragmentColor += texture2D(inputImageTexture, threeStepsBackTextureCoordinate) * 0.09;\n fragmentColor += texture2D(inputImageTexture, fourStepsBackTextureCoordinate) * 0.05;\n fragmentColor += texture2D(inputImageTexture, oneStepForwardTextureCoordinate) * 0.15;\n fragmentColor += texture2D(inputImageTexture, twoStepsForwardTextureCoordinate) * 0.12;\n fragmentColor += texture2D(inputImageTexture, threeStepsForwardTextureCoordinate) * 0.09;\n fragmentColor += texture2D(inputImageTexture, fourStepsForwardTextureCoordinate) * 0.05;\n \n gl_FragColor = fragmentColor;\n }\n " -public let MotionComparisonFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform float intensity;\n \n void main()\n {\n vec3 currentImageColor = texture2D(inputImageTexture, textureCoordinate).rgb;\n vec3 lowPassImageColor = texture2D(inputImageTexture2, textureCoordinate2).rgb;\n \n float colorDistance = distance(currentImageColor, lowPassImageColor); // * 0.57735\n float movementThreshold = step(0.2, colorDistance);\n \n gl_FragColor = movementThreshold * vec4(textureCoordinate2.x, textureCoordinate2.y, 1.0, 1.0);\n }\n " -public let MultiplyBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 base = texture2D(inputImageTexture, textureCoordinate);\n vec4 overlayer = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = overlayer * base + overlayer * (1.0 - base.a) + base * (1.0 - overlayer.a);\n }\n " -public let NearbyTexelSamplingVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n uniform float texelWidth;\n uniform float texelHeight; \n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n vec2 widthStep = vec2(texelWidth, 0.0);\n vec2 heightStep = vec2(0.0, texelHeight);\n vec2 widthHeightStep = vec2(texelWidth, texelHeight);\n vec2 widthNegativeHeightStep = vec2(texelWidth, -texelHeight);\n \n textureCoordinate = inputTextureCoordinate.xy;\n leftTextureCoordinate = inputTextureCoordinate.xy - widthStep;\n rightTextureCoordinate = inputTextureCoordinate.xy + widthStep;\n \n topTextureCoordinate = inputTextureCoordinate.xy - heightStep;\n topLeftTextureCoordinate = inputTextureCoordinate.xy - widthHeightStep;\n topRightTextureCoordinate = inputTextureCoordinate.xy + widthNegativeHeightStep;\n \n bottomTextureCoordinate = inputTextureCoordinate.xy + heightStep;\n bottomLeftTextureCoordinate = inputTextureCoordinate.xy - widthNegativeHeightStep;\n bottomRightTextureCoordinate = inputTextureCoordinate.xy + widthHeightStep;\n }\n " -public let NobleCornerDetectorFragmentShader = " varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float sensitivity;\n \n void main()\n {\n vec3 derivativeElements = texture2D(inputImageTexture, textureCoordinate).rgb;\n \n float derivativeSum = derivativeElements.x + derivativeElements.y;\n \n // R = (Ix^2 * Iy^2 - Ixy * Ixy) / (Ix^2 + Iy^2)\n float zElement = (derivativeElements.z * 2.0) - 1.0;\n // mediump float harrisIntensity = (derivativeElements.x * derivativeElements.y - (derivativeElements.z * derivativeElements.z)) / (derivativeSum);\n float cornerness = (derivativeElements.x * derivativeElements.y - (zElement * zElement)) / (derivativeSum);\n \n // Original Harris detector\n // R = Ix^2 * Iy^2 - Ixy * Ixy - k * (Ix^2 + Iy^2)^2\n // highp float harrisIntensity = derivativeElements.x * derivativeElements.y - (derivativeElements.z * derivativeElements.z) - harrisConstant * derivativeSum * derivativeSum;\n \n // gl_FragColor = vec4(vec3(harrisIntensity * 7.0), 1.0);\n gl_FragColor = vec4(vec3(cornerness * sensitivity), 1.0);\n }\n " -public let NormalBlendFragmentShader = "/*\n This equation is a simplification of the general blending equation. It assumes the destination color is opaque, and therefore drops the destination color's alpha term.\n \n D = C1 * C1a + C2 * C2a * (1 - C1a)\n where D is the resultant color, C1 is the color of the first element, C1a is the alpha of the first element, C2 is the second element color, C2a is the alpha of the second element. The destination alpha is calculated with:\n \n Da = C1a + C2a * (1 - C1a)\n The resultant color is premultiplied with the alpha. To restore the color to the unmultiplied values, just divide by Da, the resultant alpha.\n \n http://stackoverflow.com/questions/1724946/blend-mode-on-a-transparent-and-semi-transparent-background\n \n For some reason Photoshop behaves \n D = C1 + C2 * C2a * (1 - C1a)\n */\n \n varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 c2 = texture2D(inputImageTexture, textureCoordinate);\n vec4 c1 = texture2D(inputImageTexture2, textureCoordinate2);\n \n vec4 outputColor;\n \n // outputColor.r = c1.r + c2.r * c2.a * (1.0 - c1.a);\n // outputColor.g = c1.g + c2.g * c2.a * (1.0 - c1.a);\n // outputColor.b = c1.b + c2.b * c2.a * (1.0 - c1.a);\n // outputColor.a = c1.a + c2.a * (1.0 - c1.a);\n \n float a = c1.a + c2.a * (1.0 - c1.a);\n float alphaDivisor = a + step(a, 0.0); // Protect against a divide-by-zero blacking out things in the output\n \n outputColor.r = (c1.r * c1.a + c2.r * c2.a * (1.0 - c1.a))/alphaDivisor;\n outputColor.g = (c1.g * c1.a + c2.g * c2.a * (1.0 - c1.a))/alphaDivisor;\n outputColor.b = (c1.b * c1.a + c2.b * c2.a * (1.0 - c1.a))/alphaDivisor;\n outputColor.a = a;\n \n gl_FragColor = outputColor;\n }\n " -public let OneInputVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n varying vec2 textureCoordinate;\n \n void main()\n {\n gl_Position = position;\n textureCoordinate = inputTextureCoordinate.xy;\n }\n " -public let OpacityFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float opacity;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = vec4(textureColor.rgb, textureColor.a * opacity);\n }\n " -public let OverlayBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 base = texture2D(inputImageTexture, textureCoordinate);\n vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n float ra;\n if (2.0 * base.r < base.a) {\n ra = 2.0 * overlay.r * base.r + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n } else {\n ra = overlay.a * base.a - 2.0 * (base.a - base.r) * (overlay.a - overlay.r) + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n }\n \n float ga;\n if (2.0 * base.g < base.a) {\n ga = 2.0 * overlay.g * base.g + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n } else {\n ga = overlay.a * base.a - 2.0 * (base.a - base.g) * (overlay.a - overlay.g) + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n }\n \n float ba;\n if (2.0 * base.b < base.a) {\n ba = 2.0 * overlay.b * base.b + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n } else {\n ba = overlay.a * base.a - 2.0 * (base.a - base.b) * (overlay.a - overlay.b) + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n }\n \n gl_FragColor = vec4(ra, ga, ba, 1.0);\n }\n " -public let PassthroughFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n gl_FragColor = texture2D(inputImageTexture, textureCoordinate);\n }\n " -public let PinchDistortionFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform float aspectRatio;\n uniform vec2 center;\n uniform float radius;\n uniform float scale;\n \n void main()\n {\n vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n float dist = distance(center, textureCoordinateToUse);\n textureCoordinateToUse = textureCoordinate;\n \n if (dist < radius)\n {\n textureCoordinateToUse -= center;\n float percent = 1.0 + ((0.5 - dist) / 0.5) * scale;\n textureCoordinateToUse = textureCoordinateToUse * percent;\n textureCoordinateToUse += center;\n \n gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse );\n }\n else\n {\n gl_FragColor = texture2D(inputImageTexture, textureCoordinate );\n }\n }\n " -public let PixellateFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform float fractionalWidthOfPixel;\n uniform float aspectRatio;\n \n void main()\n {\n vec2 sampleDivisor = vec2(fractionalWidthOfPixel, fractionalWidthOfPixel / aspectRatio);\n \n vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor) + 0.5 * sampleDivisor;\n gl_FragColor = texture2D(inputImageTexture, samplePos );\n }\n " -public let PolarPixellateFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform vec2 center;\n uniform vec2 pixelSize;\n \n \n void main()\n {\n vec2 normCoord = 2.0 * textureCoordinate - 1.0;\n vec2 normCenter = 2.0 * center - 1.0;\n \n normCoord -= normCenter;\n \n float r = length(normCoord); // to polar coords\n float phi = atan(normCoord.y, normCoord.x); // to polar coords\n \n r = r - mod(r, pixelSize.x) + 0.03;\n phi = phi - mod(phi, pixelSize.y);\n \n normCoord.x = r * cos(phi);\n normCoord.y = r * sin(phi);\n \n normCoord += normCenter;\n \n vec2 textureCoordinateToUse = normCoord / 2.0 + 0.5;\n \n gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse );\n \n }\n " -public let PolkaDotFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform float fractionalWidthOfPixel;\n uniform float aspectRatio;\n uniform float dotScaling;\n \n void main()\n {\n vec2 sampleDivisor = vec2(fractionalWidthOfPixel, fractionalWidthOfPixel / aspectRatio);\n \n vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor) + 0.5 * sampleDivisor;\n vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n vec2 adjustedSamplePos = vec2(samplePos.x, (samplePos.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n float distanceFromSamplePoint = distance(adjustedSamplePos, textureCoordinateToUse);\n float checkForPresenceWithinDot = step(distanceFromSamplePoint, (fractionalWidthOfPixel * 0.5) * dotScaling);\n \n vec4 inputColor = texture2D(inputImageTexture, samplePos);\n \n gl_FragColor = vec4(inputColor.rgb * checkForPresenceWithinDot, inputColor.a);\n }\n " -public let PosterizeFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float colorLevels;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = floor((textureColor * colorLevels) + vec4(0.5)) / colorLevels;\n }\n " -public let PrewittEdgeDetectionFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float edgeStrength;\n \n void main()\n {\n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n float h = -topLeftIntensity - topIntensity - topRightIntensity + bottomLeftIntensity + bottomIntensity + bottomRightIntensity;\n float v = -bottomLeftIntensity - leftIntensity - topLeftIntensity + bottomRightIntensity + rightIntensity + topRightIntensity;\n \n float mag = length(vec2(h, v)) * edgeStrength;\n \n gl_FragColor = vec4(vec3(mag), 1.0);\n }\n " -public let RGBAdjustmentFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float redAdjustment;\n uniform float greenAdjustment;\n uniform float blueAdjustment;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = vec4(textureColor.r * redAdjustment, textureColor.g * greenAdjustment, textureColor.b * blueAdjustment, textureColor.a);\n }\n " -public let SaturationBlendFragmentShader = "// Saturation blend mode based upon pseudo code from the PDF specification.\n \n varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n float lum(vec3 c) {\n return dot(c, vec3(0.3, 0.59, 0.11));\n }\n \n vec3 clipcolor(vec3 c) {\n float l = lum(c);\n float n = min(min(c.r, c.g), c.b);\n float x = max(max(c.r, c.g), c.b);\n \n if (n < 0.0) {\n c.r = l + ((c.r - l) * l) / (l - n);\n c.g = l + ((c.g - l) * l) / (l - n);\n c.b = l + ((c.b - l) * l) / (l - n);\n }\n if (x > 1.0) {\n c.r = l + ((c.r - l) * (1.0 - l)) / (x - l);\n c.g = l + ((c.g - l) * (1.0 - l)) / (x - l);\n c.b = l + ((c.b - l) * (1.0 - l)) / (x - l);\n }\n \n return c;\n }\n \n vec3 setlum(vec3 c, float l) {\n float d = l - lum(c);\n c = c + vec3(d);\n return clipcolor(c);\n }\n \n float sat(vec3 c) {\n float n = min(min(c.r, c.g), c.b);\n float x = max(max(c.r, c.g), c.b);\n return x - n;\n }\n \n float mid(float cmin, float cmid, float cmax, float s) {\n return ((cmid - cmin) * s) / (cmax - cmin);\n }\n \n vec3 setsat(vec3 c, float s) {\n if (c.r > c.g) {\n if (c.r > c.b) {\n if (c.g > c.b) {\n /* g is mid, b is min */\n c.g = mid(c.b, c.g, c.r, s);\n c.b = 0.0;\n } else {\n /* b is mid, g is min */\n c.b = mid(c.g, c.b, c.r, s);\n c.g = 0.0;\n }\n c.r = s;\n } else {\n /* b is max, r is mid, g is min */\n c.r = mid(c.g, c.r, c.b, s);\n c.b = s;\n c.r = 0.0;\n }\n } else if (c.r > c.b) {\n /* g is max, r is mid, b is min */\n c.r = mid(c.b, c.r, c.g, s);\n c.g = s;\n c.b = 0.0;\n } else if (c.g > c.b) {\n /* g is max, b is mid, r is min */\n c.b = mid(c.r, c.b, c.g, s);\n c.g = s;\n c.r = 0.0;\n } else if (c.b > c.g) {\n /* b is max, g is mid, r is min */\n c.g = mid(c.r, c.g, c.b, s);\n c.b = s;\n c.r = 0.0;\n } else {\n c = vec3(0.0);\n }\n return c;\n }\n \n void main()\n {\n vec4 baseColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(setsat(baseColor.rgb, sat(overlayColor.rgb)), lum(baseColor.rgb)) * overlayColor.a, baseColor.a);\n }\n " -public let SaturationFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float saturation;\n \n // Values from \"Graphics Shaders: Theory and Practice\" by Bailey and Cunningham\n const vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n float luminance = dot(textureColor.rgb, luminanceWeighting);\n vec3 greyScaleColor = vec3(luminance);\n \n gl_FragColor = vec4(mix(greyScaleColor, textureColor.rgb, saturation), textureColor.w);\n \n }\n " -public let ScreenBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n vec4 whiteColor = vec4(1.0);\n gl_FragColor = whiteColor - ((whiteColor - textureColor2) * (whiteColor - textureColor));\n }\n " -public let SharpenVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n uniform float texelWidth; \n uniform float texelHeight; \n uniform float sharpness;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate; \n varying vec2 topTextureCoordinate;\n varying vec2 bottomTextureCoordinate;\n \n varying float centerMultiplier;\n varying float edgeMultiplier;\n \n void main()\n {\n gl_Position = position;\n \n vec2 widthStep = vec2(texelWidth, 0.0);\n vec2 heightStep = vec2(0.0, texelHeight);\n \n textureCoordinate = inputTextureCoordinate.xy;\n leftTextureCoordinate = inputTextureCoordinate.xy - widthStep;\n rightTextureCoordinate = inputTextureCoordinate.xy + widthStep;\n topTextureCoordinate = inputTextureCoordinate.xy + heightStep; \n bottomTextureCoordinate = inputTextureCoordinate.xy - heightStep;\n \n centerMultiplier = 1.0 + 4.0 * sharpness;\n edgeMultiplier = sharpness;\n }\n " -public let SharpenFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n varying vec2 topTextureCoordinate;\n varying vec2 bottomTextureCoordinate;\n \n varying float centerMultiplier;\n varying float edgeMultiplier;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n vec3 textureColor = texture2D(inputImageTexture, textureCoordinate).rgb;\n vec3 leftTextureColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb;\n vec3 rightTextureColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb;\n vec3 topTextureColor = texture2D(inputImageTexture, topTextureCoordinate).rgb;\n vec3 bottomTextureColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;\n \n gl_FragColor = vec4((textureColor * centerMultiplier - (leftTextureColor * edgeMultiplier + rightTextureColor * edgeMultiplier + topTextureColor * edgeMultiplier + bottomTextureColor * edgeMultiplier)), texture2D(inputImageTexture, bottomTextureCoordinate).w);\n }\n " -public let ShiTomasiFeatureDetectorFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float sensitivity;\n \n void main()\n {\n vec3 derivativeElements = texture2D(inputImageTexture, textureCoordinate).rgb;\n \n float derivativeDifference = derivativeElements.x - derivativeElements.y;\n float zElement = (derivativeElements.z * 2.0) - 1.0;\n \n // R = Ix^2 + Iy^2 - sqrt( (Ix^2 - Iy^2)^2 + 4 * Ixy * Ixy)\n float cornerness = derivativeElements.x + derivativeElements.y - sqrt(derivativeDifference * derivativeDifference + 4.0 * zElement * zElement);\n \n gl_FragColor = vec4(vec3(cornerness * sensitivity), 1.0);\n }\n " -public let SketchFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform float edgeStrength;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n \n float mag = 1.0 - (length(vec2(h, v)) * edgeStrength);\n \n gl_FragColor = vec4(vec3(mag), 1.0);\n }\n " -public let SobelEdgeDetectionFragmentShader = "// Code from \"Graphics Shaders: Theory and Practice\" by M. Bailey and S. Cunningham \n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float edgeStrength;\n \n void main()\n {\n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n \n float mag = length(vec2(h, v)) * edgeStrength;\n \n gl_FragColor = vec4(vec3(mag), 1.0);\n }\n " -public let SoftLightBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 base = texture2D(inputImageTexture, textureCoordinate);\n vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n float alphaDivisor = base.a + step(base.a, 0.0); // Protect against a divide-by-zero blacking out things in the output\n gl_FragColor = base * (overlay.a * (base / alphaDivisor) + (2.0 * overlay * (1.0 - (base / alphaDivisor)))) + overlay * (1.0 - base.a) + base * (1.0 - overlay.a);\n }\n " -public let SolarizeFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float threshold;\n \n const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n float luminance = dot(textureColor.rgb, W);\n float thresholdResult = step(luminance, threshold);\n vec3 finalColor = abs(thresholdResult - textureColor.rgb);\n \n gl_FragColor = vec4(vec3(finalColor), textureColor.w);\n }\n " -public let SourceOverBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate);\n \n gl_FragColor = mix(textureColor, textureColor2, textureColor2.a);\n }\n " -public let SphereRefractionFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform vec2 center;\n uniform float radius;\n uniform float aspectRatio;\n uniform float refractiveIndex;\n \n void main()\n {\n vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n float distanceFromCenter = distance(center, textureCoordinateToUse);\n float checkForPresenceWithinSphere = step(distanceFromCenter, radius);\n \n distanceFromCenter = distanceFromCenter / radius;\n \n float normalizedDepth = radius * sqrt(1.0 - distanceFromCenter * distanceFromCenter);\n vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - center, normalizedDepth));\n \n vec3 refractedVector = refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex);\n \n gl_FragColor = texture2D(inputImageTexture, (refractedVector.xy + 1.0) * 0.5) * checkForPresenceWithinSphere;\n }\n " -public let StretchDistortionFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform vec2 center;\n \n void main()\n {\n vec2 normCoord = 2.0 * textureCoordinate - 1.0;\n vec2 normCenter = 2.0 * center - 1.0;\n \n normCoord -= normCenter;\n vec2 s = sign(normCoord);\n normCoord = abs(normCoord);\n normCoord = 0.5 * normCoord + 0.5 * smoothstep(0.25, 0.5, normCoord) * normCoord;\n normCoord = s * normCoord;\n \n normCoord += normCenter;\n \n vec2 textureCoordinateToUse = normCoord / 2.0 + 0.5;\n \n gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse);\n }\n " -public let SubtractBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(textureColor.rgb - textureColor2.rgb, textureColor.a);\n }\n " -public let SwirlFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform vec2 center;\n uniform float radius;\n uniform float angle;\n \n void main()\n {\n vec2 textureCoordinateToUse = textureCoordinate;\n float dist = distance(center, textureCoordinate);\n if (dist < radius)\n {\n textureCoordinateToUse -= center;\n float percent = (radius - dist) / radius;\n float theta = percent * percent * angle * 8.0;\n float s = sin(theta);\n float c = cos(theta);\n textureCoordinateToUse = vec2(dot(textureCoordinateToUse, vec2(c, -s)), dot(textureCoordinateToUse, vec2(s, c)));\n textureCoordinateToUse += center;\n }\n \n gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse );\n }\n " -public let ThreeInputVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n attribute vec4 inputTextureCoordinate2;\n attribute vec4 inputTextureCoordinate3;\n \n varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n varying vec2 textureCoordinate3;\n \n void main()\n {\n gl_Position = position;\n textureCoordinate = inputTextureCoordinate.xy;\n textureCoordinate2 = inputTextureCoordinate2.xy;\n textureCoordinate3 = inputTextureCoordinate3.xy;\n }\n " -public let ThresholdEdgeDetectionFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float threshold;\n \n uniform float edgeStrength;\n \n void main()\n {\n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n h = max(0.0, h);\n float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n v = max(0.0, v);\n \n float mag = length(vec2(h, v)) * edgeStrength;\n mag = step(threshold, mag);\n \n gl_FragColor = vec4(vec3(mag), 1.0);\n }\n " -public let ThresholdSketchFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float threshold;\n \n uniform float edgeStrength;\n \n void main()\n {\n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n h = max(0.0, h);\n float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n v = max(0.0, v);\n \n float mag = length(vec2(h, v)) * edgeStrength;\n mag = 1.0 - step(threshold, mag);\n \n gl_FragColor = vec4(vec3(mag), 1.0);\n }\n " -public let ThresholdedNonMaximumSuppressionFragmentShader = "uniform sampler2D inputImageTexture;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform float threshold;\n \n void main()\n {\n float bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n vec4 centerColor = texture2D(inputImageTexture, textureCoordinate);\n float leftColor = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightColor = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float topColor = texture2D(inputImageTexture, topTextureCoordinate).r;\n float topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n \n // Use a tiebreaker for pixels to the left and immediately above this one\n float multiplier = 1.0 - step(centerColor.r, topColor);\n multiplier = multiplier * (1.0 - step(centerColor.r, topLeftColor));\n multiplier = multiplier * (1.0 - step(centerColor.r, leftColor));\n multiplier = multiplier * (1.0 - step(centerColor.r, bottomLeftColor));\n \n float maxValue = max(centerColor.r, bottomColor);\n maxValue = max(maxValue, bottomRightColor);\n maxValue = max(maxValue, rightColor);\n maxValue = max(maxValue, topRightColor);\n \n float finalValue = centerColor.r * step(maxValue, centerColor.r) * multiplier;\n finalValue = step(threshold, finalValue);\n \n gl_FragColor = vec4(finalValue, finalValue, finalValue, 1.0);\n //\n // gl_FragColor = vec4((centerColor.rgb * step(maxValue, step(threshold, centerColor.r)) * multiplier), 1.0);\n }\n " -public let TiltShiftFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform float topFocusLevel;\n uniform float bottomFocusLevel;\n uniform float focusFallOffRate;\n \n void main()\n {\n vec4 sharpImageColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 blurredImageColor = texture2D(inputImageTexture2, textureCoordinate2);\n \n float blurIntensity = 1.0 - smoothstep(topFocusLevel - focusFallOffRate, topFocusLevel, textureCoordinate2.y);\n blurIntensity += smoothstep(bottomFocusLevel, bottomFocusLevel + focusFallOffRate, textureCoordinate2.y);\n \n gl_FragColor = mix(sharpImageColor, blurredImageColor, blurIntensity);\n }\n " -public let ToonFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform float intensity;\n uniform float threshold;\n uniform float quantizationLevels;\n \n const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n \n float mag = length(vec2(h, v));\n \n vec3 posterizedImageColor = floor((textureColor.rgb * quantizationLevels) + 0.5) / quantizationLevels;\n \n float thresholdTest = 1.0 - step(threshold, mag);\n \n gl_FragColor = vec4(posterizedImageColor * thresholdTest, textureColor.a);\n }\n " -public let TransformVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n uniform mat4 transformMatrix;\n uniform mat4 orthographicMatrix;\n \n varying vec2 textureCoordinate;\n \n void main()\n {\n gl_Position = transformMatrix * vec4(position.xyz, 1.0) * orthographicMatrix;\n textureCoordinate = inputTextureCoordinate.xy;\n }\n " -public let TwoInputVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n attribute vec4 inputTextureCoordinate2;\n \n varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n void main()\n {\n gl_Position = position;\n textureCoordinate = inputTextureCoordinate.xy;\n textureCoordinate2 = inputTextureCoordinate2.xy;\n }\n " -public let UnsharpMaskFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform float intensity;\n \n void main()\n {\n vec4 sharpImageColor = texture2D(inputImageTexture, textureCoordinate);\n vec3 blurredImageColor = texture2D(inputImageTexture2, textureCoordinate2).rgb;\n \n gl_FragColor = vec4(sharpImageColor.rgb * intensity + blurredImageColor * (1.0 - intensity), sharpImageColor.a);\n }\n " -public let VibranceFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float vibrance;\n \n void main() {\n vec4 color = texture2D(inputImageTexture, textureCoordinate);\n float average = (color.r + color.g + color.b) / 3.0;\n float mx = max(color.r, max(color.g, color.b));\n float amt = (mx - average) * (-vibrance * 3.0);\n color.rgb = mix(color.rgb, vec3(mx), amt);\n gl_FragColor = color;\n }\n " -public let VignetteFragmentShader = "uniform sampler2D inputImageTexture;\n varying vec2 textureCoordinate;\n \n uniform vec2 vignetteCenter;\n uniform vec3 vignetteColor;\n uniform float vignetteStart;\n uniform float vignetteEnd;\n \n void main()\n {\n vec4 sourceImageColor = texture2D(inputImageTexture, textureCoordinate);\n float d = distance(textureCoordinate, vec2(vignetteCenter.x, vignetteCenter.y));\n float percent = smoothstep(vignetteStart, vignetteEnd, d);\n gl_FragColor = vec4(mix(sourceImageColor.rgb, vignetteColor, percent), sourceImageColor.a);\n }\n " -public let WeakPixelInclusionFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n float centerIntensity = texture2D(inputImageTexture, textureCoordinate).r;\n \n float pixelIntensitySum = bottomLeftIntensity + topRightIntensity + topLeftIntensity + bottomRightIntensity + leftIntensity + rightIntensity + bottomIntensity + topIntensity + centerIntensity;\n float sumTest = step(1.5, pixelIntensitySum);\n float pixelTest = step(0.01, centerIntensity);\n \n gl_FragColor = vec4(vec3(sumTest * pixelTest), 1.0);\n }\n " -public let WhiteBalanceFragmentShader = "uniform sampler2D inputImageTexture;\n varying vec2 textureCoordinate;\n \n uniform float temperature;\n uniform float tint;\n \n const vec3 warmFilter = vec3(0.93, 0.54, 0.0);\n \n const mat3 RGBtoYIQ = mat3(0.299, 0.587, 0.114, 0.596, -0.274, -0.322, 0.212, -0.523, 0.311);\n const mat3 YIQtoRGB = mat3(1.0, 0.956, 0.621, 1.0, -0.272, -0.647, 1.0, -1.105, 1.702);\n \n void main()\n {\n vec4 source = texture2D(inputImageTexture, textureCoordinate);\n \n vec3 yiq = RGBtoYIQ * source.rgb; //adjusting tint\n yiq.b = clamp(yiq.b + tint*0.5226*0.1, -0.5226, 0.5226);\n vec3 rgb = YIQtoRGB * yiq;\n \n vec3 processed = vec3(\n (rgb.r < 0.5 ? (2.0 * rgb.r * warmFilter.r) : (1.0 - 2.0 * (1.0 - rgb.r) * (1.0 - warmFilter.r))), //adjusting temperature\n (rgb.g < 0.5 ? (2.0 * rgb.g * warmFilter.g) : (1.0 - 2.0 * (1.0 - rgb.g) * (1.0 - warmFilter.g))),\n (rgb.b < 0.5 ? (2.0 * rgb.b * warmFilter.b) : (1.0 - 2.0 * (1.0 - rgb.b) * (1.0 - warmFilter.b))));\n \n gl_FragColor = vec4(mix(rgb, processed, temperature), source.a);\n }\n " -public let XYDerivativeFragmentShader = "// I'm using the Prewitt operator to obtain the derivative, then squaring the X and Y components and placing the product of the two in Z.\n // In tests, Prewitt seemed to be tied with Sobel for the best, and it's just a little cheaper to compute.\n // This is primarily intended to be used with corner detection filters.\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n \n float verticalDerivative = -topLeftIntensity - topIntensity - topRightIntensity + bottomLeftIntensity + bottomIntensity + bottomRightIntensity;\n float horizontalDerivative = -bottomLeftIntensity - leftIntensity - topLeftIntensity + bottomRightIntensity + rightIntensity + topRightIntensity;\n verticalDerivative = verticalDerivative;\n horizontalDerivative = horizontalDerivative;\n \n // Scaling the X * Y operation so that negative numbers are not clipped in the 0..1 range. This will be expanded in the corner detection filter\n gl_FragColor = vec4(horizontalDerivative * horizontalDerivative, verticalDerivative * verticalDerivative, ((verticalDerivative * horizontalDerivative) + 1.0) / 2.0, 1.0);\n }\n " -public let YUVConversionFullRangeUVPlanarFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n varying vec2 textureCoordinate3;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n uniform sampler2D inputImageTexture3;\n \n uniform mat3 colorConversionMatrix;\n \n void main()\n {\n vec3 yuv;\n \n yuv.x = texture2D(inputImageTexture, textureCoordinate).r;\n yuv.y = texture2D(inputImageTexture2, textureCoordinate).r - 0.5;\n yuv.z = texture2D(inputImageTexture3, textureCoordinate).r - 0.5;\n vec3 rgb = colorConversionMatrix * yuv;\n \n gl_FragColor = vec4(rgb, 1.0);\n }\n " -public let YUVConversionFullRangeFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform mat3 colorConversionMatrix;\n \n void main()\n {\n vec3 yuv;\n \n yuv.x = texture2D(inputImageTexture, textureCoordinate).r;\n yuv.yz = texture2D(inputImageTexture2, textureCoordinate).ra - vec2(0.5, 0.5);\n vec3 rgb = colorConversionMatrix * yuv;\n \n gl_FragColor = vec4(rgb, 1.0);\n }\n " -public let YUVConversionVideoRangeFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform mat3 colorConversionMatrix;\n \n void main()\n {\n vec3 yuv;\n \n yuv.x = texture2D(inputImageTexture, textureCoordinate).r - (16.0/255.0);\n yuv.yz = texture2D(inputImageTexture2, textureCoordinate).ra - vec2(0.5, 0.5);\n vec3 rgb = colorConversionMatrix * yuv;\n \n gl_FragColor = vec4(rgb, 1.0);\n }\n " -public let ZoomBlurFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform vec2 blurCenter;\n uniform float blurSize;\n \n void main()\n {\n // TODO: Do a more intelligent scaling based on resolution here\n vec2 samplingOffset = 1.0/100.0 * (blurCenter - textureCoordinate) * blurSize;\n \n vec4 fragmentColor = texture2D(inputImageTexture, textureCoordinate) * 0.18;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate + samplingOffset) * 0.15;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate + (2.0 * samplingOffset)) * 0.12;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate + (3.0 * samplingOffset)) * 0.09;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate + (4.0 * samplingOffset)) * 0.05;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate - samplingOffset) * 0.15;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate - (2.0 * samplingOffset)) * 0.12;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate - (3.0 * samplingOffset)) * 0.09;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate - (4.0 * samplingOffset)) * 0.05;\n \n gl_FragColor = fragmentColor;\n }\n " +public let AdaptiveThresholdFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + float blurredInput = texture2D(inputImageTexture, textureCoordinate).r; + float localLuminance = texture2D(inputImageTexture2, textureCoordinate2).r; + float thresholdResult = step(blurredInput - 0.05, localLuminance); + + gl_FragColor = vec4(vec3(thresholdResult), 1.0); +} +""" +public let AddBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 base = texture2D(inputImageTexture, textureCoordinate); + vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2); + + float r; + if (overlay.r * base.a + base.r * overlay.a >= overlay.a * base.a) { + r = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a); + } else { + r = overlay.r + base.r; + } + + float g; + if (overlay.g * base.a + base.g * overlay.a >= overlay.a * base.a) { + g = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a); + } else { + g = overlay.g + base.g; + } + + float b; + if (overlay.b * base.a + base.b * overlay.a >= overlay.a * base.a) { + b = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a); + } else { + b = overlay.b + base.b; + } + + float a = overlay.a + base.a - overlay.a * base.a; + + gl_FragColor = vec4(r, g, b, a); +} +""" +public let AlphaBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +uniform float mixturePercent; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = vec4(mix(textureColor.rgb, textureColor2.rgb, textureColor2.a * mixturePercent), textureColor.a); +} +""" +public let AlphaTestFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + vec4 color = texture2D(inputImageTexture, textureCoordinate); + if (color.a < 0.5) + { + discard; + } + else + { + gl_FragColor = color; + } +} +""" +public let AverageColorVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 upperLeftInputTextureCoordinate; +varying vec2 upperRightInputTextureCoordinate; +varying vec2 lowerLeftInputTextureCoordinate; +varying vec2 lowerRightInputTextureCoordinate; + +void main() +{ + gl_Position = position; + + upperLeftInputTextureCoordinate = inputTextureCoordinate.xy + vec2(-texelWidth, -texelHeight); + upperRightInputTextureCoordinate = inputTextureCoordinate.xy + vec2(texelWidth, -texelHeight); + lowerLeftInputTextureCoordinate = inputTextureCoordinate.xy + vec2(-texelWidth, texelHeight); + lowerRightInputTextureCoordinate = inputTextureCoordinate.xy + vec2(texelWidth, texelHeight); +} +""" +public let AverageColorFragmentShader = """ +uniform sampler2D inputImageTexture; + +varying vec2 outputTextureCoordinate; + +varying vec2 upperLeftInputTextureCoordinate; +varying vec2 upperRightInputTextureCoordinate; +varying vec2 lowerLeftInputTextureCoordinate; +varying vec2 lowerRightInputTextureCoordinate; + +void main() +{ + vec4 upperLeftColor = texture2D(inputImageTexture, upperLeftInputTextureCoordinate); + vec4 upperRightColor = texture2D(inputImageTexture, upperRightInputTextureCoordinate); + vec4 lowerLeftColor = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate); + vec4 lowerRightColor = texture2D(inputImageTexture, lowerRightInputTextureCoordinate); + + gl_FragColor = 0.25 * (upperLeftColor + upperRightColor + lowerLeftColor + lowerRightColor); +} +""" +public let AverageLuminanceFragmentShader = """ +uniform sampler2D inputImageTexture; + +varying vec2 outputTextureCoordinate; + +varying vec2 upperLeftInputTextureCoordinate; +varying vec2 upperRightInputTextureCoordinate; +varying vec2 lowerLeftInputTextureCoordinate; +varying vec2 lowerRightInputTextureCoordinate; + +void main() +{ + float upperLeftLuminance = texture2D(inputImageTexture, upperLeftInputTextureCoordinate).r; + float upperRightLuminance = texture2D(inputImageTexture, upperRightInputTextureCoordinate).r; + float lowerLeftLuminance = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate).r; + float lowerRightLuminance = texture2D(inputImageTexture, lowerRightInputTextureCoordinate).r; + + float luminosity = 0.25 * (upperLeftLuminance + upperRightLuminance + lowerLeftLuminance + lowerRightLuminance); + gl_FragColor = vec4(luminosity, luminosity, luminosity, 1.0); +} +""" +public let BilateralBlurVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; + +const int GAUSSIAN_SAMPLES = 9; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 textureCoordinate; +varying vec2 blurCoordinates[GAUSSIAN_SAMPLES]; + +void main() +{ + gl_Position = position; + textureCoordinate = inputTextureCoordinate.xy; + + // Calculate the positions for the blur + int multiplier = 0; + vec2 blurStep; + vec2 singleStepOffset = vec2(texelWidth, texelHeight); + + for (int i = 0; i < GAUSSIAN_SAMPLES; i++) + { + multiplier = (i - ((GAUSSIAN_SAMPLES - 1) / 2)); + // Blur in x (horizontal) + blurStep = float(multiplier) * singleStepOffset; + blurCoordinates[i] = inputTextureCoordinate.xy + blurStep; + } +} +""" +public let BilateralBlurFragmentShader = """ +uniform sampler2D inputImageTexture; + +const int GAUSSIAN_SAMPLES = 9; + +varying vec2 textureCoordinate; +varying vec2 blurCoordinates[GAUSSIAN_SAMPLES]; + +uniform float distanceNormalizationFactor; + +void main() +{ + vec4 centralColor; + float gaussianWeightTotal; + vec4 sum; + vec4 sampleColor; + float distanceFromCentralColor; + float gaussianWeight; + + centralColor = texture2D(inputImageTexture, blurCoordinates[4]); + gaussianWeightTotal = 0.18; + sum = centralColor * 0.18; + + sampleColor = texture2D(inputImageTexture, blurCoordinates[0]); + distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0); + gaussianWeight = 0.05 * (1.0 - distanceFromCentralColor); + gaussianWeightTotal += gaussianWeight; + sum += sampleColor * gaussianWeight; + + sampleColor = texture2D(inputImageTexture, blurCoordinates[1]); + distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0); + gaussianWeight = 0.09 * (1.0 - distanceFromCentralColor); + gaussianWeightTotal += gaussianWeight; + sum += sampleColor * gaussianWeight; + + sampleColor = texture2D(inputImageTexture, blurCoordinates[2]); + distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0); + gaussianWeight = 0.12 * (1.0 - distanceFromCentralColor); + gaussianWeightTotal += gaussianWeight; + sum += sampleColor * gaussianWeight; + + sampleColor = texture2D(inputImageTexture, blurCoordinates[3]); + distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0); + gaussianWeight = 0.15 * (1.0 - distanceFromCentralColor); + gaussianWeightTotal += gaussianWeight; + sum += sampleColor * gaussianWeight; + + sampleColor = texture2D(inputImageTexture, blurCoordinates[5]); + distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0); + gaussianWeight = 0.15 * (1.0 - distanceFromCentralColor); + gaussianWeightTotal += gaussianWeight; + sum += sampleColor * gaussianWeight; + + sampleColor = texture2D(inputImageTexture, blurCoordinates[6]); + distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0); + gaussianWeight = 0.12 * (1.0 - distanceFromCentralColor); + gaussianWeightTotal += gaussianWeight; + sum += sampleColor * gaussianWeight; + + sampleColor = texture2D(inputImageTexture, blurCoordinates[7]); + distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0); + gaussianWeight = 0.09 * (1.0 - distanceFromCentralColor); + gaussianWeightTotal += gaussianWeight; + sum += sampleColor * gaussianWeight; + + sampleColor = texture2D(inputImageTexture, blurCoordinates[8]); + distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0); + gaussianWeight = 0.05 * (1.0 - distanceFromCentralColor); + gaussianWeightTotal += gaussianWeight; + sum += sampleColor * gaussianWeight; + + gl_FragColor = sum / gaussianWeightTotal; +} +""" +public let BrightnessFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float brightness; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = vec4((textureColor.rgb + vec3(brightness)), textureColor.w); +} + +""" +public let BulgeDistortionFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform float aspectRatio; +uniform vec2 center; +uniform float radius; +uniform float scale; + +void main() +{ + vec2 textureCoordinateToUse = vec2(textureCoordinate.x, ((textureCoordinate.y - center.y) * aspectRatio) + center.y); + float dist = distance(center, textureCoordinateToUse); + textureCoordinateToUse = textureCoordinate; + + if (dist < radius) + { + textureCoordinateToUse -= center; + float percent = 1.0 - ((radius - dist) / radius) * scale; + percent = percent * percent; + + textureCoordinateToUse = textureCoordinateToUse * percent; + textureCoordinateToUse += center; + } + + gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse ); +} +""" +public let CGAColorspaceFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + vec2 sampleDivisor = vec2(1.0 / 200.0, 1.0 / 320.0); + //highp vec4 colorDivisor = vec4(colorDepth); + + vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor); + vec4 color = texture2D(inputImageTexture, samplePos ); + + //gl_FragColor = texture2D(inputImageTexture, samplePos ); + vec4 colorCyan = vec4(85.0 / 255.0, 1.0, 1.0, 1.0); + vec4 colorMagenta = vec4(1.0, 85.0 / 255.0, 1.0, 1.0); + vec4 colorWhite = vec4(1.0, 1.0, 1.0, 1.0); + vec4 colorBlack = vec4(0.0, 0.0, 0.0, 1.0); + + vec4 endColor; + float blackDistance = distance(color, colorBlack); + float whiteDistance = distance(color, colorWhite); + float magentaDistance = distance(color, colorMagenta); + float cyanDistance = distance(color, colorCyan); + + vec4 finalColor; + + float colorDistance = min(magentaDistance, cyanDistance); + colorDistance = min(colorDistance, whiteDistance); + colorDistance = min(colorDistance, blackDistance); + + if (colorDistance == blackDistance) { + finalColor = colorBlack; + } else if (colorDistance == whiteDistance) { + finalColor = colorWhite; + } else if (colorDistance == cyanDistance) { + finalColor = colorCyan; + } else { + finalColor = colorMagenta; + } + + gl_FragColor = finalColor; +} + +""" +public let ChromaKeyBlendFragmentShader = """ +// Shader code based on Apple's CIChromaKeyFilter example: https://developer.apple.com/library/mac/#samplecode/CIChromaKeyFilter/Introduction/Intro.html + +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform float thresholdSensitivity; +uniform float smoothing; +uniform vec3 colorToReplace; +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + + float maskY = 0.2989 * colorToReplace.r + 0.5866 * colorToReplace.g + 0.1145 * colorToReplace.b; + float maskCr = 0.7132 * (colorToReplace.r - maskY); + float maskCb = 0.5647 * (colorToReplace.b - maskY); + + float Y = 0.2989 * textureColor.r + 0.5866 * textureColor.g + 0.1145 * textureColor.b; + float Cr = 0.7132 * (textureColor.r - Y); + float Cb = 0.5647 * (textureColor.b - Y); + + // float blendValue = 1.0 - smoothstep(thresholdSensitivity - smoothing, thresholdSensitivity , abs(Cr - maskCr) + abs(Cb - maskCb)); + float blendValue = 1.0 - smoothstep(thresholdSensitivity, thresholdSensitivity + smoothing, distance(vec2(Cr, Cb), vec2(maskCr, maskCb))); + gl_FragColor = mix(textureColor, textureColor2, blendValue); +} +""" +public let ChromaKeyFragmentShader = """ +// Shader code based on Apple's CIChromaKeyFilter example: https://developer.apple.com/library/mac/#samplecode/CIChromaKeyFilter/Introduction/Intro.html + +varying vec2 textureCoordinate; + +uniform float thresholdSensitivity; +uniform float smoothing; +uniform vec3 colorToReplace; +uniform sampler2D inputImageTexture; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + float maskY = 0.2989 * colorToReplace.r + 0.5866 * colorToReplace.g + 0.1145 * colorToReplace.b; + float maskCr = 0.7132 * (colorToReplace.r - maskY); + float maskCb = 0.5647 * (colorToReplace.b - maskY); + + float Y = 0.2989 * textureColor.r + 0.5866 * textureColor.g + 0.1145 * textureColor.b; + float Cr = 0.7132 * (textureColor.r - Y); + float Cb = 0.5647 * (textureColor.b - Y); + + // float blendValue = 1.0 - smoothstep(thresholdSensitivity - smoothing, thresholdSensitivity , abs(Cr - maskCr) + abs(Cb - maskCb)); + float blendValue = smoothstep(thresholdSensitivity, thresholdSensitivity + smoothing, distance(vec2(Cr, Cb), vec2(maskCr, maskCb))); + gl_FragColor = vec4(textureColor.rgb, textureColor.a * blendValue); +} +""" +public let CircleVertexShader = """ +attribute vec4 position; +varying vec2 currentPosition; +uniform float aspectRatio; + +void main() +{ + currentPosition = vec2(position.x, position.y * aspectRatio); + gl_Position = position; +} +""" +public let CircleFragmentShader = """ +uniform vec4 circleColor; +uniform vec4 backgroundColor; +uniform vec2 center; +uniform float radius; + +varying vec2 currentPosition; + +void main() +{ + float distanceFromCenter = distance(center, currentPosition); + float checkForPresenceWithinCircle = step(distanceFromCenter, radius); + + gl_FragColor = mix(backgroundColor, circleColor, checkForPresenceWithinCircle); +} +""" +public let ColorBlendFragmentShader = """ +// Color blend mode based upon pseudo code from the PDF specification. + +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +float lum(vec3 c) { + return dot(c, vec3(0.3, 0.59, 0.11)); +} + +vec3 clipcolor(vec3 c) { + float l = lum(c); + float n = min(min(c.r, c.g), c.b); + float x = max(max(c.r, c.g), c.b); + + if (n < 0.0) { + c.r = l + ((c.r - l) * l) / (l - n); + c.g = l + ((c.g - l) * l) / (l - n); + c.b = l + ((c.b - l) * l) / (l - n); + } + if (x > 1.0) { + c.r = l + ((c.r - l) * (1.0 - l)) / (x - l); + c.g = l + ((c.g - l) * (1.0 - l)) / (x - l); + c.b = l + ((c.b - l) * (1.0 - l)) / (x - l); + } + + return c; +} + +vec3 setlum(vec3 c, float l) { + float d = l - lum(c); + c = c + vec3(d); + return clipcolor(c); +} + +void main() +{ + vec4 baseColor = texture2D(inputImageTexture, textureCoordinate); + vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(overlayColor.rgb, lum(baseColor.rgb)) * overlayColor.a, baseColor.a); +} +""" +public let ColorBurnBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + vec4 whiteColor = vec4(1.0); + gl_FragColor = whiteColor - (whiteColor - textureColor) / textureColor2; +} +""" +public let ColorDodgeBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 base = texture2D(inputImageTexture, textureCoordinate); + vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2); + + vec3 baseOverlayAlphaProduct = vec3(overlay.a * base.a); + vec3 rightHandProduct = overlay.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlay.a); + + vec3 firstBlendColor = baseOverlayAlphaProduct + rightHandProduct; + vec3 overlayRGB = clamp((overlay.rgb / clamp(overlay.a, 0.01, 1.0)) * step(0.0, overlay.a), 0.0, 0.99); + + vec3 secondBlendColor = (base.rgb * overlay.a) / (1.0 - overlayRGB) + rightHandProduct; + + vec3 colorChoice = step((overlay.rgb * base.a + base.rgb * overlay.a), baseOverlayAlphaProduct); + + gl_FragColor = vec4(mix(firstBlendColor, secondBlendColor, colorChoice), 1.0); +} +""" +public let ColorInvertFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = vec4((1.0 - textureColor.rgb), textureColor.w); +} +""" +public let ColorLocalBinaryPatternFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + vec3 centerColor = texture2D(inputImageTexture, textureCoordinate).rgb; + vec3 bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb; + vec3 topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).rgb; + vec3 topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb; + vec3 bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb; + vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb; + vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb; + vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb; + vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb; + + float redByteTally = 1.0 / 255.0 * step(centerColor.r, topRightColor.r); + redByteTally += 2.0 / 255.0 * step(centerColor.r, topColor.r); + redByteTally += 4.0 / 255.0 * step(centerColor.r, topLeftColor.r); + redByteTally += 8.0 / 255.0 * step(centerColor.r, leftColor.r); + redByteTally += 16.0 / 255.0 * step(centerColor.r, bottomLeftColor.r); + redByteTally += 32.0 / 255.0 * step(centerColor.r, bottomColor.r); + redByteTally += 64.0 / 255.0 * step(centerColor.r, bottomRightColor.r); + redByteTally += 128.0 / 255.0 * step(centerColor.r, rightColor.r); + + float blueByteTally = 1.0 / 255.0 * step(centerColor.b, topRightColor.b); + blueByteTally += 2.0 / 255.0 * step(centerColor.b, topColor.b); + blueByteTally += 4.0 / 255.0 * step(centerColor.b, topLeftColor.b); + blueByteTally += 8.0 / 255.0 * step(centerColor.b, leftColor.b); + blueByteTally += 16.0 / 255.0 * step(centerColor.b, bottomLeftColor.b); + blueByteTally += 32.0 / 255.0 * step(centerColor.b, bottomColor.b); + blueByteTally += 64.0 / 255.0 * step(centerColor.b, bottomRightColor.b); + blueByteTally += 128.0 / 255.0 * step(centerColor.b, rightColor.b); + + float greenByteTally = 1.0 / 255.0 * step(centerColor.g, topRightColor.g); + greenByteTally += 2.0 / 255.0 * step(centerColor.g, topColor.g); + greenByteTally += 4.0 / 255.0 * step(centerColor.g, topLeftColor.g); + greenByteTally += 8.0 / 255.0 * step(centerColor.g, leftColor.g); + greenByteTally += 16.0 / 255.0 * step(centerColor.g, bottomLeftColor.g); + greenByteTally += 32.0 / 255.0 * step(centerColor.g, bottomColor.g); + greenByteTally += 64.0 / 255.0 * step(centerColor.g, bottomRightColor.g); + greenByteTally += 128.0 / 255.0 * step(centerColor.g, rightColor.g); + + // TODO: Replace the above with a dot product and two vec4s + // TODO: Apply step to a matrix, rather than individually + + gl_FragColor = vec4(redByteTally, blueByteTally, greenByteTally, 1.0); +} +""" +public let ColorMatrixFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform mat4 colorMatrix; +uniform float intensity; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + vec4 outputColor = textureColor * colorMatrix; + + gl_FragColor = (intensity * outputColor) + ((1.0 - intensity) * textureColor); +} +""" +public let ColorSwizzlingFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + gl_FragColor = texture2D(inputImageTexture, textureCoordinate).bgra; +} +""" +public let ColourFASTDecriptorVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; +attribute vec4 inputTextureCoordinate2; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 textureCoordinate; +varying vec2 pointATextureCoordinate; +varying vec2 pointBTextureCoordinate; +varying vec2 pointCTextureCoordinate; +varying vec2 pointDTextureCoordinate; +varying vec2 pointETextureCoordinate; +varying vec2 pointFTextureCoordinate; +varying vec2 pointGTextureCoordinate; +varying vec2 pointHTextureCoordinate; + +void main() +{ + gl_Position = position; + + float tripleTexelWidth = 3.0 * texelWidth; + float tripleTexelHeight = 3.0 * texelHeight; + + textureCoordinate = inputTextureCoordinate.xy; + + pointATextureCoordinate = vec2(inputTextureCoordinate2.x + tripleTexelWidth, textureCoordinate.y + texelHeight); + pointBTextureCoordinate = vec2(inputTextureCoordinate2.x + texelWidth, textureCoordinate.y + tripleTexelHeight); + pointCTextureCoordinate = vec2(inputTextureCoordinate2.x - texelWidth, textureCoordinate.y + tripleTexelHeight); + pointDTextureCoordinate = vec2(inputTextureCoordinate2.x - tripleTexelWidth, textureCoordinate.y + texelHeight); + pointETextureCoordinate = vec2(inputTextureCoordinate2.x - tripleTexelWidth, textureCoordinate.y - texelHeight); + pointFTextureCoordinate = vec2(inputTextureCoordinate2.x - texelWidth, textureCoordinate.y - tripleTexelHeight); + pointGTextureCoordinate = vec2(inputTextureCoordinate2.x + texelWidth, textureCoordinate.y - tripleTexelHeight); + pointHTextureCoordinate = vec2(inputTextureCoordinate2.x + tripleTexelWidth, textureCoordinate.y - texelHeight); +} +""" +public let ColourFASTDecriptorFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 pointATextureCoordinate; +varying vec2 pointBTextureCoordinate; +varying vec2 pointCTextureCoordinate; +varying vec2 pointDTextureCoordinate; +varying vec2 pointETextureCoordinate; +varying vec2 pointFTextureCoordinate; +varying vec2 pointGTextureCoordinate; +varying vec2 pointHTextureCoordinate; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; +const float PITwo = 6.2832; +const float PI = 3.1416; +void main() +{ + vec3 centerColor = texture2D(inputImageTexture, textureCoordinate).rgb; + + vec3 pointAColor = texture2D(inputImageTexture2, pointATextureCoordinate).rgb; + vec3 pointBColor = texture2D(inputImageTexture2, pointBTextureCoordinate).rgb; + vec3 pointCColor = texture2D(inputImageTexture2, pointCTextureCoordinate).rgb; + vec3 pointDColor = texture2D(inputImageTexture2, pointDTextureCoordinate).rgb; + vec3 pointEColor = texture2D(inputImageTexture2, pointETextureCoordinate).rgb; + vec3 pointFColor = texture2D(inputImageTexture2, pointFTextureCoordinate).rgb; + vec3 pointGColor = texture2D(inputImageTexture2, pointGTextureCoordinate).rgb; + vec3 pointHColor = texture2D(inputImageTexture2, pointHTextureCoordinate).rgb; + + vec3 colorComparison = ((pointAColor + pointBColor + pointCColor + pointDColor + pointEColor + pointFColor + pointGColor + pointHColor) * 0.125) - centerColor; + + // Direction calculation drawn from Appendix B of Seth Hall's Ph.D. thesis + + vec3 dirX = (pointAColor*0.94868) + (pointBColor*0.316227) - (pointCColor*0.316227) - (pointDColor*0.94868) - (pointEColor*0.94868) - (pointFColor*0.316227) + (pointGColor*0.316227) + (pointHColor*0.94868); + vec3 dirY = (pointAColor*0.316227) + (pointBColor*0.94868) + (pointCColor*0.94868) + (pointDColor*0.316227) - (pointEColor*0.316227) - (pointFColor*0.94868) - (pointGColor*0.94868) - (pointHColor*0.316227); + vec3 absoluteDifference = abs(colorComparison); + float componentLength = length(colorComparison); + float avgX = dot(absoluteDifference, dirX) / componentLength; + float avgY = dot(absoluteDifference, dirY) / componentLength; + float angle = atan(avgY, avgX); + + vec3 normalizedColorComparison = (colorComparison + 1.0) * 0.5; + + gl_FragColor = vec4(normalizedColorComparison, (angle+PI)/PITwo); +} +""" +public let ContrastFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float contrast; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = vec4(((textureColor.rgb - vec3(0.5)) * contrast + vec3(0.5)), textureColor.w); +} +""" +public let Convolution3x3FragmentShader = """ +uniform sampler2D inputImageTexture; + +uniform mat3 convolutionMatrix; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +void main() +{ + vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb; + vec3 bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb; + vec3 bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb; + vec4 centerColor = texture2D(inputImageTexture, textureCoordinate); + vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb; + vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb; + vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb; + vec3 topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).rgb; + vec3 topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb; + + vec3 resultColor = topLeftColor * convolutionMatrix[0][0] + topColor * convolutionMatrix[0][1] + topRightColor * convolutionMatrix[0][2]; + resultColor += leftColor * convolutionMatrix[1][0] + centerColor.rgb * convolutionMatrix[1][1] + rightColor * convolutionMatrix[1][2]; + resultColor += bottomLeftColor * convolutionMatrix[2][0] + bottomColor * convolutionMatrix[2][1] + bottomRightColor * convolutionMatrix[2][2]; + + gl_FragColor = vec4(resultColor, centerColor.a); +} +""" +public let CrosshairVertexShader = """ +attribute vec4 position; + +uniform float crosshairWidth; + +varying vec2 centerLocation; +varying float pointSpacing; + +void main() +{ + gl_Position = vec4(((position.xy * 2.0) - 1.0), 0.0, 1.0); + gl_PointSize = crosshairWidth + 1.0; + pointSpacing = 1.0 / crosshairWidth; + centerLocation = vec2(pointSpacing * ceil(crosshairWidth / 2.0), pointSpacing * ceil(crosshairWidth / 2.0)); +} +""" +public let CrosshairFragmentShader = """ +#version 120 + +uniform vec3 crosshairColor; + +varying vec2 centerLocation; +varying float pointSpacing; + +void main() +{ + vec2 distanceFromCenter = abs(centerLocation - gl_PointCoord.xy); + float axisTest = step(pointSpacing, gl_PointCoord.y) * step(distanceFromCenter.x, 0.09) + step(pointSpacing, gl_PointCoord.x) * step(distanceFromCenter.y, 0.09); + + gl_FragColor = vec4(crosshairColor * axisTest, axisTest); + // gl_FragColor = vec4(distanceFromCenterInX, distanceFromCenterInY, 0.0, 1.0); +} + +""" +public let CrosshatchFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform float crossHatchSpacing; +uniform float lineWidth; + +const vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + float luminance = dot(texture2D(inputImageTexture, textureCoordinate).rgb, W); + + vec4 colorToDisplay = vec4(1.0, 1.0, 1.0, 1.0); + if (luminance < 1.00) + { + if (mod(textureCoordinate.x + textureCoordinate.y, crossHatchSpacing) <= lineWidth) + { + colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0); + } + } + if (luminance < 0.75) + { + if (mod(textureCoordinate.x - textureCoordinate.y, crossHatchSpacing) <= lineWidth) + { + colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0); + } + } + if (luminance < 0.50) + { + if (mod(textureCoordinate.x + textureCoordinate.y - (crossHatchSpacing / 2.0), crossHatchSpacing) <= lineWidth) + { + colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0); + } + } + if (luminance < 0.3) + { + if (mod(textureCoordinate.x - textureCoordinate.y - (crossHatchSpacing / 2.0), crossHatchSpacing) <= lineWidth) + { + colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0); + } + } + + gl_FragColor = colorToDisplay; +} +""" +public let DarkenBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 base = texture2D(inputImageTexture, textureCoordinate); + vec4 overlayer = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = vec4(min(overlayer.rgb * base.a, base.rgb * overlayer.a) + overlayer.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlayer.a), 1.0); +} +""" +public let DifferenceBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + gl_FragColor = vec4(abs(textureColor2.rgb - textureColor.rgb), textureColor.a); +} +""" +public let Dilation1FragmentShader = """ +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate); + vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate); + vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate); + + vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity); + + gl_FragColor = max(maxValue, oneStepNegativeIntensity); +} +""" +public let Dilation2FragmentShader = """ +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate); + vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate); + vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate); + vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate); + vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate); + + vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity); + maxValue = max(maxValue, oneStepNegativeIntensity); + maxValue = max(maxValue, twoStepsPositiveIntensity); + maxValue = max(maxValue, twoStepsNegativeIntensity); + + gl_FragColor = max(maxValue, twoStepsNegativeIntensity); +} +""" +public let Dilation3FragmentShader = """ +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; +varying vec2 threeStepsPositiveTextureCoordinate; +varying vec2 threeStepsNegativeTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate); + vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate); + vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate); + vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate); + vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate); + vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate); + vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate); + + vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity); + maxValue = max(maxValue, oneStepNegativeIntensity); + maxValue = max(maxValue, twoStepsPositiveIntensity); + maxValue = max(maxValue, twoStepsNegativeIntensity); + maxValue = max(maxValue, threeStepsPositiveIntensity); + + gl_FragColor = max(maxValue, threeStepsNegativeIntensity); +} +""" +public let Dilation4FragmentShader = """ +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; +varying vec2 threeStepsPositiveTextureCoordinate; +varying vec2 threeStepsNegativeTextureCoordinate; +varying vec2 fourStepsPositiveTextureCoordinate; +varying vec2 fourStepsNegativeTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate); + vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate); + vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate); + vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate); + vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate); + vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate); + vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate); + vec4 fourStepsPositiveIntensity = texture2D(inputImageTexture, fourStepsPositiveTextureCoordinate); + vec4 fourStepsNegativeIntensity = texture2D(inputImageTexture, fourStepsNegativeTextureCoordinate); + + vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity); + maxValue = max(maxValue, oneStepNegativeIntensity); + maxValue = max(maxValue, twoStepsPositiveIntensity); + maxValue = max(maxValue, twoStepsNegativeIntensity); + maxValue = max(maxValue, threeStepsPositiveIntensity); + maxValue = max(maxValue, threeStepsNegativeIntensity); + maxValue = max(maxValue, fourStepsPositiveIntensity); + + gl_FragColor = max(maxValue, fourStepsNegativeIntensity); +} +""" +public let DirectionalNonMaximumSuppressionFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float texelWidth; +uniform float texelHeight; +uniform float upperThreshold; +uniform float lowerThreshold; + +void main() +{ + vec3 currentGradientAndDirection = texture2D(inputImageTexture, textureCoordinate).rgb; + vec2 gradientDirection = ((currentGradientAndDirection.gb * 2.0) - 1.0) * vec2(texelWidth, texelHeight); + + float firstSampledGradientMagnitude = texture2D(inputImageTexture, textureCoordinate + gradientDirection).r; + float secondSampledGradientMagnitude = texture2D(inputImageTexture, textureCoordinate - gradientDirection).r; + + float multiplier = step(firstSampledGradientMagnitude, currentGradientAndDirection.r); + multiplier = multiplier * step(secondSampledGradientMagnitude, currentGradientAndDirection.r); + + float thresholdCompliance = smoothstep(lowerThreshold, upperThreshold, currentGradientAndDirection.r); + multiplier = multiplier * thresholdCompliance; + + gl_FragColor = vec4(multiplier, multiplier, multiplier, 1.0); +} +""" +public let DirectionalSobelEdgeDetectionFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + + vec2 gradientDirection; + gradientDirection.x = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity; + gradientDirection.y = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity; + + float gradientMagnitude = length(gradientDirection); + vec2 normalizedDirection = normalize(gradientDirection); + normalizedDirection = sign(normalizedDirection) * floor(abs(normalizedDirection) + 0.617316); // Offset by 1-sin(pi/8) to set to 0 if near axis, 1 if away + normalizedDirection = (normalizedDirection + 1.0) * 0.5; // Place -1.0 - 1.0 within 0 - 1.0 + + gl_FragColor = vec4(gradientMagnitude, normalizedDirection.x, normalizedDirection.y, 1.0); +} +""" +public let DissolveBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; +uniform float mixturePercent; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = mix(textureColor, textureColor2, mixturePercent); +} +""" +public let DivideBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 base = texture2D(inputImageTexture, textureCoordinate); + vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2); + + float ra; + if (overlay.a == 0.0 || ((base.r / overlay.r) > (base.a / overlay.a))) + ra = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a); + else + ra = (base.r * overlay.a * overlay.a) / overlay.r + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a); + + + float ga; + if (overlay.a == 0.0 || ((base.g / overlay.g) > (base.a / overlay.a))) + ga = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a); + else + ga = (base.g * overlay.a * overlay.a) / overlay.g + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a); + + + float ba; + if (overlay.a == 0.0 || ((base.b / overlay.b) > (base.a / overlay.a))) + ba = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a); + else + ba = (base.b * overlay.a * overlay.a) / overlay.b + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a); + + float a = overlay.a + base.a - overlay.a * base.a; + + gl_FragColor = vec4(ra, ga, ba, a); +} +""" +public let Erosion1FragmentShader = """ +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate); + vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate); + vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate); + + vec4 minValue = min(centerIntensity, oneStepPositiveIntensity); + + gl_FragColor = min(minValue, oneStepNegativeIntensity); +} +""" +public let Erosion2FragmentShader = """ +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate); + vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate); + vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate); + vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate); + vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate); + + vec4 minValue = min(centerIntensity, oneStepPositiveIntensity); + minValue = min(minValue, oneStepNegativeIntensity); + minValue = min(minValue, twoStepsPositiveIntensity); + + gl_FragColor = min(minValue, twoStepsNegativeIntensity); +} +""" +public let Erosion3FragmentShader = """ +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; +varying vec2 threeStepsPositiveTextureCoordinate; +varying vec2 threeStepsNegativeTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate); + vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate); + vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate); + vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate); + vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate); + vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate); + vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate); + + vec4 minValue = min(centerIntensity, oneStepPositiveIntensity); + minValue = min(minValue, oneStepNegativeIntensity); + minValue = min(minValue, twoStepsPositiveIntensity); + minValue = min(minValue, twoStepsNegativeIntensity); + minValue = min(minValue, threeStepsPositiveIntensity); + + gl_FragColor = min(minValue, threeStepsNegativeIntensity); +} +""" +public let Erosion4FragmentShader = """ +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; +varying vec2 threeStepsPositiveTextureCoordinate; +varying vec2 threeStepsNegativeTextureCoordinate; +varying vec2 fourStepsPositiveTextureCoordinate; +varying vec2 fourStepsNegativeTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate); + vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate); + vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate); + vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate); + vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate); + vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate); + vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate); + vec4 fourStepsPositiveIntensity = texture2D(inputImageTexture, fourStepsPositiveTextureCoordinate); + vec4 fourStepsNegativeIntensity = texture2D(inputImageTexture, fourStepsNegativeTextureCoordinate); + + vec4 minValue = min(centerIntensity, oneStepPositiveIntensity); + minValue = min(minValue, oneStepNegativeIntensity); + minValue = min(minValue, twoStepsPositiveIntensity); + minValue = min(minValue, twoStepsNegativeIntensity); + minValue = min(minValue, threeStepsPositiveIntensity); + minValue = min(minValue, threeStepsNegativeIntensity); + minValue = min(minValue, fourStepsPositiveIntensity); + + gl_FragColor = min(minValue, fourStepsNegativeIntensity); +} +""" +public let ErosionDilation1VertexShader = """ +attribute vec4 position; +attribute vec2 inputTextureCoordinate; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; + +void main() +{ + gl_Position = position; + + vec2 offset = vec2(texelWidth, texelHeight); + + centerTextureCoordinate = inputTextureCoordinate; + oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset; + oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset; +} +""" +public let ErosionDilation2VertexShader = """ +attribute vec4 position; +attribute vec2 inputTextureCoordinate; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; + +void main() +{ + gl_Position = position; + + vec2 offset = vec2(texelWidth, texelHeight); + + centerTextureCoordinate = inputTextureCoordinate; + oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset; + oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset; + twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0); + twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0); +} +""" +public let ErosionDilation3VertexShader = """ +attribute vec4 position; +attribute vec2 inputTextureCoordinate; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; +varying vec2 threeStepsPositiveTextureCoordinate; +varying vec2 threeStepsNegativeTextureCoordinate; + +void main() +{ + gl_Position = position; + + vec2 offset = vec2(texelWidth, texelHeight); + + centerTextureCoordinate = inputTextureCoordinate; + oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset; + oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset; + twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0); + twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0); + threeStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 3.0); + threeStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 3.0); +} +""" +public let ErosionDilation4VertexShader = """ +attribute vec4 position; +attribute vec2 inputTextureCoordinate; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; +varying vec2 threeStepsPositiveTextureCoordinate; +varying vec2 threeStepsNegativeTextureCoordinate; +varying vec2 fourStepsPositiveTextureCoordinate; +varying vec2 fourStepsNegativeTextureCoordinate; + +void main() +{ + gl_Position = position; + + vec2 offset = vec2(texelWidth, texelHeight); + + centerTextureCoordinate = inputTextureCoordinate; + oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset; + oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset; + twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0); + twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0); + threeStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 3.0); + threeStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 3.0); + fourStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 4.0); + fourStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 4.0); +} +""" +public let ExclusionBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 base = texture2D(inputImageTexture, textureCoordinate); + vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2); + + // Dca = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa) + + gl_FragColor = vec4((overlay.rgb * base.a + base.rgb * overlay.a - 2.0 * overlay.rgb * base.rgb) + overlay.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlay.a), base.a); +} +""" +public let ExposureFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float exposure; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = vec4(textureColor.rgb * pow(2.0, exposure), textureColor.w); +} +""" +public let FalseColorFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float intensity; +uniform vec3 firstColor; +uniform vec3 secondColor; + +const vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + float luminance = dot(textureColor.rgb, luminanceWeighting); + + gl_FragColor = vec4( mix(firstColor.rgb, secondColor.rgb, luminance), textureColor.a); +} +""" +public let FiveInputVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; +attribute vec4 inputTextureCoordinate2; +attribute vec4 inputTextureCoordinate3; +attribute vec4 inputTextureCoordinate4; +attribute vec4 inputTextureCoordinate5; + +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; +varying vec2 textureCoordinate3; +varying vec2 textureCoordinate4; +varying vec2 textureCoordinate5; + +void main() +{ + gl_Position = position; + textureCoordinate = inputTextureCoordinate.xy; + textureCoordinate2 = inputTextureCoordinate2.xy; + textureCoordinate3 = inputTextureCoordinate3.xy; + textureCoordinate4 = inputTextureCoordinate4.xy; + textureCoordinate5 = inputTextureCoordinate5.xy; +} +""" +public let FourInputVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; +attribute vec4 inputTextureCoordinate2; +attribute vec4 inputTextureCoordinate3; +attribute vec4 inputTextureCoordinate4; + +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; +varying vec2 textureCoordinate3; +varying vec2 textureCoordinate4; + +void main() +{ + gl_Position = position; + textureCoordinate = inputTextureCoordinate.xy; + textureCoordinate2 = inputTextureCoordinate2.xy; + textureCoordinate3 = inputTextureCoordinate3.xy; + textureCoordinate4 = inputTextureCoordinate4.xy; +} +""" +public let GammaFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float gamma; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = vec4(pow(textureColor.rgb, vec3(gamma)), textureColor.w); +} +""" +public let GlassSphereFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform vec2 center; +uniform float radius; +uniform float aspectRatio; +uniform float refractiveIndex; +// uniform vec3 lightPosition; +const vec3 lightPosition = vec3(-0.5, 0.5, 1.0); +const vec3 ambientLightPosition = vec3(0.0, 0.0, 1.0); + +void main() +{ + vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); + float distanceFromCenter = distance(center, textureCoordinateToUse); + float checkForPresenceWithinSphere = step(distanceFromCenter, radius); + + distanceFromCenter = distanceFromCenter / radius; + + float normalizedDepth = radius * sqrt(1.0 - distanceFromCenter * distanceFromCenter); + vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - center, normalizedDepth)); + + vec3 refractedVector = 2.0 * refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex); + refractedVector.xy = -refractedVector.xy; + + vec3 finalSphereColor = texture2D(inputImageTexture, (refractedVector.xy + 1.0) * 0.5).rgb; + + // Grazing angle lighting + float lightingIntensity = 2.5 * (1.0 - pow(clamp(dot(ambientLightPosition, sphereNormal), 0.0, 1.0), 0.25)); + finalSphereColor += lightingIntensity; + + // Specular lighting + lightingIntensity = clamp(dot(normalize(lightPosition), sphereNormal), 0.0, 1.0); + lightingIntensity = pow(lightingIntensity, 15.0); + finalSphereColor += vec3(0.8, 0.8, 0.8) * lightingIntensity; + + gl_FragColor = vec4(finalSphereColor, 1.0) * checkForPresenceWithinSphere; +} +""" +public let HalftoneFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform float fractionalWidthOfPixel; +uniform float aspectRatio; + +const vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + vec2 sampleDivisor = vec2(fractionalWidthOfPixel, fractionalWidthOfPixel / aspectRatio); + + vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor) + 0.5 * sampleDivisor; + vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); + vec2 adjustedSamplePos = vec2(samplePos.x, (samplePos.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); + float distanceFromSamplePoint = distance(adjustedSamplePos, textureCoordinateToUse); + + vec3 sampledColor = texture2D(inputImageTexture, samplePos ).rgb; + float dotScaling = 1.0 - dot(sampledColor, W); + + float checkForPresenceWithinDot = 1.0 - step(distanceFromSamplePoint, (fractionalWidthOfPixel * 0.5) * dotScaling); + + gl_FragColor = vec4(vec3(checkForPresenceWithinDot), 1.0); +} +""" +public let HardLightBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +const vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + vec4 base = texture2D(inputImageTexture, textureCoordinate); + vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2); + + float ra; + if (2.0 * overlay.r < overlay.a) { + ra = 2.0 * overlay.r * base.r + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a); + } else { + ra = overlay.a * base.a - 2.0 * (base.a - base.r) * (overlay.a - overlay.r) + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a); + } + + float ga; + if (2.0 * overlay.g < overlay.a) { + ga = 2.0 * overlay.g * base.g + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a); + } else { + ga = overlay.a * base.a - 2.0 * (base.a - base.g) * (overlay.a - overlay.g) + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a); + } + + float ba; + if (2.0 * overlay.b < overlay.a) { + ba = 2.0 * overlay.b * base.b + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a); + } else { + ba = overlay.a * base.a - 2.0 * (base.a - base.b) * (overlay.a - overlay.b) + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a); + } + + gl_FragColor = vec4(ra, ga, ba, 1.0); +} +""" +public let HarrisCornerDetectorFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float sensitivity; + +const float harrisConstant = 0.04; + +void main() +{ + vec3 derivativeElements = texture2D(inputImageTexture, textureCoordinate).rgb; + + float derivativeSum = derivativeElements.x + derivativeElements.y; + + float zElement = (derivativeElements.z * 2.0) - 1.0; + + // R = Ix^2 * Iy^2 - Ixy * Ixy - k * (Ix^2 + Iy^2)^2 + float cornerness = derivativeElements.x * derivativeElements.y - (zElement * zElement) - harrisConstant * derivativeSum * derivativeSum; + + gl_FragColor = vec4(vec3(cornerness * sensitivity), 1.0); +} +""" +public let HazeFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform float hazeDistance; +uniform float slope; + +void main() +{ + //todo reconsider precision modifiers + vec4 color = vec4(1.0);//todo reimplement as a parameter + + float d = textureCoordinate.y * slope + hazeDistance; + + vec4 c = texture2D(inputImageTexture, textureCoordinate) ; // consider using unpremultiply + + c = (c - d * color) / (1.0 -d); + + gl_FragColor = c; //consider using premultiply(c); +} +""" +public let HighlightShadowTintFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float shadowTintIntensity; +uniform float highlightTintIntensity; +uniform vec3 shadowTintColor; +uniform vec3 highlightTintColor; + +const vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + float luminance = dot(textureColor.rgb, luminanceWeighting); + + vec4 shadowResult = mix(textureColor, max(textureColor, vec4( mix(shadowTintColor, textureColor.rgb, luminance), textureColor.a)), shadowTintIntensity); + vec4 highlightResult = mix(textureColor, min(shadowResult, vec4( mix(shadowResult.rgb, highlightTintColor.rgb, luminance), textureColor.a)), highlightTintIntensity); + + gl_FragColor = vec4( mix(shadowResult.rgb, highlightResult.rgb, luminance), textureColor.a); +} +""" +public let HighlightShadowFragmentShader = """ +uniform sampler2D inputImageTexture; +varying vec2 textureCoordinate; + +uniform float shadows; +uniform float highlights; + +const vec3 luminanceWeighting = vec3(0.3, 0.3, 0.3); + +void main() +{ + vec4 source = texture2D(inputImageTexture, textureCoordinate); + float luminance = dot(source.rgb, luminanceWeighting); + + float shadow = clamp((pow(luminance, 1.0/(shadows+1.0)) + (-0.76)*pow(luminance, 2.0/(shadows+1.0))) - luminance, 0.0, 1.0); + float highlight = clamp((1.0 - (pow(1.0-luminance, 1.0/(2.0-highlights)) + (-0.8)*pow(1.0-luminance, 2.0/(2.0-highlights)))) - luminance, -1.0, 0.0); + vec3 result = vec3(0.0, 0.0, 0.0) + ((luminance + shadow + highlight) - 0.0) * ((source.rgb - vec3(0.0, 0.0, 0.0))/(luminance - 0.0)); + + gl_FragColor = vec4(result.rgb, source.a); +} +""" +public let HistogramAccumulationFragmentShader = """ +const float scalingFactor = 1.0 / 256.0; + +varying vec3 colorFactor; + +void main() +{ + gl_FragColor = vec4(colorFactor * scalingFactor , 1.0); +} +""" +public let HistogramBlueSamplingVertexShader = """ +attribute vec4 position; + +varying vec3 colorFactor; + +void main() +{ + colorFactor = vec3(0.0, 0.0, 1.0); + gl_Position = vec4(-1.0 + (position.z * 0.0078125), 0.0, 0.0, 1.0); + gl_PointSize = 1.0; +} +""" +public let HistogramDisplayVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; + +varying vec2 textureCoordinate; +varying float height; + +void main() +{ + gl_Position = position; + textureCoordinate = vec2(inputTextureCoordinate.x, 0.5); + height = 1.0 - inputTextureCoordinate.y; +} +""" +public let HistogramDisplayFragmentShader = """ +varying vec2 textureCoordinate; +varying float height; + +uniform sampler2D inputImageTexture; +vec4 backgroundColor = vec4(0.0, 0.0, 0.0, 0.0); + +void main() +{ + vec3 colorChannels = texture2D(inputImageTexture, textureCoordinate).rgb; + vec4 heightTest = vec4(step(height, colorChannels), 1.0); + gl_FragColor = mix(backgroundColor, heightTest, heightTest.r + heightTest.g + heightTest.b); +} +""" +public let HistogramEqualizationBlueFragmentShader = """ +varying vec2 textureCoordinate; +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + float blueCurveValue = texture2D(inputImageTexture2, vec2(textureColor.b, 0.0)).b; + + gl_FragColor = vec4(textureColor.r, textureColor.g, blueCurveValue, textureColor.a); +} +""" +public let HistogramEqualizationGreenFragmentShader = """ +varying vec2 textureCoordinate; +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + float greenCurveValue = texture2D(inputImageTexture2, vec2(textureColor.g, 0.0)).g; + + gl_FragColor = vec4(textureColor.r, greenCurveValue, textureColor.b, textureColor.a); +} +""" +public let HistogramEqualizationLuminanceFragmentShader = """ +varying vec2 textureCoordinate; +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +const vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + float luminance = dot(textureColor.rgb, W); + float newLuminance = texture2D(inputImageTexture2, vec2(luminance, 0.0)).r; + float deltaLuminance = newLuminance - luminance; + + float red = clamp(textureColor.r + deltaLuminance, 0.0, 1.0); + float green = clamp(textureColor.g + deltaLuminance, 0.0, 1.0); + float blue = clamp(textureColor.b + deltaLuminance, 0.0, 1.0); + + gl_FragColor = vec4(red, green, blue, textureColor.a); +} +""" +public let HistogramEqualizationRGBFragmentShader = """ +varying vec2 textureCoordinate; +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + float redCurveValue = texture2D(inputImageTexture2, vec2(textureColor.r, 0.0)).r; + float greenCurveValue = texture2D(inputImageTexture2, vec2(textureColor.g, 0.0)).g; + float blueCurveValue = texture2D(inputImageTexture2, vec2(textureColor.b, 0.0)).b; + + gl_FragColor = vec4(redCurveValue, greenCurveValue, blueCurveValue, textureColor.a); +} +""" +public let HistogramEqualizationRedFragmentShader = """ +varying vec2 textureCoordinate; +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + float redCurveValue = texture2D(inputImageTexture2, vec2(textureColor.r, 0.0)).r; + + gl_FragColor = vec4(redCurveValue, textureColor.g, textureColor.b, textureColor.a); +} +""" +public let HistogramGreenSamplingVertexShader = """ +attribute vec4 position; + +varying vec3 colorFactor; + +void main() +{ + colorFactor = vec3(0.0, 1.0, 0.0); + gl_Position = vec4(-1.0 + (position.y * 0.0078125), 0.0, 0.0, 1.0); + gl_PointSize = 1.0; +} +""" +public let HistogramLuminanceSamplingVertexShader = """ +attribute vec4 position; + +varying vec3 colorFactor; + +const vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + float luminance = dot(position.xyz, W); + + colorFactor = vec3(1.0, 1.0, 1.0); + gl_Position = vec4(-1.0 + (luminance * 0.0078125), 0.0, 0.0, 1.0); + gl_PointSize = 1.0; +} +""" +public let HistogramRedSamplingVertexShader = """ +attribute vec4 position; + +varying vec3 colorFactor; + +void main() +{ + colorFactor = vec3(1.0, 0.0, 0.0); + gl_Position = vec4(-1.0 + (position.x * 0.0078125), 0.0, 0.0, 1.0); + gl_PointSize = 1.0; +} +""" +public let HueBlendFragmentShader = """ +// Hue blend mode based upon pseudo code from the PDF specification. + +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +float lum(vec3 c) { + return dot(c, vec3(0.3, 0.59, 0.11)); +} + +vec3 clipcolor(vec3 c) { + float l = lum(c); + float n = min(min(c.r, c.g), c.b); + float x = max(max(c.r, c.g), c.b); + + if (n < 0.0) { + c.r = l + ((c.r - l) * l) / (l - n); + c.g = l + ((c.g - l) * l) / (l - n); + c.b = l + ((c.b - l) * l) / (l - n); + } + if (x > 1.0) { + c.r = l + ((c.r - l) * (1.0 - l)) / (x - l); + c.g = l + ((c.g - l) * (1.0 - l)) / (x - l); + c.b = l + ((c.b - l) * (1.0 - l)) / (x - l); + } + + return c; +} + +vec3 setlum(vec3 c, float l) { + float d = l - lum(c); + c = c + vec3(d); + return clipcolor(c); +} + +float sat(vec3 c) { + float n = min(min(c.r, c.g), c.b); + float x = max(max(c.r, c.g), c.b); + return x - n; +} + +float mid(float cmin, float cmid, float cmax, float s) { + return ((cmid - cmin) * s) / (cmax - cmin); +} + +vec3 setsat(vec3 c, float s) { + if (c.r > c.g) { + if (c.r > c.b) { + if (c.g > c.b) { + /* g is mid, b is min */ + c.g = mid(c.b, c.g, c.r, s); + c.b = 0.0; + } else { + /* b is mid, g is min */ + c.b = mid(c.g, c.b, c.r, s); + c.g = 0.0; + } + c.r = s; + } else { + /* b is max, r is mid, g is min */ + c.r = mid(c.g, c.r, c.b, s); + c.b = s; + c.r = 0.0; + } + } else if (c.r > c.b) { + /* g is max, r is mid, b is min */ + c.r = mid(c.b, c.r, c.g, s); + c.g = s; + c.b = 0.0; + } else if (c.g > c.b) { + /* g is max, b is mid, r is min */ + c.b = mid(c.r, c.b, c.g, s); + c.g = s; + c.r = 0.0; + } else if (c.b > c.g) { + /* b is max, g is mid, r is min */ + c.g = mid(c.r, c.g, c.b, s); + c.b = s; + c.r = 0.0; + } else { + c = vec3(0.0); + } + return c; +} + +void main() +{ + vec4 baseColor = texture2D(inputImageTexture, textureCoordinate); + vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(setsat(overlayColor.rgb, sat(baseColor.rgb)), lum(baseColor.rgb)) * overlayColor.a, baseColor.a); +} +""" +public let HueFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float hueAdjust; +const vec4 kRGBToYPrime = vec4 (0.299, 0.587, 0.114, 0.0); +const vec4 kRGBToI = vec4 (0.595716, -0.274453, -0.321263, 0.0); +const vec4 kRGBToQ = vec4 (0.211456, -0.522591, 0.31135, 0.0); + +const vec4 kYIQToR = vec4 (1.0, 0.9563, 0.6210, 0.0); +const vec4 kYIQToG = vec4 (1.0, -0.2721, -0.6474, 0.0); +const vec4 kYIQToB = vec4 (1.0, -1.1070, 1.7046, 0.0); + +void main () +{ + // Sample the input pixel + vec4 color = texture2D(inputImageTexture, textureCoordinate); + + // Convert to YIQ + float YPrime = dot (color, kRGBToYPrime); + float I = dot (color, kRGBToI); + float Q = dot (color, kRGBToQ); + + // Calculate the hue and chroma + float hue = atan (Q, I); + float chroma = sqrt (I * I + Q * Q); + + // Make the user's adjustments + hue += (-hueAdjust); //why negative rotation? + + // Convert back to YIQ + Q = chroma * sin (hue); + I = chroma * cos (hue); + + // Convert back to RGB + vec4 yIQ = vec4 (YPrime, I, Q, 0.0); + color.r = dot (yIQ, kYIQToR); + color.g = dot (yIQ, kYIQToG); + color.b = dot (yIQ, kYIQToB); + + // Save the result + gl_FragColor = color; +} +""" +public let KuwaharaRadius3FragmentShader = """ +// Sourced from Kyprianidis, J. E., Kang, H., and Doellner, J. "Anisotropic Kuwahara Filtering on the GPU," GPU Pro p.247 (2010). +// +// Original header: +// +// Anisotropic Kuwahara Filtering on the GPU +// by Jan Eric Kyprianidis + +varying vec2 textureCoordinate; +uniform sampler2D inputImageTexture; + +const vec2 src_size = vec2 (1.0 / 768.0, 1.0 / 1024.0); + +void main (void) +{ + vec2 uv = textureCoordinate; + float n = float(16); // radius is assumed to be 3 + vec3 m0 = vec3(0.0); vec3 m1 = vec3(0.0); vec3 m2 = vec3(0.0); vec3 m3 = vec3(0.0); + vec3 s0 = vec3(0.0); vec3 s1 = vec3(0.0); vec3 s2 = vec3(0.0); vec3 s3 = vec3(0.0); + vec3 c; + vec3 cSq; + + c = texture2D(inputImageTexture, uv + vec2(-3,-3) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-3,-2) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-3,-1) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-3,0) * src_size).rgb; + cSq = c * c; + m0 += c; + s0 += cSq; + m1 += c; + s1 += cSq; + + c = texture2D(inputImageTexture, uv + vec2(-2,-3) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-2,-2) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-2,-1) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-2,0) * src_size).rgb; + cSq = c * c; + m0 += c; + s0 += cSq; + m1 += c; + s1 += cSq; + + c = texture2D(inputImageTexture, uv + vec2(-1,-3) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-1,-2) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-1,-1) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-1,0) * src_size).rgb; + cSq = c * c; + m0 += c; + s0 += cSq; + m1 += c; + s1 += cSq; + + c = texture2D(inputImageTexture, uv + vec2(0,-3) * src_size).rgb; + cSq = c * c; + m0 += c; + s0 += cSq; + m3 += c; + s3 += cSq; + c = texture2D(inputImageTexture, uv + vec2(0,-2) * src_size).rgb; + cSq = c * c; + m0 += c; + s0 += cSq; + m3 += c; + s3 += cSq; + c = texture2D(inputImageTexture, uv + vec2(0,-1) * src_size).rgb; + cSq = c * c; + m0 += c; + s0 += cSq; + m3 += c; + s3 += cSq; + c = texture2D(inputImageTexture, uv + vec2(0,0) * src_size).rgb; + cSq = c * c; + m0 += c; + s0 += cSq; + m1 += c; + s1 += cSq; + m2 += c; + s2 += cSq; + m3 += c; + s3 += cSq; + + c = texture2D(inputImageTexture, uv + vec2(-3,3) * src_size).rgb; + m1 += c; + s1 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-3,2) * src_size).rgb; + m1 += c; + s1 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-3,1) * src_size).rgb; + m1 += c; + s1 += c * c; + + c = texture2D(inputImageTexture, uv + vec2(-2,3) * src_size).rgb; + m1 += c; + s1 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-2,2) * src_size).rgb; + m1 += c; + s1 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-2,1) * src_size).rgb; + m1 += c; + s1 += c * c; + + c = texture2D(inputImageTexture, uv + vec2(-1,3) * src_size).rgb; + m1 += c; + s1 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-1,2) * src_size).rgb; + m1 += c; + s1 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-1,1) * src_size).rgb; + m1 += c; + s1 += c * c; + + c = texture2D(inputImageTexture, uv + vec2(0,3) * src_size).rgb; + cSq = c * c; + m1 += c; + s1 += cSq; + m2 += c; + s2 += cSq; + c = texture2D(inputImageTexture, uv + vec2(0,2) * src_size).rgb; + cSq = c * c; + m1 += c; + s1 += cSq; + m2 += c; + s2 += cSq; + c = texture2D(inputImageTexture, uv + vec2(0,1) * src_size).rgb; + cSq = c * c; + m1 += c; + s1 += cSq; + m2 += c; + s2 += cSq; + + c = texture2D(inputImageTexture, uv + vec2(3,3) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(3,2) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(3,1) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(3,0) * src_size).rgb; + cSq = c * c; + m2 += c; + s2 += cSq; + m3 += c; + s3 += cSq; + + c = texture2D(inputImageTexture, uv + vec2(2,3) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(2,2) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(2,1) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(2,0) * src_size).rgb; + cSq = c * c; + m2 += c; + s2 += cSq; + m3 += c; + s3 += cSq; + + c = texture2D(inputImageTexture, uv + vec2(1,3) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(1,2) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(1,1) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(1,0) * src_size).rgb; + cSq = c * c; + m2 += c; + s2 += cSq; + m3 += c; + s3 += cSq; + + c = texture2D(inputImageTexture, uv + vec2(3,-3) * src_size).rgb; + m3 += c; + s3 += c * c; + c = texture2D(inputImageTexture, uv + vec2(3,-2) * src_size).rgb; + m3 += c; + s3 += c * c; + c = texture2D(inputImageTexture, uv + vec2(3,-1) * src_size).rgb; + m3 += c; + s3 += c * c; + + c = texture2D(inputImageTexture, uv + vec2(2,-3) * src_size).rgb; + m3 += c; + s3 += c * c; + c = texture2D(inputImageTexture, uv + vec2(2,-2) * src_size).rgb; + m3 += c; + s3 += c * c; + c = texture2D(inputImageTexture, uv + vec2(2,-1) * src_size).rgb; + m3 += c; + s3 += c * c; + + c = texture2D(inputImageTexture, uv + vec2(1,-3) * src_size).rgb; + m3 += c; + s3 += c * c; + c = texture2D(inputImageTexture, uv + vec2(1,-2) * src_size).rgb; + m3 += c; + s3 += c * c; + c = texture2D(inputImageTexture, uv + vec2(1,-1) * src_size).rgb; + m3 += c; + s3 += c * c; + + float min_sigma2 = 1e+2; + m0 /= n; + s0 = abs(s0 / n - m0 * m0); + + float sigma2 = s0.r + s0.g + s0.b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + gl_FragColor = vec4(m0, 1.0); + } + + m1 /= n; + s1 = abs(s1 / n - m1 * m1); + + sigma2 = s1.r + s1.g + s1.b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + gl_FragColor = vec4(m1, 1.0); + } + + m2 /= n; + s2 = abs(s2 / n - m2 * m2); + + sigma2 = s2.r + s2.g + s2.b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + gl_FragColor = vec4(m2, 1.0); + } + + m3 /= n; + s3 = abs(s3 / n - m3 * m3); + + sigma2 = s3.r + s3.g + s3.b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + gl_FragColor = vec4(m3, 1.0); + } +} +""" +public let KuwaharaFragmentShader = """ +// Sourced from Kyprianidis, J. E., Kang, H., and Doellner, J. "Anisotropic Kuwahara Filtering on the GPU," GPU Pro p.247 (2010). +// +// Original header: +// +// Anisotropic Kuwahara Filtering on the GPU +// by Jan Eric Kyprianidis + +varying vec2 textureCoordinate; +uniform sampler2D inputImageTexture; +uniform int radius; + +const vec2 src_size = vec2 (1.0 / 768.0, 1.0 / 1024.0); + +void main (void) +{ + vec2 uv = textureCoordinate; + float n = float((radius + 1) * (radius + 1)); + int i; int j; + vec3 m0 = vec3(0.0); vec3 m1 = vec3(0.0); vec3 m2 = vec3(0.0); vec3 m3 = vec3(0.0); + vec3 s0 = vec3(0.0); vec3 s1 = vec3(0.0); vec3 s2 = vec3(0.0); vec3 s3 = vec3(0.0); + vec3 c; + + for (j = -radius; j <= 0; ++j) { + for (i = -radius; i <= 0; ++i) { + c = texture2D(inputImageTexture, uv + vec2(i,j) * src_size).rgb; + m0 += c; + s0 += c * c; + } + } + + for (j = -radius; j <= 0; ++j) { + for (i = 0; i <= radius; ++i) { + c = texture2D(inputImageTexture, uv + vec2(i,j) * src_size).rgb; + m1 += c; + s1 += c * c; + } + } + + for (j = 0; j <= radius; ++j) { + for (i = 0; i <= radius; ++i) { + c = texture2D(inputImageTexture, uv + vec2(i,j) * src_size).rgb; + m2 += c; + s2 += c * c; + } + } + + for (j = 0; j <= radius; ++j) { + for (i = -radius; i <= 0; ++i) { + c = texture2D(inputImageTexture, uv + vec2(i,j) * src_size).rgb; + m3 += c; + s3 += c * c; + } + } + + + float min_sigma2 = 1e+2; + m0 /= n; + s0 = abs(s0 / n - m0 * m0); + + float sigma2 = s0.r + s0.g + s0.b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + gl_FragColor = vec4(m0, 1.0); + } + + m1 /= n; + s1 = abs(s1 / n - m1 * m1); + + sigma2 = s1.r + s1.g + s1.b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + gl_FragColor = vec4(m1, 1.0); + } + + m2 /= n; + s2 = abs(s2 / n - m2 * m2); + + sigma2 = s2.r + s2.g + s2.b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + gl_FragColor = vec4(m2, 1.0); + } + + m3 /= n; + s3 = abs(s3 / n - m3 * m3); + + sigma2 = s3.r + s3.g + s3.b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + gl_FragColor = vec4(m3, 1.0); + } +} +""" +public let LanczosResamplingVertexShader = """ +attribute vec4 position; +attribute vec2 inputTextureCoordinate; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepLeftTextureCoordinate; +varying vec2 twoStepsLeftTextureCoordinate; +varying vec2 threeStepsLeftTextureCoordinate; +varying vec2 fourStepsLeftTextureCoordinate; +varying vec2 oneStepRightTextureCoordinate; +varying vec2 twoStepsRightTextureCoordinate; +varying vec2 threeStepsRightTextureCoordinate; +varying vec2 fourStepsRightTextureCoordinate; + +void main() +{ + gl_Position = position; + + vec2 firstOffset = vec2(texelWidth, texelHeight); + vec2 secondOffset = vec2(2.0 * texelWidth, 2.0 * texelHeight); + vec2 thirdOffset = vec2(3.0 * texelWidth, 3.0 * texelHeight); + vec2 fourthOffset = vec2(4.0 * texelWidth, 4.0 * texelHeight); + + centerTextureCoordinate = inputTextureCoordinate; + oneStepLeftTextureCoordinate = inputTextureCoordinate - firstOffset; + twoStepsLeftTextureCoordinate = inputTextureCoordinate - secondOffset; + threeStepsLeftTextureCoordinate = inputTextureCoordinate - thirdOffset; + fourStepsLeftTextureCoordinate = inputTextureCoordinate - fourthOffset; + oneStepRightTextureCoordinate = inputTextureCoordinate + firstOffset; + twoStepsRightTextureCoordinate = inputTextureCoordinate + secondOffset; + threeStepsRightTextureCoordinate = inputTextureCoordinate + thirdOffset; + fourStepsRightTextureCoordinate = inputTextureCoordinate + fourthOffset; +} +""" +public let LanczosResamplingFragmentShader = """ +uniform sampler2D inputImageTexture; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepLeftTextureCoordinate; +varying vec2 twoStepsLeftTextureCoordinate; +varying vec2 threeStepsLeftTextureCoordinate; +varying vec2 fourStepsLeftTextureCoordinate; +varying vec2 oneStepRightTextureCoordinate; +varying vec2 twoStepsRightTextureCoordinate; +varying vec2 threeStepsRightTextureCoordinate; +varying vec2 fourStepsRightTextureCoordinate; + +// sinc(x) * sinc(x/a) = (a * sin(pi * x) * sin(pi * x / a)) / (pi^2 * x^2) +// Assuming a Lanczos constant of 2.0, and scaling values to max out at x = +/- 1.5 + +void main() +{ + vec4 fragmentColor = texture2D(inputImageTexture, centerTextureCoordinate) * 0.38026; + + fragmentColor += texture2D(inputImageTexture, oneStepLeftTextureCoordinate) * 0.27667; + fragmentColor += texture2D(inputImageTexture, oneStepRightTextureCoordinate) * 0.27667; + + fragmentColor += texture2D(inputImageTexture, twoStepsLeftTextureCoordinate) * 0.08074; + fragmentColor += texture2D(inputImageTexture, twoStepsRightTextureCoordinate) * 0.08074; + + fragmentColor += texture2D(inputImageTexture, threeStepsLeftTextureCoordinate) * -0.02612; + fragmentColor += texture2D(inputImageTexture, threeStepsRightTextureCoordinate) * -0.02612; + + fragmentColor += texture2D(inputImageTexture, fourStepsLeftTextureCoordinate) * -0.02143; + fragmentColor += texture2D(inputImageTexture, fourStepsRightTextureCoordinate) * -0.02143; + + gl_FragColor = fragmentColor; +} +""" +public let LaplacianFragmentShader = """ +uniform sampler2D inputImageTexture; + +uniform mat3 convolutionMatrix; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +void main() +{ + vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb; + vec3 bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb; + vec3 bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb; + vec4 centerColor = texture2D(inputImageTexture, textureCoordinate); + vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb; + vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb; + vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb; + vec3 topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).rgb; + vec3 topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb; + + vec3 resultColor = topLeftColor * 0.5 + topColor * 1.0 + topRightColor * 0.5; + resultColor += leftColor * 1.0 + centerColor.rgb * (-6.0) + rightColor * 1.0; + resultColor += bottomLeftColor * 0.5 + bottomColor * 1.0 + bottomRightColor * 0.5; + + // Normalize the results to allow for negative gradients in the 0.0-1.0 colorspace + resultColor = resultColor + 0.5; + + gl_FragColor = vec4(resultColor, centerColor.a); +} +""" +public let LevelsFragmentShader = """ +/* + ** Gamma correction + ** Details: http://blog.mouaif.org/2009/01/22/photoshop-gamma-correction-shader/ + */ + +#define GammaCorrection(color, gamma) pow(color, 1.0 / gamma) + +/* + ** Levels control (input (+gamma), output) + ** Details: http://blog.mouaif.org/2009/01/28/levels-control-shader/ + */ + +#define LevelsControlInputRange(color, minInput, maxInput) min(max(color - minInput, vec3(0.0)) / (maxInput - minInput), vec3(1.0)) +#define LevelsControlInput(color, minInput, gamma, maxInput) GammaCorrection(LevelsControlInputRange(color, minInput, maxInput), gamma) +#define LevelsControlOutputRange(color, minOutput, maxOutput) mix(minOutput, maxOutput, color) +#define LevelsControl(color, minInput, gamma, maxInput, minOutput, maxOutput) LevelsControlOutputRange(LevelsControlInput(color, minInput, gamma, maxInput), minOutput, maxOutput) + +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform vec3 levelMinimum; +uniform vec3 levelMiddle; +uniform vec3 levelMaximum; +uniform vec3 minOutput; +uniform vec3 maxOutput; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = vec4(LevelsControl(textureColor.rgb, levelMinimum, levelMiddle, levelMaximum, minOutput, maxOutput), textureColor.a); +} + +""" +public let LightenBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = max(textureColor, textureColor2); +} +""" +public let LineVertexShader = """ +attribute vec4 position; + +void main() +{ + gl_Position = position; +} +""" +public let LineFragmentShader = """ +uniform vec3 lineColor; + +void main() +{ + gl_FragColor = vec4(lineColor, 1.0); +} +""" +public let LinearBurnBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = vec4(clamp(textureColor.rgb + textureColor2.rgb - vec3(1.0), vec3(0.0), vec3(1.0)), textureColor.a); +} +""" +public let LocalBinaryPatternFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + float centerIntensity = texture2D(inputImageTexture, textureCoordinate).r; + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + + float byteTally = 1.0 / 255.0 * step(centerIntensity, topRightIntensity); + byteTally += 2.0 / 255.0 * step(centerIntensity, topIntensity); + byteTally += 4.0 / 255.0 * step(centerIntensity, topLeftIntensity); + byteTally += 8.0 / 255.0 * step(centerIntensity, leftIntensity); + byteTally += 16.0 / 255.0 * step(centerIntensity, bottomLeftIntensity); + byteTally += 32.0 / 255.0 * step(centerIntensity, bottomIntensity); + byteTally += 64.0 / 255.0 * step(centerIntensity, bottomRightIntensity); + byteTally += 128.0 / 255.0 * step(centerIntensity, rightIntensity); + + // TODO: Replace the above with a dot product and two vec4s + // TODO: Apply step to a matrix, rather than individually + + gl_FragColor = vec4(byteTally, byteTally, byteTally, 1.0); +} +""" +public let LookupFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; // lookup texture + +uniform float intensity; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + float blueColor = textureColor.b * 63.0; + + vec2 quad1; + quad1.y = floor(floor(blueColor) / 8.0); + quad1.x = floor(blueColor) - (quad1.y * 8.0); + + vec2 quad2; + quad2.y = floor(ceil(blueColor) / 8.0); + quad2.x = ceil(blueColor) - (quad2.y * 8.0); + + vec2 texPos1; + texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r); + texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g); + + vec2 texPos2; + texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r); + texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g); + + vec4 newColor1 = texture2D(inputImageTexture2, texPos1); + vec4 newColor2 = texture2D(inputImageTexture2, texPos2); + + vec4 newColor = mix(newColor1, newColor2, fract(blueColor)); + gl_FragColor = mix(textureColor, vec4(newColor.rgb, textureColor.w), intensity); +} +""" +public let LuminanceRangeFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float rangeReduction; + +// Values from "Graphics Shaders: Theory and Practice" by Bailey and Cunningham +const vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + float luminance = dot(textureColor.rgb, luminanceWeighting); + float luminanceRatio = ((0.5 - luminance) * rangeReduction); + + gl_FragColor = vec4((textureColor.rgb) + (luminanceRatio), textureColor.w); +} +""" +public let LuminanceThresholdFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float threshold; + +const vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + float luminance = dot(textureColor.rgb, W); + float thresholdResult = step(threshold, luminance); + + gl_FragColor = vec4(vec3(thresholdResult), textureColor.w); +} +""" +public let LuminanceFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +// Values from "Graphics Shaders: Theory and Practice" by Bailey and Cunningham +const vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + float luminance = dot(textureColor.rgb, W); + + gl_FragColor = vec4(vec3(luminance), textureColor.a); +} +""" +public let LuminosityBlendFragmentShader = """ +// Luminosity blend mode based upon pseudo code from the PDF specification. + +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +float lum(vec3 c) { + return dot(c, vec3(0.3, 0.59, 0.11)); +} + +vec3 clipcolor(vec3 c) { + float l = lum(c); + float n = min(min(c.r, c.g), c.b); + float x = max(max(c.r, c.g), c.b); + + if (n < 0.0) { + c.r = l + ((c.r - l) * l) / (l - n); + c.g = l + ((c.g - l) * l) / (l - n); + c.b = l + ((c.b - l) * l) / (l - n); + } + if (x > 1.0) { + c.r = l + ((c.r - l) * (1.0 - l)) / (x - l); + c.g = l + ((c.g - l) * (1.0 - l)) / (x - l); + c.b = l + ((c.b - l) * (1.0 - l)) / (x - l); + } + + return c; +} + +vec3 setlum(vec3 c, float l) { + float d = l - lum(c); + c = c + vec3(d); + return clipcolor(c); +} + +void main() +{ + vec4 baseColor = texture2D(inputImageTexture, textureCoordinate); + vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(baseColor.rgb, lum(overlayColor.rgb)) * overlayColor.a, baseColor.a); +} +""" +public let MedianFragmentShader = """ +/* + 3x3 median filter, adapted from "A Fast, Small-Radius GPU Median Filter" by Morgan McGuire in ShaderX6 + http://graphics.cs.williams.edu/papers/MedianShaderX6/ + + Morgan McGuire and Kyle Whitson + Williams College + + Register allocation tips by Victor Huang Xiaohuang + University of Illinois at Urbana-Champaign + + http://graphics.cs.williams.edu + + + Copyright (c) Morgan McGuire and Williams College, 2006 + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + varying vec2 textureCoordinate; + varying vec2 leftTextureCoordinate; + varying vec2 rightTextureCoordinate; + + varying vec2 topTextureCoordinate; + varying vec2 topLeftTextureCoordinate; + varying vec2 topRightTextureCoordinate; + + varying vec2 bottomTextureCoordinate; + varying vec2 bottomLeftTextureCoordinate; + varying vec2 bottomRightTextureCoordinate; + + uniform sampler2D inputImageTexture; + +#define s2(a, b) temp = a; a = min(a, b); b = max(temp, b); +#define mn3(a, b, c) s2(a, b); s2(a, c); +#define mx3(a, b, c) s2(b, c); s2(a, c); + +#define mnmx3(a, b, c) mx3(a, b, c); s2(a, b); // 3 exchanges +#define mnmx4(a, b, c, d) s2(a, b); s2(c, d); s2(a, c); s2(b, d); // 4 exchanges +#define mnmx5(a, b, c, d, e) s2(a, b); s2(c, d); mn3(a, c, e); mx3(b, d, e); // 6 exchanges +#define mnmx6(a, b, c, d, e, f) s2(a, d); s2(b, e); s2(c, f); mn3(a, b, c); mx3(d, e, f); // 7 exchanges + + void main() + { + vec3 v[6]; + + v[0] = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb; + v[1] = texture2D(inputImageTexture, topRightTextureCoordinate).rgb; + v[2] = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb; + v[3] = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb; + v[4] = texture2D(inputImageTexture, leftTextureCoordinate).rgb; + v[5] = texture2D(inputImageTexture, rightTextureCoordinate).rgb; + // v[6] = texture2D(inputImageTexture, bottomTextureCoordinate).rgb; + // v[7] = texture2D(inputImageTexture, topTextureCoordinate).rgb; + vec3 temp; + + mnmx6(v[0], v[1], v[2], v[3], v[4], v[5]); + + v[5] = texture2D(inputImageTexture, bottomTextureCoordinate).rgb; + + mnmx5(v[1], v[2], v[3], v[4], v[5]); + + v[5] = texture2D(inputImageTexture, topTextureCoordinate).rgb; + + mnmx4(v[2], v[3], v[4], v[5]); + + v[5] = texture2D(inputImageTexture, textureCoordinate).rgb; + + mnmx3(v[3], v[4], v[5]); + + gl_FragColor = vec4(v[4], 1.0); + } +""" +public let MonochromeFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float intensity; +uniform vec3 filterColor; + +const vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + //desat, then apply overlay blend + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + float luminance = dot(textureColor.rgb, luminanceWeighting); + + vec4 desat = vec4(vec3(luminance), 1.0); + + //overlay + vec4 outputColor = vec4( + (desat.r < 0.5 ? (2.0 * desat.r * filterColor.r) : (1.0 - 2.0 * (1.0 - desat.r) * (1.0 - filterColor.r))), + (desat.g < 0.5 ? (2.0 * desat.g * filterColor.g) : (1.0 - 2.0 * (1.0 - desat.g) * (1.0 - filterColor.g))), + (desat.b < 0.5 ? (2.0 * desat.b * filterColor.b) : (1.0 - 2.0 * (1.0 - desat.b) * (1.0 - filterColor.b))), + 1.0 + ); + + //which is better, or are they equal? + gl_FragColor = vec4( mix(textureColor.rgb, outputColor.rgb, intensity), textureColor.a); +} +""" +public let MotionBlurVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; + +uniform vec2 directionalTexelStep; + +varying vec2 textureCoordinate; +varying vec2 oneStepBackTextureCoordinate; +varying vec2 twoStepsBackTextureCoordinate; +varying vec2 threeStepsBackTextureCoordinate; +varying vec2 fourStepsBackTextureCoordinate; +varying vec2 oneStepForwardTextureCoordinate; +varying vec2 twoStepsForwardTextureCoordinate; +varying vec2 threeStepsForwardTextureCoordinate; +varying vec2 fourStepsForwardTextureCoordinate; + +void main() +{ + gl_Position = position; + + textureCoordinate = inputTextureCoordinate.xy; + oneStepBackTextureCoordinate = inputTextureCoordinate.xy - directionalTexelStep; + twoStepsBackTextureCoordinate = inputTextureCoordinate.xy - 2.0 * directionalTexelStep; + threeStepsBackTextureCoordinate = inputTextureCoordinate.xy - 3.0 * directionalTexelStep; + fourStepsBackTextureCoordinate = inputTextureCoordinate.xy - 4.0 * directionalTexelStep; + oneStepForwardTextureCoordinate = inputTextureCoordinate.xy + directionalTexelStep; + twoStepsForwardTextureCoordinate = inputTextureCoordinate.xy + 2.0 * directionalTexelStep; + threeStepsForwardTextureCoordinate = inputTextureCoordinate.xy + 3.0 * directionalTexelStep; + fourStepsForwardTextureCoordinate = inputTextureCoordinate.xy + 4.0 * directionalTexelStep; +} +""" +public let MotionBlurFragmentShader = """ +uniform sampler2D inputImageTexture; + +varying vec2 textureCoordinate; +varying vec2 oneStepBackTextureCoordinate; +varying vec2 twoStepsBackTextureCoordinate; +varying vec2 threeStepsBackTextureCoordinate; +varying vec2 fourStepsBackTextureCoordinate; +varying vec2 oneStepForwardTextureCoordinate; +varying vec2 twoStepsForwardTextureCoordinate; +varying vec2 threeStepsForwardTextureCoordinate; +varying vec2 fourStepsForwardTextureCoordinate; + +void main() +{ + vec4 fragmentColor = texture2D(inputImageTexture, textureCoordinate) * 0.18; + fragmentColor += texture2D(inputImageTexture, oneStepBackTextureCoordinate) * 0.15; + fragmentColor += texture2D(inputImageTexture, twoStepsBackTextureCoordinate) * 0.12; + fragmentColor += texture2D(inputImageTexture, threeStepsBackTextureCoordinate) * 0.09; + fragmentColor += texture2D(inputImageTexture, fourStepsBackTextureCoordinate) * 0.05; + fragmentColor += texture2D(inputImageTexture, oneStepForwardTextureCoordinate) * 0.15; + fragmentColor += texture2D(inputImageTexture, twoStepsForwardTextureCoordinate) * 0.12; + fragmentColor += texture2D(inputImageTexture, threeStepsForwardTextureCoordinate) * 0.09; + fragmentColor += texture2D(inputImageTexture, fourStepsForwardTextureCoordinate) * 0.05; + + gl_FragColor = fragmentColor; +} +""" +public let MotionComparisonFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +uniform float intensity; + +void main() +{ + vec3 currentImageColor = texture2D(inputImageTexture, textureCoordinate).rgb; + vec3 lowPassImageColor = texture2D(inputImageTexture2, textureCoordinate2).rgb; + + float colorDistance = distance(currentImageColor, lowPassImageColor); // * 0.57735 + float movementThreshold = step(0.2, colorDistance); + + gl_FragColor = movementThreshold * vec4(textureCoordinate2.x, textureCoordinate2.y, 1.0, 1.0); +} +""" +public let MultiplyBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 base = texture2D(inputImageTexture, textureCoordinate); + vec4 overlayer = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = overlayer * base + overlayer * (1.0 - base.a) + base * (1.0 - overlayer.a); +} +""" +public let NearbyTexelSamplingVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +void main() +{ + gl_Position = position; + + vec2 widthStep = vec2(texelWidth, 0.0); + vec2 heightStep = vec2(0.0, texelHeight); + vec2 widthHeightStep = vec2(texelWidth, texelHeight); + vec2 widthNegativeHeightStep = vec2(texelWidth, -texelHeight); + + textureCoordinate = inputTextureCoordinate.xy; + leftTextureCoordinate = inputTextureCoordinate.xy - widthStep; + rightTextureCoordinate = inputTextureCoordinate.xy + widthStep; + + topTextureCoordinate = inputTextureCoordinate.xy - heightStep; + topLeftTextureCoordinate = inputTextureCoordinate.xy - widthHeightStep; + topRightTextureCoordinate = inputTextureCoordinate.xy + widthNegativeHeightStep; + + bottomTextureCoordinate = inputTextureCoordinate.xy + heightStep; + bottomLeftTextureCoordinate = inputTextureCoordinate.xy - widthNegativeHeightStep; + bottomRightTextureCoordinate = inputTextureCoordinate.xy + widthHeightStep; +} +""" +public let NobleCornerDetectorFragmentShader = """ + varying vec2 textureCoordinate; + + uniform sampler2D inputImageTexture; + uniform float sensitivity; + + void main() + { + vec3 derivativeElements = texture2D(inputImageTexture, textureCoordinate).rgb; + + float derivativeSum = derivativeElements.x + derivativeElements.y; + + // R = (Ix^2 * Iy^2 - Ixy * Ixy) / (Ix^2 + Iy^2) + float zElement = (derivativeElements.z * 2.0) - 1.0; + // mediump float harrisIntensity = (derivativeElements.x * derivativeElements.y - (derivativeElements.z * derivativeElements.z)) / (derivativeSum); + float cornerness = (derivativeElements.x * derivativeElements.y - (zElement * zElement)) / (derivativeSum); + + // Original Harris detector + // R = Ix^2 * Iy^2 - Ixy * Ixy - k * (Ix^2 + Iy^2)^2 + // highp float harrisIntensity = derivativeElements.x * derivativeElements.y - (derivativeElements.z * derivativeElements.z) - harrisConstant * derivativeSum * derivativeSum; + + // gl_FragColor = vec4(vec3(harrisIntensity * 7.0), 1.0); + gl_FragColor = vec4(vec3(cornerness * sensitivity), 1.0); + } +""" +public let NormalBlendFragmentShader = """ +/* + This equation is a simplification of the general blending equation. It assumes the destination color is opaque, and therefore drops the destination color's alpha term. + + D = C1 * C1a + C2 * C2a * (1 - C1a) + where D is the resultant color, C1 is the color of the first element, C1a is the alpha of the first element, C2 is the second element color, C2a is the alpha of the second element. The destination alpha is calculated with: + + Da = C1a + C2a * (1 - C1a) + The resultant color is premultiplied with the alpha. To restore the color to the unmultiplied values, just divide by Da, the resultant alpha. + + http://stackoverflow.com/questions/1724946/blend-mode-on-a-transparent-and-semi-transparent-background + + For some reason Photoshop behaves + D = C1 + C2 * C2a * (1 - C1a) + */ + +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 c2 = texture2D(inputImageTexture, textureCoordinate); + vec4 c1 = texture2D(inputImageTexture2, textureCoordinate2); + + vec4 outputColor; + + // outputColor.r = c1.r + c2.r * c2.a * (1.0 - c1.a); + // outputColor.g = c1.g + c2.g * c2.a * (1.0 - c1.a); + // outputColor.b = c1.b + c2.b * c2.a * (1.0 - c1.a); + // outputColor.a = c1.a + c2.a * (1.0 - c1.a); + + float a = c1.a + c2.a * (1.0 - c1.a); + float alphaDivisor = a + step(a, 0.0); // Protect against a divide-by-zero blacking out things in the output + + outputColor.r = (c1.r * c1.a + c2.r * c2.a * (1.0 - c1.a))/alphaDivisor; + outputColor.g = (c1.g * c1.a + c2.g * c2.a * (1.0 - c1.a))/alphaDivisor; + outputColor.b = (c1.b * c1.a + c2.b * c2.a * (1.0 - c1.a))/alphaDivisor; + outputColor.a = a; + + gl_FragColor = outputColor; +} +""" +public let OneInputVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; + +varying vec2 textureCoordinate; + +void main() +{ + gl_Position = position; + textureCoordinate = inputTextureCoordinate.xy; +} + +""" +public let OpacityFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float opacity; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = vec4(textureColor.rgb, textureColor.a * opacity); +} +""" +public let OverlayBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 base = texture2D(inputImageTexture, textureCoordinate); + vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2); + + float ra; + if (2.0 * base.r < base.a) { + ra = 2.0 * overlay.r * base.r + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a); + } else { + ra = overlay.a * base.a - 2.0 * (base.a - base.r) * (overlay.a - overlay.r) + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a); + } + + float ga; + if (2.0 * base.g < base.a) { + ga = 2.0 * overlay.g * base.g + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a); + } else { + ga = overlay.a * base.a - 2.0 * (base.a - base.g) * (overlay.a - overlay.g) + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a); + } + + float ba; + if (2.0 * base.b < base.a) { + ba = 2.0 * overlay.b * base.b + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a); + } else { + ba = overlay.a * base.a - 2.0 * (base.a - base.b) * (overlay.a - overlay.b) + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a); + } + + gl_FragColor = vec4(ra, ga, ba, 1.0); +} +""" +public let PassthroughFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + gl_FragColor = texture2D(inputImageTexture, textureCoordinate); +} +""" +public let PinchDistortionFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform float aspectRatio; +uniform vec2 center; +uniform float radius; +uniform float scale; + +void main() +{ + vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); + float dist = distance(center, textureCoordinateToUse); + textureCoordinateToUse = textureCoordinate; + + if (dist < radius) + { + textureCoordinateToUse -= center; + float percent = 1.0 + ((0.5 - dist) / 0.5) * scale; + textureCoordinateToUse = textureCoordinateToUse * percent; + textureCoordinateToUse += center; + + gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse ); + } + else + { + gl_FragColor = texture2D(inputImageTexture, textureCoordinate ); + } +} +""" +public let PixellateFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform float fractionalWidthOfPixel; +uniform float aspectRatio; + +void main() +{ + vec2 sampleDivisor = vec2(fractionalWidthOfPixel, fractionalWidthOfPixel / aspectRatio); + + vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor) + 0.5 * sampleDivisor; + gl_FragColor = texture2D(inputImageTexture, samplePos ); +} +""" +public let PolarPixellateFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform vec2 center; +uniform vec2 pixelSize; + + +void main() +{ + vec2 normCoord = 2.0 * textureCoordinate - 1.0; + vec2 normCenter = 2.0 * center - 1.0; + + normCoord -= normCenter; + + float r = length(normCoord); // to polar coords + float phi = atan(normCoord.y, normCoord.x); // to polar coords + + r = r - mod(r, pixelSize.x) + 0.03; + phi = phi - mod(phi, pixelSize.y); + + normCoord.x = r * cos(phi); + normCoord.y = r * sin(phi); + + normCoord += normCenter; + + vec2 textureCoordinateToUse = normCoord / 2.0 + 0.5; + + gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse ); + +} +""" +public let PolkaDotFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform float fractionalWidthOfPixel; +uniform float aspectRatio; +uniform float dotScaling; + +void main() +{ + vec2 sampleDivisor = vec2(fractionalWidthOfPixel, fractionalWidthOfPixel / aspectRatio); + + vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor) + 0.5 * sampleDivisor; + vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); + vec2 adjustedSamplePos = vec2(samplePos.x, (samplePos.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); + float distanceFromSamplePoint = distance(adjustedSamplePos, textureCoordinateToUse); + float checkForPresenceWithinDot = step(distanceFromSamplePoint, (fractionalWidthOfPixel * 0.5) * dotScaling); + + vec4 inputColor = texture2D(inputImageTexture, samplePos); + + gl_FragColor = vec4(inputColor.rgb * checkForPresenceWithinDot, inputColor.a); +} +""" +public let PosterizeFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float colorLevels; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = floor((textureColor * colorLevels) + vec4(0.5)) / colorLevels; +} +""" +public let PrewittEdgeDetectionFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float edgeStrength; + +void main() +{ + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + float h = -topLeftIntensity - topIntensity - topRightIntensity + bottomLeftIntensity + bottomIntensity + bottomRightIntensity; + float v = -bottomLeftIntensity - leftIntensity - topLeftIntensity + bottomRightIntensity + rightIntensity + topRightIntensity; + + float mag = length(vec2(h, v)) * edgeStrength; + + gl_FragColor = vec4(vec3(mag), 1.0); +} +""" +public let RGBAdjustmentFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float redAdjustment; +uniform float greenAdjustment; +uniform float blueAdjustment; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = vec4(textureColor.r * redAdjustment, textureColor.g * greenAdjustment, textureColor.b * blueAdjustment, textureColor.a); +} +""" +public let SaturationBlendFragmentShader = """ +// Saturation blend mode based upon pseudo code from the PDF specification. + +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +float lum(vec3 c) { + return dot(c, vec3(0.3, 0.59, 0.11)); +} + +vec3 clipcolor(vec3 c) { + float l = lum(c); + float n = min(min(c.r, c.g), c.b); + float x = max(max(c.r, c.g), c.b); + + if (n < 0.0) { + c.r = l + ((c.r - l) * l) / (l - n); + c.g = l + ((c.g - l) * l) / (l - n); + c.b = l + ((c.b - l) * l) / (l - n); + } + if (x > 1.0) { + c.r = l + ((c.r - l) * (1.0 - l)) / (x - l); + c.g = l + ((c.g - l) * (1.0 - l)) / (x - l); + c.b = l + ((c.b - l) * (1.0 - l)) / (x - l); + } + + return c; +} + +vec3 setlum(vec3 c, float l) { + float d = l - lum(c); + c = c + vec3(d); + return clipcolor(c); +} + +float sat(vec3 c) { + float n = min(min(c.r, c.g), c.b); + float x = max(max(c.r, c.g), c.b); + return x - n; +} + +float mid(float cmin, float cmid, float cmax, float s) { + return ((cmid - cmin) * s) / (cmax - cmin); +} + +vec3 setsat(vec3 c, float s) { + if (c.r > c.g) { + if (c.r > c.b) { + if (c.g > c.b) { + /* g is mid, b is min */ + c.g = mid(c.b, c.g, c.r, s); + c.b = 0.0; + } else { + /* b is mid, g is min */ + c.b = mid(c.g, c.b, c.r, s); + c.g = 0.0; + } + c.r = s; + } else { + /* b is max, r is mid, g is min */ + c.r = mid(c.g, c.r, c.b, s); + c.b = s; + c.r = 0.0; + } + } else if (c.r > c.b) { + /* g is max, r is mid, b is min */ + c.r = mid(c.b, c.r, c.g, s); + c.g = s; + c.b = 0.0; + } else if (c.g > c.b) { + /* g is max, b is mid, r is min */ + c.b = mid(c.r, c.b, c.g, s); + c.g = s; + c.r = 0.0; + } else if (c.b > c.g) { + /* b is max, g is mid, r is min */ + c.g = mid(c.r, c.g, c.b, s); + c.b = s; + c.r = 0.0; + } else { + c = vec3(0.0); + } + return c; +} + +void main() +{ + vec4 baseColor = texture2D(inputImageTexture, textureCoordinate); + vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(setsat(baseColor.rgb, sat(overlayColor.rgb)), lum(baseColor.rgb)) * overlayColor.a, baseColor.a); +} +""" +public let SaturationFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float saturation; + +// Values from "Graphics Shaders: Theory and Practice" by Bailey and Cunningham +const vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + float luminance = dot(textureColor.rgb, luminanceWeighting); + vec3 greyScaleColor = vec3(luminance); + + gl_FragColor = vec4(mix(greyScaleColor, textureColor.rgb, saturation), textureColor.w); + +} + +""" +public let ScreenBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + vec4 whiteColor = vec4(1.0); + gl_FragColor = whiteColor - ((whiteColor - textureColor2) * (whiteColor - textureColor)); +} +""" +public let SharpenVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; + +uniform float texelWidth; +uniform float texelHeight; +uniform float sharpness; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; +varying vec2 topTextureCoordinate; +varying vec2 bottomTextureCoordinate; + +varying float centerMultiplier; +varying float edgeMultiplier; + +void main() +{ + gl_Position = position; + + vec2 widthStep = vec2(texelWidth, 0.0); + vec2 heightStep = vec2(0.0, texelHeight); + + textureCoordinate = inputTextureCoordinate.xy; + leftTextureCoordinate = inputTextureCoordinate.xy - widthStep; + rightTextureCoordinate = inputTextureCoordinate.xy + widthStep; + topTextureCoordinate = inputTextureCoordinate.xy + heightStep; + bottomTextureCoordinate = inputTextureCoordinate.xy - heightStep; + + centerMultiplier = 1.0 + 4.0 * sharpness; + edgeMultiplier = sharpness; +} +""" +public let SharpenFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; +varying vec2 topTextureCoordinate; +varying vec2 bottomTextureCoordinate; + +varying float centerMultiplier; +varying float edgeMultiplier; + +uniform sampler2D inputImageTexture; + +void main() +{ + vec3 textureColor = texture2D(inputImageTexture, textureCoordinate).rgb; + vec3 leftTextureColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb; + vec3 rightTextureColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb; + vec3 topTextureColor = texture2D(inputImageTexture, topTextureCoordinate).rgb; + vec3 bottomTextureColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb; + + gl_FragColor = vec4((textureColor * centerMultiplier - (leftTextureColor * edgeMultiplier + rightTextureColor * edgeMultiplier + topTextureColor * edgeMultiplier + bottomTextureColor * edgeMultiplier)), texture2D(inputImageTexture, bottomTextureCoordinate).w); +} +""" +public let ShiTomasiFeatureDetectorFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float sensitivity; + +void main() +{ + vec3 derivativeElements = texture2D(inputImageTexture, textureCoordinate).rgb; + + float derivativeDifference = derivativeElements.x - derivativeElements.y; + float zElement = (derivativeElements.z * 2.0) - 1.0; + + // R = Ix^2 + Iy^2 - sqrt( (Ix^2 - Iy^2)^2 + 4 * Ixy * Ixy) + float cornerness = derivativeElements.x + derivativeElements.y - sqrt(derivativeDifference * derivativeDifference + 4.0 * zElement * zElement); + + gl_FragColor = vec4(vec3(cornerness * sensitivity), 1.0); +} +""" +public let SketchFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform float edgeStrength; + +uniform sampler2D inputImageTexture; + +void main() +{ + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity; + float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity; + + float mag = 1.0 - (length(vec2(h, v)) * edgeStrength); + + gl_FragColor = vec4(vec3(mag), 1.0); +} +""" +public let SobelEdgeDetectionFragmentShader = """ +// Code from "Graphics Shaders: Theory and Practice" by M. Bailey and S. Cunningham + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float edgeStrength; + +void main() +{ + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity; + float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity; + + float mag = length(vec2(h, v)) * edgeStrength; + + gl_FragColor = vec4(vec3(mag), 1.0); +} +""" +public let SoftLightBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 base = texture2D(inputImageTexture, textureCoordinate); + vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2); + + float alphaDivisor = base.a + step(base.a, 0.0); // Protect against a divide-by-zero blacking out things in the output + gl_FragColor = base * (overlay.a * (base / alphaDivisor) + (2.0 * overlay * (1.0 - (base / alphaDivisor)))) + overlay * (1.0 - base.a) + base * (1.0 - overlay.a); +} +""" +public let SolarizeFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float threshold; + +const vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + float luminance = dot(textureColor.rgb, W); + float thresholdResult = step(luminance, threshold); + vec3 finalColor = abs(thresholdResult - textureColor.rgb); + + gl_FragColor = vec4(vec3(finalColor), textureColor.w); +} +""" +public let SourceOverBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate); + + gl_FragColor = mix(textureColor, textureColor2, textureColor2.a); +} +""" +public let SphereRefractionFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform vec2 center; +uniform float radius; +uniform float aspectRatio; +uniform float refractiveIndex; + +void main() +{ + vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); + float distanceFromCenter = distance(center, textureCoordinateToUse); + float checkForPresenceWithinSphere = step(distanceFromCenter, radius); + + distanceFromCenter = distanceFromCenter / radius; + + float normalizedDepth = radius * sqrt(1.0 - distanceFromCenter * distanceFromCenter); + vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - center, normalizedDepth)); + + vec3 refractedVector = refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex); + + gl_FragColor = texture2D(inputImageTexture, (refractedVector.xy + 1.0) * 0.5) * checkForPresenceWithinSphere; +} +""" +public let StretchDistortionFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform vec2 center; + +void main() +{ + vec2 normCoord = 2.0 * textureCoordinate - 1.0; + vec2 normCenter = 2.0 * center - 1.0; + + normCoord -= normCenter; + vec2 s = sign(normCoord); + normCoord = abs(normCoord); + normCoord = 0.5 * normCoord + 0.5 * smoothstep(0.25, 0.5, normCoord) * normCoord; + normCoord = s * normCoord; + + normCoord += normCenter; + + vec2 textureCoordinateToUse = normCoord / 2.0 + 0.5; + + gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse); +} +""" +public let SubtractBlendFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = vec4(textureColor.rgb - textureColor2.rgb, textureColor.a); +} +""" +public let SwirlFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform vec2 center; +uniform float radius; +uniform float angle; + +void main() +{ + vec2 textureCoordinateToUse = textureCoordinate; + float dist = distance(center, textureCoordinate); + if (dist < radius) + { + textureCoordinateToUse -= center; + float percent = (radius - dist) / radius; + float theta = percent * percent * angle * 8.0; + float s = sin(theta); + float c = cos(theta); + textureCoordinateToUse = vec2(dot(textureCoordinateToUse, vec2(c, -s)), dot(textureCoordinateToUse, vec2(s, c))); + textureCoordinateToUse += center; + } + + gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse ); +} +""" +public let ThreeInputVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; +attribute vec4 inputTextureCoordinate2; +attribute vec4 inputTextureCoordinate3; + +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; +varying vec2 textureCoordinate3; + +void main() +{ + gl_Position = position; + textureCoordinate = inputTextureCoordinate.xy; + textureCoordinate2 = inputTextureCoordinate2.xy; + textureCoordinate3 = inputTextureCoordinate3.xy; +} +""" +public let ThresholdEdgeDetectionFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float threshold; + +uniform float edgeStrength; + +void main() +{ + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity; + h = max(0.0, h); + float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity; + v = max(0.0, v); + + float mag = length(vec2(h, v)) * edgeStrength; + mag = step(threshold, mag); + + gl_FragColor = vec4(vec3(mag), 1.0); +} +""" +public let ThresholdSketchFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float threshold; + +uniform float edgeStrength; + +void main() +{ + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity; + h = max(0.0, h); + float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity; + v = max(0.0, v); + + float mag = length(vec2(h, v)) * edgeStrength; + mag = 1.0 - step(threshold, mag); + + gl_FragColor = vec4(vec3(mag), 1.0); +} +""" +public let ThresholdedNonMaximumSuppressionFragmentShader = """ +uniform sampler2D inputImageTexture; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform float threshold; + +void main() +{ + float bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + vec4 centerColor = texture2D(inputImageTexture, textureCoordinate); + float leftColor = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightColor = texture2D(inputImageTexture, rightTextureCoordinate).r; + float topColor = texture2D(inputImageTexture, topTextureCoordinate).r; + float topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + + // Use a tiebreaker for pixels to the left and immediately above this one + float multiplier = 1.0 - step(centerColor.r, topColor); + multiplier = multiplier * (1.0 - step(centerColor.r, topLeftColor)); + multiplier = multiplier * (1.0 - step(centerColor.r, leftColor)); + multiplier = multiplier * (1.0 - step(centerColor.r, bottomLeftColor)); + + float maxValue = max(centerColor.r, bottomColor); + maxValue = max(maxValue, bottomRightColor); + maxValue = max(maxValue, rightColor); + maxValue = max(maxValue, topRightColor); + + float finalValue = centerColor.r * step(maxValue, centerColor.r) * multiplier; + finalValue = step(threshold, finalValue); + + gl_FragColor = vec4(finalValue, finalValue, finalValue, 1.0); + // + // gl_FragColor = vec4((centerColor.rgb * step(maxValue, step(threshold, centerColor.r)) * multiplier), 1.0); +} +""" +public let TiltShiftFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +uniform float topFocusLevel; +uniform float bottomFocusLevel; +uniform float focusFallOffRate; + +void main() +{ + vec4 sharpImageColor = texture2D(inputImageTexture, textureCoordinate); + vec4 blurredImageColor = texture2D(inputImageTexture2, textureCoordinate2); + + float blurIntensity = 1.0 - smoothstep(topFocusLevel - focusFallOffRate, topFocusLevel, textureCoordinate2.y); + blurIntensity += smoothstep(bottomFocusLevel, bottomFocusLevel + focusFallOffRate, textureCoordinate2.y); + + gl_FragColor = mix(sharpImageColor, blurredImageColor, blurIntensity); +} +""" +public let ToonFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform float intensity; +uniform float threshold; +uniform float quantizationLevels; + +const vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity; + float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity; + + float mag = length(vec2(h, v)); + + vec3 posterizedImageColor = floor((textureColor.rgb * quantizationLevels) + 0.5) / quantizationLevels; + + float thresholdTest = 1.0 - step(threshold, mag); + + gl_FragColor = vec4(posterizedImageColor * thresholdTest, textureColor.a); +} +""" +public let TransformVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; + +uniform mat4 transformMatrix; +uniform mat4 orthographicMatrix; + +varying vec2 textureCoordinate; + +void main() +{ + gl_Position = transformMatrix * vec4(position.xyz, 1.0) * orthographicMatrix; + textureCoordinate = inputTextureCoordinate.xy; +} +""" +public let TwoInputVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; +attribute vec4 inputTextureCoordinate2; + +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +void main() +{ + gl_Position = position; + textureCoordinate = inputTextureCoordinate.xy; + textureCoordinate2 = inputTextureCoordinate2.xy; +} + +""" +public let UnsharpMaskFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +uniform float intensity; + +void main() +{ + vec4 sharpImageColor = texture2D(inputImageTexture, textureCoordinate); + vec3 blurredImageColor = texture2D(inputImageTexture2, textureCoordinate2).rgb; + + gl_FragColor = vec4(sharpImageColor.rgb * intensity + blurredImageColor * (1.0 - intensity), sharpImageColor.a); +} +""" +public let VibranceFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float vibrance; + +void main() { + vec4 color = texture2D(inputImageTexture, textureCoordinate); + float average = (color.r + color.g + color.b) / 3.0; + float mx = max(color.r, max(color.g, color.b)); + float amt = (mx - average) * (-vibrance * 3.0); + color.rgb = mix(color.rgb, vec3(mx), amt); + gl_FragColor = color; +} +""" +public let VignetteFragmentShader = """ +uniform sampler2D inputImageTexture; +varying vec2 textureCoordinate; + +uniform vec2 vignetteCenter; +uniform vec3 vignetteColor; +uniform float vignetteStart; +uniform float vignetteEnd; + +void main() +{ + vec4 sourceImageColor = texture2D(inputImageTexture, textureCoordinate); + float d = distance(textureCoordinate, vec2(vignetteCenter.x, vignetteCenter.y)); + float percent = smoothstep(vignetteStart, vignetteEnd, d); + gl_FragColor = vec4(mix(sourceImageColor.rgb, vignetteColor, percent), sourceImageColor.a); +} +""" +public let WeakPixelInclusionFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + float centerIntensity = texture2D(inputImageTexture, textureCoordinate).r; + + float pixelIntensitySum = bottomLeftIntensity + topRightIntensity + topLeftIntensity + bottomRightIntensity + leftIntensity + rightIntensity + bottomIntensity + topIntensity + centerIntensity; + float sumTest = step(1.5, pixelIntensitySum); + float pixelTest = step(0.01, centerIntensity); + + gl_FragColor = vec4(vec3(sumTest * pixelTest), 1.0); +} +""" +public let WhiteBalanceFragmentShader = """ +uniform sampler2D inputImageTexture; +varying vec2 textureCoordinate; + +uniform float temperature; +uniform float tint; + +const vec3 warmFilter = vec3(0.93, 0.54, 0.0); + +const mat3 RGBtoYIQ = mat3(0.299, 0.587, 0.114, 0.596, -0.274, -0.322, 0.212, -0.523, 0.311); +const mat3 YIQtoRGB = mat3(1.0, 0.956, 0.621, 1.0, -0.272, -0.647, 1.0, -1.105, 1.702); + +void main() +{ + vec4 source = texture2D(inputImageTexture, textureCoordinate); + + vec3 yiq = RGBtoYIQ * source.rgb; //adjusting tint + yiq.b = clamp(yiq.b + tint*0.5226*0.1, -0.5226, 0.5226); + vec3 rgb = YIQtoRGB * yiq; + + vec3 processed = vec3( + (rgb.r < 0.5 ? (2.0 * rgb.r * warmFilter.r) : (1.0 - 2.0 * (1.0 - rgb.r) * (1.0 - warmFilter.r))), //adjusting temperature + (rgb.g < 0.5 ? (2.0 * rgb.g * warmFilter.g) : (1.0 - 2.0 * (1.0 - rgb.g) * (1.0 - warmFilter.g))), + (rgb.b < 0.5 ? (2.0 * rgb.b * warmFilter.b) : (1.0 - 2.0 * (1.0 - rgb.b) * (1.0 - warmFilter.b)))); + + gl_FragColor = vec4(mix(rgb, processed, temperature), source.a); +} +""" +public let XYDerivativeFragmentShader = """ +// I'm using the Prewitt operator to obtain the derivative, then squaring the X and Y components and placing the product of the two in Z. +// In tests, Prewitt seemed to be tied with Sobel for the best, and it's just a little cheaper to compute. +// This is primarily intended to be used with corner detection filters. + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + + float verticalDerivative = -topLeftIntensity - topIntensity - topRightIntensity + bottomLeftIntensity + bottomIntensity + bottomRightIntensity; + float horizontalDerivative = -bottomLeftIntensity - leftIntensity - topLeftIntensity + bottomRightIntensity + rightIntensity + topRightIntensity; + verticalDerivative = verticalDerivative; + horizontalDerivative = horizontalDerivative; + + // Scaling the X * Y operation so that negative numbers are not clipped in the 0..1 range. This will be expanded in the corner detection filter + gl_FragColor = vec4(horizontalDerivative * horizontalDerivative, verticalDerivative * verticalDerivative, ((verticalDerivative * horizontalDerivative) + 1.0) / 2.0, 1.0); +} +""" +public let YUVConversionFullRangeUVPlanarFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; +varying vec2 textureCoordinate3; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; +uniform sampler2D inputImageTexture3; + +uniform mat3 colorConversionMatrix; + +void main() +{ + vec3 yuv; + + yuv.x = texture2D(inputImageTexture, textureCoordinate).r; + yuv.y = texture2D(inputImageTexture2, textureCoordinate).r - 0.5; + yuv.z = texture2D(inputImageTexture3, textureCoordinate).r - 0.5; + vec3 rgb = colorConversionMatrix * yuv; + + gl_FragColor = vec4(rgb, 1.0); +} + +""" +public let YUVConversionFullRangeFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +uniform mat3 colorConversionMatrix; + +void main() +{ + vec3 yuv; + + yuv.x = texture2D(inputImageTexture, textureCoordinate).r; + yuv.yz = texture2D(inputImageTexture2, textureCoordinate).ra - vec2(0.5, 0.5); + vec3 rgb = colorConversionMatrix * yuv; + + gl_FragColor = vec4(rgb, 1.0); +} + +""" +public let YUVConversionVideoRangeFragmentShader = """ +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +uniform mat3 colorConversionMatrix; + +void main() +{ + vec3 yuv; + + yuv.x = texture2D(inputImageTexture, textureCoordinate).r - (16.0/255.0); + yuv.yz = texture2D(inputImageTexture2, textureCoordinate).ra - vec2(0.5, 0.5); + vec3 rgb = colorConversionMatrix * yuv; + + gl_FragColor = vec4(rgb, 1.0); +} +""" +public let ZoomBlurFragmentShader = """ +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform vec2 blurCenter; +uniform float blurSize; + +void main() +{ + // TODO: Do a more intelligent scaling based on resolution here + vec2 samplingOffset = 1.0/100.0 * (blurCenter - textureCoordinate) * blurSize; + + vec4 fragmentColor = texture2D(inputImageTexture, textureCoordinate) * 0.18; + fragmentColor += texture2D(inputImageTexture, textureCoordinate + samplingOffset) * 0.15; + fragmentColor += texture2D(inputImageTexture, textureCoordinate + (2.0 * samplingOffset)) * 0.12; + fragmentColor += texture2D(inputImageTexture, textureCoordinate + (3.0 * samplingOffset)) * 0.09; + fragmentColor += texture2D(inputImageTexture, textureCoordinate + (4.0 * samplingOffset)) * 0.05; + fragmentColor += texture2D(inputImageTexture, textureCoordinate - samplingOffset) * 0.15; + fragmentColor += texture2D(inputImageTexture, textureCoordinate - (2.0 * samplingOffset)) * 0.12; + fragmentColor += texture2D(inputImageTexture, textureCoordinate - (3.0 * samplingOffset)) * 0.09; + fragmentColor += texture2D(inputImageTexture, textureCoordinate - (4.0 * samplingOffset)) * 0.05; + + gl_FragColor = fragmentColor; +} +""" diff --git a/framework/Source/Operations/Shaders/ConvertedShaders_GLES.swift b/framework/Source/Operations/Shaders/ConvertedShaders_GLES.swift index 8e934039..0c1eb084 100644 --- a/framework/Source/Operations/Shaders/ConvertedShaders_GLES.swift +++ b/framework/Source/Operations/Shaders/ConvertedShaders_GLES.swift @@ -1,144 +1,4181 @@ -public let AdaptiveThresholdFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2; \n \n void main()\n {\n highp float blurredInput = texture2D(inputImageTexture, textureCoordinate).r;\n highp float localLuminance = texture2D(inputImageTexture2, textureCoordinate2).r;\n highp float thresholdResult = step(blurredInput - 0.05, localLuminance);\n \n gl_FragColor = vec4(vec3(thresholdResult), 1.0);\n }\n " -public let AddBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n lowp vec4 base = texture2D(inputImageTexture, textureCoordinate);\n lowp vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n mediump float r;\n if (overlay.r * base.a + base.r * overlay.a >= overlay.a * base.a) {\n r = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n } else {\n r = overlay.r + base.r;\n }\n \n mediump float g;\n if (overlay.g * base.a + base.g * overlay.a >= overlay.a * base.a) {\n g = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n } else {\n g = overlay.g + base.g;\n }\n \n mediump float b;\n if (overlay.b * base.a + base.b * overlay.a >= overlay.a * base.a) {\n b = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n } else {\n b = overlay.b + base.b;\n }\n \n mediump float a = overlay.a + base.a - overlay.a * base.a;\n \n gl_FragColor = vec4(r, g, b, a);\n }\n " -public let AlphaBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform lowp float mixturePercent;\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(mix(textureColor.rgb, textureColor2.rgb, textureColor2.a * mixturePercent), textureColor.a);\n }\n " -public let AlphaTestFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n lowp vec4 color = texture2D(inputImageTexture, textureCoordinate);\n if (color.a < 0.5) \n {\n discard;\n } \n else\n {\n gl_FragColor = color;\n }\n }\n " -public let AverageColorVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n uniform float texelWidth;\n uniform float texelHeight;\n \n varying vec2 upperLeftInputTextureCoordinate;\n varying vec2 upperRightInputTextureCoordinate;\n varying vec2 lowerLeftInputTextureCoordinate;\n varying vec2 lowerRightInputTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n upperLeftInputTextureCoordinate = inputTextureCoordinate.xy + vec2(-texelWidth, -texelHeight);\n upperRightInputTextureCoordinate = inputTextureCoordinate.xy + vec2(texelWidth, -texelHeight);\n lowerLeftInputTextureCoordinate = inputTextureCoordinate.xy + vec2(-texelWidth, texelHeight);\n lowerRightInputTextureCoordinate = inputTextureCoordinate.xy + vec2(texelWidth, texelHeight);\n }\n " -public let AverageColorFragmentShader = "precision highp float;\n \n uniform sampler2D inputImageTexture;\n \n varying highp vec2 outputTextureCoordinate;\n \n varying highp vec2 upperLeftInputTextureCoordinate;\n varying highp vec2 upperRightInputTextureCoordinate;\n varying highp vec2 lowerLeftInputTextureCoordinate;\n varying highp vec2 lowerRightInputTextureCoordinate;\n \n void main()\n {\n highp vec4 upperLeftColor = texture2D(inputImageTexture, upperLeftInputTextureCoordinate);\n highp vec4 upperRightColor = texture2D(inputImageTexture, upperRightInputTextureCoordinate);\n highp vec4 lowerLeftColor = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate);\n highp vec4 lowerRightColor = texture2D(inputImageTexture, lowerRightInputTextureCoordinate);\n \n gl_FragColor = 0.25 * (upperLeftColor + upperRightColor + lowerLeftColor + lowerRightColor);\n }\n " -public let AverageLuminanceFragmentShader = "precision highp float;\n \n uniform sampler2D inputImageTexture;\n \n varying highp vec2 outputTextureCoordinate;\n \n varying highp vec2 upperLeftInputTextureCoordinate;\n varying highp vec2 upperRightInputTextureCoordinate;\n varying highp vec2 lowerLeftInputTextureCoordinate;\n varying highp vec2 lowerRightInputTextureCoordinate;\n \n void main()\n {\n highp float upperLeftLuminance = texture2D(inputImageTexture, upperLeftInputTextureCoordinate).r;\n highp float upperRightLuminance = texture2D(inputImageTexture, upperRightInputTextureCoordinate).r;\n highp float lowerLeftLuminance = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate).r;\n highp float lowerRightLuminance = texture2D(inputImageTexture, lowerRightInputTextureCoordinate).r;\n \n highp float luminosity = 0.25 * (upperLeftLuminance + upperRightLuminance + lowerLeftLuminance + lowerRightLuminance);\n gl_FragColor = vec4(luminosity, luminosity, luminosity, 1.0);\n }\n " -public let BilateralBlurVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n const int GAUSSIAN_SAMPLES = 9;\n \n uniform float texelWidth;\n uniform float texelHeight;\n \n varying vec2 textureCoordinate;\n varying vec2 blurCoordinates[GAUSSIAN_SAMPLES];\n \n void main()\n {\n gl_Position = position;\n textureCoordinate = inputTextureCoordinate.xy;\n \n // Calculate the positions for the blur\n int multiplier = 0;\n vec2 blurStep;\n vec2 singleStepOffset = vec2(texelWidth, texelHeight);\n \n for (int i = 0; i < GAUSSIAN_SAMPLES; i++)\n {\n multiplier = (i - ((GAUSSIAN_SAMPLES - 1) / 2));\n // Blur in x (horizontal)\n blurStep = float(multiplier) * singleStepOffset;\n blurCoordinates[i] = inputTextureCoordinate.xy + blurStep;\n }\n }\n " -public let BilateralBlurFragmentShader = "uniform sampler2D inputImageTexture;\n \n const lowp int GAUSSIAN_SAMPLES = 9;\n \n varying highp vec2 textureCoordinate;\n varying highp vec2 blurCoordinates[GAUSSIAN_SAMPLES];\n \n uniform mediump float distanceNormalizationFactor;\n \n void main()\n {\n lowp vec4 centralColor;\n lowp float gaussianWeightTotal;\n lowp vec4 sum;\n lowp vec4 sampleColor;\n lowp float distanceFromCentralColor;\n lowp float gaussianWeight;\n \n centralColor = texture2D(inputImageTexture, blurCoordinates[4]);\n gaussianWeightTotal = 0.18;\n sum = centralColor * 0.18;\n \n sampleColor = texture2D(inputImageTexture, blurCoordinates[0]);\n distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n gaussianWeight = 0.05 * (1.0 - distanceFromCentralColor);\n gaussianWeightTotal += gaussianWeight;\n sum += sampleColor * gaussianWeight;\n \n sampleColor = texture2D(inputImageTexture, blurCoordinates[1]);\n distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n gaussianWeight = 0.09 * (1.0 - distanceFromCentralColor);\n gaussianWeightTotal += gaussianWeight;\n sum += sampleColor * gaussianWeight;\n \n sampleColor = texture2D(inputImageTexture, blurCoordinates[2]);\n distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n gaussianWeight = 0.12 * (1.0 - distanceFromCentralColor);\n gaussianWeightTotal += gaussianWeight;\n sum += sampleColor * gaussianWeight;\n \n sampleColor = texture2D(inputImageTexture, blurCoordinates[3]);\n distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n gaussianWeight = 0.15 * (1.0 - distanceFromCentralColor);\n gaussianWeightTotal += gaussianWeight;\n sum += sampleColor * gaussianWeight;\n \n sampleColor = texture2D(inputImageTexture, blurCoordinates[5]);\n distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n gaussianWeight = 0.15 * (1.0 - distanceFromCentralColor);\n gaussianWeightTotal += gaussianWeight;\n sum += sampleColor * gaussianWeight;\n \n sampleColor = texture2D(inputImageTexture, blurCoordinates[6]);\n distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n gaussianWeight = 0.12 * (1.0 - distanceFromCentralColor);\n gaussianWeightTotal += gaussianWeight;\n sum += sampleColor * gaussianWeight;\n \n sampleColor = texture2D(inputImageTexture, blurCoordinates[7]);\n distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n gaussianWeight = 0.09 * (1.0 - distanceFromCentralColor);\n gaussianWeightTotal += gaussianWeight;\n sum += sampleColor * gaussianWeight;\n \n sampleColor = texture2D(inputImageTexture, blurCoordinates[8]);\n distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n gaussianWeight = 0.05 * (1.0 - distanceFromCentralColor);\n gaussianWeightTotal += gaussianWeight;\n sum += sampleColor * gaussianWeight;\n \n gl_FragColor = sum / gaussianWeightTotal;\n }\n " -public let BrightnessFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform lowp float brightness;\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = vec4((textureColor.rgb + vec3(brightness)), textureColor.w);\n }\n " -public let BulgeDistortionFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform highp float aspectRatio;\n uniform highp vec2 center;\n uniform highp float radius;\n uniform highp float scale;\n \n void main()\n {\n highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, ((textureCoordinate.y - center.y) * aspectRatio) + center.y);\n highp float dist = distance(center, textureCoordinateToUse);\n textureCoordinateToUse = textureCoordinate;\n \n if (dist < radius)\n {\n textureCoordinateToUse -= center;\n highp float percent = 1.0 - ((radius - dist) / radius) * scale;\n percent = percent * percent;\n \n textureCoordinateToUse = textureCoordinateToUse * percent;\n textureCoordinateToUse += center;\n }\n \n gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse ); \n }\n " -public let CGAColorspaceFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n highp vec2 sampleDivisor = vec2(1.0 / 200.0, 1.0 / 320.0);\n //highp vec4 colorDivisor = vec4(colorDepth);\n \n highp vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor);\n highp vec4 color = texture2D(inputImageTexture, samplePos );\n \n //gl_FragColor = texture2D(inputImageTexture, samplePos );\n mediump vec4 colorCyan = vec4(85.0 / 255.0, 1.0, 1.0, 1.0);\n mediump vec4 colorMagenta = vec4(1.0, 85.0 / 255.0, 1.0, 1.0);\n mediump vec4 colorWhite = vec4(1.0, 1.0, 1.0, 1.0);\n mediump vec4 colorBlack = vec4(0.0, 0.0, 0.0, 1.0);\n \n mediump vec4 endColor;\n highp float blackDistance = distance(color, colorBlack);\n highp float whiteDistance = distance(color, colorWhite);\n highp float magentaDistance = distance(color, colorMagenta);\n highp float cyanDistance = distance(color, colorCyan);\n \n mediump vec4 finalColor;\n \n highp float colorDistance = min(magentaDistance, cyanDistance);\n colorDistance = min(colorDistance, whiteDistance);\n colorDistance = min(colorDistance, blackDistance); \n \n if (colorDistance == blackDistance) {\n finalColor = colorBlack;\n } else if (colorDistance == whiteDistance) {\n finalColor = colorWhite;\n } else if (colorDistance == cyanDistance) {\n finalColor = colorCyan;\n } else {\n finalColor = colorMagenta;\n }\n \n gl_FragColor = finalColor;\n }\n " -public let ChromaKeyBlendFragmentShader = "// Shader code based on Apple's CIChromaKeyFilter example: https://developer.apple.com/library/mac/#samplecode/CIChromaKeyFilter/Introduction/Intro.html\n \n precision highp float;\n \n varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform float thresholdSensitivity;\n uniform float smoothing;\n uniform vec3 colorToReplace;\n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n \n float maskY = 0.2989 * colorToReplace.r + 0.5866 * colorToReplace.g + 0.1145 * colorToReplace.b;\n float maskCr = 0.7132 * (colorToReplace.r - maskY);\n float maskCb = 0.5647 * (colorToReplace.b - maskY);\n \n float Y = 0.2989 * textureColor.r + 0.5866 * textureColor.g + 0.1145 * textureColor.b;\n float Cr = 0.7132 * (textureColor.r - Y);\n float Cb = 0.5647 * (textureColor.b - Y);\n \n // float blendValue = 1.0 - smoothstep(thresholdSensitivity - smoothing, thresholdSensitivity , abs(Cr - maskCr) + abs(Cb - maskCb));\n float blendValue = 1.0 - smoothstep(thresholdSensitivity, thresholdSensitivity + smoothing, distance(vec2(Cr, Cb), vec2(maskCr, maskCb)));\n gl_FragColor = mix(textureColor, textureColor2, blendValue);\n }\n " -public let ChromaKeyFragmentShader = "// Shader code based on Apple's CIChromaKeyFilter example: https://developer.apple.com/library/mac/#samplecode/CIChromaKeyFilter/Introduction/Intro.html\n \n precision highp float;\n \n varying highp vec2 textureCoordinate;\n \n uniform float thresholdSensitivity;\n uniform float smoothing;\n uniform vec3 colorToReplace;\n uniform sampler2D inputImageTexture;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n float maskY = 0.2989 * colorToReplace.r + 0.5866 * colorToReplace.g + 0.1145 * colorToReplace.b;\n float maskCr = 0.7132 * (colorToReplace.r - maskY);\n float maskCb = 0.5647 * (colorToReplace.b - maskY);\n \n float Y = 0.2989 * textureColor.r + 0.5866 * textureColor.g + 0.1145 * textureColor.b;\n float Cr = 0.7132 * (textureColor.r - Y);\n float Cb = 0.5647 * (textureColor.b - Y);\n \n // float blendValue = 1.0 - smoothstep(thresholdSensitivity - smoothing, thresholdSensitivity , abs(Cr - maskCr) + abs(Cb - maskCb));\n float blendValue = smoothstep(thresholdSensitivity, thresholdSensitivity + smoothing, distance(vec2(Cr, Cb), vec2(maskCr, maskCb)));\n gl_FragColor = vec4(textureColor.rgb, textureColor.a * blendValue);\n }\n " -public let CircleVertexShader = "attribute vec4 position;\n varying vec2 currentPosition;\n uniform float aspectRatio;\n \n void main()\n {\n currentPosition = vec2(position.x, position.y * aspectRatio);\n gl_Position = position;\n }\n " -public let CircleFragmentShader = "uniform lowp vec4 circleColor;\n uniform lowp vec4 backgroundColor;\n uniform highp vec2 center;\n uniform highp float radius;\n \n varying highp vec2 currentPosition;\n \n void main()\n {\n highp float distanceFromCenter = distance(center, currentPosition);\n highp float checkForPresenceWithinCircle = step(distanceFromCenter, radius);\n \n gl_FragColor = mix(backgroundColor, circleColor, checkForPresenceWithinCircle);\n }\n " -public let ColorBlendFragmentShader = "// Color blend mode based upon pseudo code from the PDF specification.\n \n varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n highp float lum(lowp vec3 c) {\n return dot(c, vec3(0.3, 0.59, 0.11));\n }\n \n lowp vec3 clipcolor(lowp vec3 c) {\n highp float l = lum(c);\n lowp float n = min(min(c.r, c.g), c.b);\n lowp float x = max(max(c.r, c.g), c.b);\n \n if (n < 0.0) {\n c.r = l + ((c.r - l) * l) / (l - n);\n c.g = l + ((c.g - l) * l) / (l - n);\n c.b = l + ((c.b - l) * l) / (l - n);\n }\n if (x > 1.0) {\n c.r = l + ((c.r - l) * (1.0 - l)) / (x - l);\n c.g = l + ((c.g - l) * (1.0 - l)) / (x - l);\n c.b = l + ((c.b - l) * (1.0 - l)) / (x - l);\n }\n \n return c;\n }\n \n lowp vec3 setlum(lowp vec3 c, highp float l) {\n highp float d = l - lum(c);\n c = c + vec3(d);\n return clipcolor(c);\n }\n \n void main()\n {\n highp vec4 baseColor = texture2D(inputImageTexture, textureCoordinate);\n highp vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(overlayColor.rgb, lum(baseColor.rgb)) * overlayColor.a, baseColor.a);\n }\n " -public let ColorBurnBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n mediump vec4 whiteColor = vec4(1.0);\n gl_FragColor = whiteColor - (whiteColor - textureColor) / textureColor2;\n }\n " -public let ColorDodgeBlendFragmentShader = "precision mediump float;\n \n varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 base = texture2D(inputImageTexture, textureCoordinate);\n vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n vec3 baseOverlayAlphaProduct = vec3(overlay.a * base.a);\n vec3 rightHandProduct = overlay.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlay.a);\n \n vec3 firstBlendColor = baseOverlayAlphaProduct + rightHandProduct;\n vec3 overlayRGB = clamp((overlay.rgb / clamp(overlay.a, 0.01, 1.0)) * step(0.0, overlay.a), 0.0, 0.99);\n \n vec3 secondBlendColor = (base.rgb * overlay.a) / (1.0 - overlayRGB) + rightHandProduct;\n \n vec3 colorChoice = step((overlay.rgb * base.a + base.rgb * overlay.a), baseOverlayAlphaProduct);\n \n gl_FragColor = vec4(mix(firstBlendColor, secondBlendColor, colorChoice), 1.0);\n }\n " -public let ColorInvertFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = vec4((1.0 - textureColor.rgb), textureColor.w);\n }\n " -public let ColorLocalBinaryPatternFragmentShader = "precision highp float;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n lowp vec3 centerColor = texture2D(inputImageTexture, textureCoordinate).rgb;\n lowp vec3 bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb;\n lowp vec3 topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).rgb;\n lowp vec3 topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb;\n lowp vec3 bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb;\n lowp vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb;\n lowp vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb;\n lowp vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;\n lowp vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb;\n \n lowp float redByteTally = 1.0 / 255.0 * step(centerColor.r, topRightColor.r);\n redByteTally += 2.0 / 255.0 * step(centerColor.r, topColor.r);\n redByteTally += 4.0 / 255.0 * step(centerColor.r, topLeftColor.r);\n redByteTally += 8.0 / 255.0 * step(centerColor.r, leftColor.r);\n redByteTally += 16.0 / 255.0 * step(centerColor.r, bottomLeftColor.r);\n redByteTally += 32.0 / 255.0 * step(centerColor.r, bottomColor.r);\n redByteTally += 64.0 / 255.0 * step(centerColor.r, bottomRightColor.r);\n redByteTally += 128.0 / 255.0 * step(centerColor.r, rightColor.r);\n \n lowp float blueByteTally = 1.0 / 255.0 * step(centerColor.b, topRightColor.b);\n blueByteTally += 2.0 / 255.0 * step(centerColor.b, topColor.b);\n blueByteTally += 4.0 / 255.0 * step(centerColor.b, topLeftColor.b);\n blueByteTally += 8.0 / 255.0 * step(centerColor.b, leftColor.b);\n blueByteTally += 16.0 / 255.0 * step(centerColor.b, bottomLeftColor.b);\n blueByteTally += 32.0 / 255.0 * step(centerColor.b, bottomColor.b);\n blueByteTally += 64.0 / 255.0 * step(centerColor.b, bottomRightColor.b);\n blueByteTally += 128.0 / 255.0 * step(centerColor.b, rightColor.b);\n \n lowp float greenByteTally = 1.0 / 255.0 * step(centerColor.g, topRightColor.g);\n greenByteTally += 2.0 / 255.0 * step(centerColor.g, topColor.g);\n greenByteTally += 4.0 / 255.0 * step(centerColor.g, topLeftColor.g);\n greenByteTally += 8.0 / 255.0 * step(centerColor.g, leftColor.g);\n greenByteTally += 16.0 / 255.0 * step(centerColor.g, bottomLeftColor.g);\n greenByteTally += 32.0 / 255.0 * step(centerColor.g, bottomColor.g);\n greenByteTally += 64.0 / 255.0 * step(centerColor.g, bottomRightColor.g);\n greenByteTally += 128.0 / 255.0 * step(centerColor.g, rightColor.g);\n \n // TODO: Replace the above with a dot product and two vec4s\n // TODO: Apply step to a matrix, rather than individually\n \n gl_FragColor = vec4(redByteTally, blueByteTally, greenByteTally, 1.0);\n }\n " -public let ColorMatrixFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform lowp mat4 colorMatrix;\n uniform lowp float intensity;\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n lowp vec4 outputColor = textureColor * colorMatrix;\n \n gl_FragColor = (intensity * outputColor) + ((1.0 - intensity) * textureColor);\n }\n " -public let ColorSwizzlingFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n gl_FragColor = texture2D(inputImageTexture, textureCoordinate).bgra;\n }\n " -public let ColourFASTDecriptorVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n attribute vec4 inputTextureCoordinate2;\n \n uniform float texelWidth;\n uniform float texelHeight;\n \n varying vec2 textureCoordinate;\n varying vec2 pointATextureCoordinate;\n varying vec2 pointBTextureCoordinate;\n varying vec2 pointCTextureCoordinate;\n varying vec2 pointDTextureCoordinate;\n varying vec2 pointETextureCoordinate;\n varying vec2 pointFTextureCoordinate;\n varying vec2 pointGTextureCoordinate;\n varying vec2 pointHTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n float tripleTexelWidth = 3.0 * texelWidth;\n float tripleTexelHeight = 3.0 * texelHeight;\n \n textureCoordinate = inputTextureCoordinate.xy;\n \n pointATextureCoordinate = vec2(inputTextureCoordinate2.x + tripleTexelWidth, textureCoordinate.y + texelHeight);\n pointBTextureCoordinate = vec2(inputTextureCoordinate2.x + texelWidth, textureCoordinate.y + tripleTexelHeight);\n pointCTextureCoordinate = vec2(inputTextureCoordinate2.x - texelWidth, textureCoordinate.y + tripleTexelHeight);\n pointDTextureCoordinate = vec2(inputTextureCoordinate2.x - tripleTexelWidth, textureCoordinate.y + texelHeight);\n pointETextureCoordinate = vec2(inputTextureCoordinate2.x - tripleTexelWidth, textureCoordinate.y - texelHeight);\n pointFTextureCoordinate = vec2(inputTextureCoordinate2.x - texelWidth, textureCoordinate.y - tripleTexelHeight);\n pointGTextureCoordinate = vec2(inputTextureCoordinate2.x + texelWidth, textureCoordinate.y - tripleTexelHeight);\n pointHTextureCoordinate = vec2(inputTextureCoordinate2.x + tripleTexelWidth, textureCoordinate.y - texelHeight);\n }\n " -public let ColourFASTDecriptorFragmentShader = "precision highp float;\n \n varying vec2 textureCoordinate;\n varying vec2 pointATextureCoordinate;\n varying vec2 pointBTextureCoordinate;\n varying vec2 pointCTextureCoordinate;\n varying vec2 pointDTextureCoordinate;\n varying vec2 pointETextureCoordinate;\n varying vec2 pointFTextureCoordinate;\n varying vec2 pointGTextureCoordinate;\n varying vec2 pointHTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n const float PITwo = 6.2832;\n const float PI = 3.1416;\n void main()\n {\n vec3 centerColor = texture2D(inputImageTexture, textureCoordinate).rgb;\n \n vec3 pointAColor = texture2D(inputImageTexture2, pointATextureCoordinate).rgb;\n vec3 pointBColor = texture2D(inputImageTexture2, pointBTextureCoordinate).rgb;\n vec3 pointCColor = texture2D(inputImageTexture2, pointCTextureCoordinate).rgb;\n vec3 pointDColor = texture2D(inputImageTexture2, pointDTextureCoordinate).rgb;\n vec3 pointEColor = texture2D(inputImageTexture2, pointETextureCoordinate).rgb;\n vec3 pointFColor = texture2D(inputImageTexture2, pointFTextureCoordinate).rgb;\n vec3 pointGColor = texture2D(inputImageTexture2, pointGTextureCoordinate).rgb;\n vec3 pointHColor = texture2D(inputImageTexture2, pointHTextureCoordinate).rgb;\n \n vec3 colorComparison = ((pointAColor + pointBColor + pointCColor + pointDColor + pointEColor + pointFColor + pointGColor + pointHColor) * 0.125) - centerColor;\n \n // Direction calculation drawn from Appendix B of Seth Hall's Ph.D. thesis\n \n vec3 dirX = (pointAColor*0.94868) + (pointBColor*0.316227) - (pointCColor*0.316227) - (pointDColor*0.94868) - (pointEColor*0.94868) - (pointFColor*0.316227) + (pointGColor*0.316227) + (pointHColor*0.94868);\n vec3 dirY = (pointAColor*0.316227) + (pointBColor*0.94868) + (pointCColor*0.94868) + (pointDColor*0.316227) - (pointEColor*0.316227) - (pointFColor*0.94868) - (pointGColor*0.94868) - (pointHColor*0.316227);\n vec3 absoluteDifference = abs(colorComparison);\n float componentLength = length(colorComparison);\n float avgX = dot(absoluteDifference, dirX) / componentLength;\n float avgY = dot(absoluteDifference, dirY) / componentLength;\n float angle = atan(avgY, avgX);\n \n vec3 normalizedColorComparison = (colorComparison + 1.0) * 0.5;\n \n gl_FragColor = vec4(normalizedColorComparison, (angle+PI)/PITwo);\n }\n " -public let ContrastFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform lowp float contrast;\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = vec4(((textureColor.rgb - vec3(0.5)) * contrast + vec3(0.5)), textureColor.w);\n }\n " -public let Convolution3x3FragmentShader = "precision highp float;\n \n uniform sampler2D inputImageTexture;\n \n uniform mediump mat3 convolutionMatrix;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n void main()\n {\n mediump vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;\n mediump vec3 bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb;\n mediump vec3 bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb;\n mediump vec4 centerColor = texture2D(inputImageTexture, textureCoordinate);\n mediump vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb;\n mediump vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb;\n mediump vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb;\n mediump vec3 topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).rgb;\n mediump vec3 topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb;\n \n mediump vec3 resultColor = topLeftColor * convolutionMatrix[0][0] + topColor * convolutionMatrix[0][1] + topRightColor * convolutionMatrix[0][2];\n resultColor += leftColor * convolutionMatrix[1][0] + centerColor.rgb * convolutionMatrix[1][1] + rightColor * convolutionMatrix[1][2];\n resultColor += bottomLeftColor * convolutionMatrix[2][0] + bottomColor * convolutionMatrix[2][1] + bottomRightColor * convolutionMatrix[2][2];\n \n gl_FragColor = vec4(resultColor, centerColor.a);\n }\n " -public let CrosshairVertexShader = "attribute vec4 position;\n \n uniform float crosshairWidth;\n \n varying vec2 centerLocation;\n varying float pointSpacing;\n \n void main()\n {\n gl_Position = vec4(((position.xy * 2.0) - 1.0), 0.0, 1.0);\n gl_PointSize = crosshairWidth + 1.0;\n pointSpacing = 1.0 / crosshairWidth;\n centerLocation = vec2(pointSpacing * ceil(crosshairWidth / 2.0), pointSpacing * ceil(crosshairWidth / 2.0));\n }\n " -public let CrosshairFragmentShader = "uniform lowp vec3 crosshairColor;\n \n varying highp vec2 centerLocation;\n varying highp float pointSpacing;\n \n void main()\n {\n lowp vec2 distanceFromCenter = abs(centerLocation - gl_PointCoord.xy);\n lowp float axisTest = step(pointSpacing, gl_PointCoord.y) * step(distanceFromCenter.x, 0.09) + step(pointSpacing, gl_PointCoord.x) * step(distanceFromCenter.y, 0.09);\n \n gl_FragColor = vec4(crosshairColor * axisTest, axisTest);\n // gl_FragColor = vec4(distanceFromCenterInX, distanceFromCenterInY, 0.0, 1.0);\n }\n " -public let CrosshatchFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform highp float crossHatchSpacing;\n uniform highp float lineWidth;\n \n const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n highp float luminance = dot(texture2D(inputImageTexture, textureCoordinate).rgb, W);\n \n lowp vec4 colorToDisplay = vec4(1.0, 1.0, 1.0, 1.0);\n if (luminance < 1.00) \n {\n if (mod(textureCoordinate.x + textureCoordinate.y, crossHatchSpacing) <= lineWidth) \n {\n colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);\n }\n }\n if (luminance < 0.75) \n {\n if (mod(textureCoordinate.x - textureCoordinate.y, crossHatchSpacing) <= lineWidth) \n {\n colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);\n }\n }\n if (luminance < 0.50) \n {\n if (mod(textureCoordinate.x + textureCoordinate.y - (crossHatchSpacing / 2.0), crossHatchSpacing) <= lineWidth) \n {\n colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);\n }\n }\n if (luminance < 0.3) \n {\n if (mod(textureCoordinate.x - textureCoordinate.y - (crossHatchSpacing / 2.0), crossHatchSpacing) <= lineWidth) \n {\n colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);\n }\n }\n \n gl_FragColor = colorToDisplay;\n }\n " -public let DarkenBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n lowp vec4 base = texture2D(inputImageTexture, textureCoordinate);\n lowp vec4 overlayer = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(min(overlayer.rgb * base.a, base.rgb * overlayer.a) + overlayer.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlayer.a), 1.0);\n }\n " -public let DifferenceBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n gl_FragColor = vec4(abs(textureColor2.rgb - textureColor.rgb), textureColor.a);\n }\n " -public let Dilation1FragmentShader = "precision highp float;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n \n lowp vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity);\n \n gl_FragColor = max(maxValue, oneStepNegativeIntensity);\n }\n " -public let Dilation2FragmentShader = "precision highp float;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n lowp vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate);\n lowp vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate);\n \n lowp vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity);\n maxValue = max(maxValue, oneStepNegativeIntensity);\n maxValue = max(maxValue, twoStepsPositiveIntensity);\n maxValue = max(maxValue, twoStepsNegativeIntensity);\n \n gl_FragColor = max(maxValue, twoStepsNegativeIntensity);\n }\n " -public let Dilation3FragmentShader = "precision highp float;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n varying vec2 threeStepsPositiveTextureCoordinate;\n varying vec2 threeStepsNegativeTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n lowp vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate);\n lowp vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate);\n lowp vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate);\n lowp vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate);\n \n lowp vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity);\n maxValue = max(maxValue, oneStepNegativeIntensity);\n maxValue = max(maxValue, twoStepsPositiveIntensity);\n maxValue = max(maxValue, twoStepsNegativeIntensity);\n maxValue = max(maxValue, threeStepsPositiveIntensity);\n \n gl_FragColor = max(maxValue, threeStepsNegativeIntensity);\n }\n " -public let Dilation4FragmentShader = "precision highp float;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n varying vec2 threeStepsPositiveTextureCoordinate;\n varying vec2 threeStepsNegativeTextureCoordinate;\n varying vec2 fourStepsPositiveTextureCoordinate;\n varying vec2 fourStepsNegativeTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n lowp vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate);\n lowp vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate);\n lowp vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate);\n lowp vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate);\n lowp vec4 fourStepsPositiveIntensity = texture2D(inputImageTexture, fourStepsPositiveTextureCoordinate);\n lowp vec4 fourStepsNegativeIntensity = texture2D(inputImageTexture, fourStepsNegativeTextureCoordinate);\n \n lowp vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity);\n maxValue = max(maxValue, oneStepNegativeIntensity);\n maxValue = max(maxValue, twoStepsPositiveIntensity);\n maxValue = max(maxValue, twoStepsNegativeIntensity);\n maxValue = max(maxValue, threeStepsPositiveIntensity);\n maxValue = max(maxValue, threeStepsNegativeIntensity);\n maxValue = max(maxValue, fourStepsPositiveIntensity);\n \n gl_FragColor = max(maxValue, fourStepsNegativeIntensity);\n }\n " -public let DirectionalNonMaximumSuppressionFragmentShader = "precision mediump float;\n \n varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform highp float texelWidth; \n uniform highp float texelHeight; \n uniform mediump float upperThreshold; \n uniform mediump float lowerThreshold; \n \n void main()\n {\n vec3 currentGradientAndDirection = texture2D(inputImageTexture, textureCoordinate).rgb;\n vec2 gradientDirection = ((currentGradientAndDirection.gb * 2.0) - 1.0) * vec2(texelWidth, texelHeight);\n \n float firstSampledGradientMagnitude = texture2D(inputImageTexture, textureCoordinate + gradientDirection).r;\n float secondSampledGradientMagnitude = texture2D(inputImageTexture, textureCoordinate - gradientDirection).r;\n \n float multiplier = step(firstSampledGradientMagnitude, currentGradientAndDirection.r);\n multiplier = multiplier * step(secondSampledGradientMagnitude, currentGradientAndDirection.r);\n \n float thresholdCompliance = smoothstep(lowerThreshold, upperThreshold, currentGradientAndDirection.r);\n multiplier = multiplier * thresholdCompliance;\n \n gl_FragColor = vec4(multiplier, multiplier, multiplier, 1.0);\n }\n " -public let DirectionalSobelEdgeDetectionFragmentShader = "precision mediump float;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n \n vec2 gradientDirection;\n gradientDirection.x = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n gradientDirection.y = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n \n float gradientMagnitude = length(gradientDirection);\n vec2 normalizedDirection = normalize(gradientDirection);\n normalizedDirection = sign(normalizedDirection) * floor(abs(normalizedDirection) + 0.617316); // Offset by 1-sin(pi/8) to set to 0 if near axis, 1 if away\n normalizedDirection = (normalizedDirection + 1.0) * 0.5; // Place -1.0 - 1.0 within 0 - 1.0\n \n gl_FragColor = vec4(gradientMagnitude, normalizedDirection.x, normalizedDirection.y, 1.0);\n }\n " -public let DissolveBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n uniform lowp float mixturePercent;\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = mix(textureColor, textureColor2, mixturePercent);\n }\n " -public let DivideBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n mediump vec4 base = texture2D(inputImageTexture, textureCoordinate);\n mediump vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n mediump float ra;\n if (overlay.a == 0.0 || ((base.r / overlay.r) > (base.a / overlay.a)))\n ra = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n else\n ra = (base.r * overlay.a * overlay.a) / overlay.r + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n \n \n mediump float ga;\n if (overlay.a == 0.0 || ((base.g / overlay.g) > (base.a / overlay.a)))\n ga = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n else\n ga = (base.g * overlay.a * overlay.a) / overlay.g + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n \n \n mediump float ba;\n if (overlay.a == 0.0 || ((base.b / overlay.b) > (base.a / overlay.a)))\n ba = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n else\n ba = (base.b * overlay.a * overlay.a) / overlay.b + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n \n mediump float a = overlay.a + base.a - overlay.a * base.a;\n \n gl_FragColor = vec4(ra, ga, ba, a);\n }\n " -public let Erosion1FragmentShader = "precision highp float;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n \n lowp vec4 minValue = min(centerIntensity, oneStepPositiveIntensity);\n \n gl_FragColor = min(minValue, oneStepNegativeIntensity);\n }\n " -public let Erosion2FragmentShader = "precision highp float;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n lowp vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate);\n lowp vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate);\n \n lowp vec4 minValue = min(centerIntensity, oneStepPositiveIntensity);\n minValue = min(minValue, oneStepNegativeIntensity);\n minValue = min(minValue, twoStepsPositiveIntensity);\n \n gl_FragColor = min(minValue, twoStepsNegativeIntensity);\n }\n " -public let Erosion3FragmentShader = "precision highp float;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n varying vec2 threeStepsPositiveTextureCoordinate;\n varying vec2 threeStepsNegativeTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n lowp vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate);\n lowp vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate);\n lowp vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate);\n lowp vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate);\n \n lowp vec4 minValue = min(centerIntensity, oneStepPositiveIntensity);\n minValue = min(minValue, oneStepNegativeIntensity);\n minValue = min(minValue, twoStepsPositiveIntensity);\n minValue = min(minValue, twoStepsNegativeIntensity);\n minValue = min(minValue, threeStepsPositiveIntensity);\n \n gl_FragColor = min(minValue, threeStepsNegativeIntensity);\n }\n " -public let Erosion4FragmentShader = "precision highp float;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n varying vec2 threeStepsPositiveTextureCoordinate;\n varying vec2 threeStepsNegativeTextureCoordinate;\n varying vec2 fourStepsPositiveTextureCoordinate;\n varying vec2 fourStepsNegativeTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n lowp vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate);\n lowp vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate);\n lowp vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate);\n lowp vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate);\n lowp vec4 fourStepsPositiveIntensity = texture2D(inputImageTexture, fourStepsPositiveTextureCoordinate);\n lowp vec4 fourStepsNegativeIntensity = texture2D(inputImageTexture, fourStepsNegativeTextureCoordinate);\n \n lowp vec4 minValue = min(centerIntensity, oneStepPositiveIntensity);\n minValue = min(minValue, oneStepNegativeIntensity);\n minValue = min(minValue, twoStepsPositiveIntensity);\n minValue = min(minValue, twoStepsNegativeIntensity);\n minValue = min(minValue, threeStepsPositiveIntensity);\n minValue = min(minValue, threeStepsNegativeIntensity);\n minValue = min(minValue, fourStepsPositiveIntensity);\n \n gl_FragColor = min(minValue, fourStepsNegativeIntensity);\n }\n " -public let ErosionDilation1VertexShader = "attribute vec4 position;\n attribute vec2 inputTextureCoordinate;\n \n uniform float texelWidth; \n uniform float texelHeight; \n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n vec2 offset = vec2(texelWidth, texelHeight);\n \n centerTextureCoordinate = inputTextureCoordinate;\n oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;\n oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;\n }\n " -public let ErosionDilation2VertexShader = "attribute vec4 position;\n attribute vec2 inputTextureCoordinate;\n \n uniform float texelWidth;\n uniform float texelHeight;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n vec2 offset = vec2(texelWidth, texelHeight);\n \n centerTextureCoordinate = inputTextureCoordinate;\n oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;\n oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;\n twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0);\n twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0);\n }\n " -public let ErosionDilation3VertexShader = "attribute vec4 position;\n attribute vec2 inputTextureCoordinate;\n \n uniform float texelWidth;\n uniform float texelHeight;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n varying vec2 threeStepsPositiveTextureCoordinate;\n varying vec2 threeStepsNegativeTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n vec2 offset = vec2(texelWidth, texelHeight);\n \n centerTextureCoordinate = inputTextureCoordinate;\n oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;\n oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;\n twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0);\n twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0);\n threeStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 3.0);\n threeStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 3.0);\n }\n " -public let ErosionDilation4VertexShader = "attribute vec4 position;\n attribute vec2 inputTextureCoordinate;\n \n uniform float texelWidth;\n uniform float texelHeight;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepPositiveTextureCoordinate;\n varying vec2 oneStepNegativeTextureCoordinate;\n varying vec2 twoStepsPositiveTextureCoordinate;\n varying vec2 twoStepsNegativeTextureCoordinate;\n varying vec2 threeStepsPositiveTextureCoordinate;\n varying vec2 threeStepsNegativeTextureCoordinate;\n varying vec2 fourStepsPositiveTextureCoordinate;\n varying vec2 fourStepsNegativeTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n vec2 offset = vec2(texelWidth, texelHeight);\n \n centerTextureCoordinate = inputTextureCoordinate;\n oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;\n oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;\n twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0);\n twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0);\n threeStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 3.0);\n threeStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 3.0);\n fourStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 4.0);\n fourStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 4.0);\n }\n " -public let ExclusionBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n mediump vec4 base = texture2D(inputImageTexture, textureCoordinate);\n mediump vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n // Dca = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa)\n \n gl_FragColor = vec4((overlay.rgb * base.a + base.rgb * overlay.a - 2.0 * overlay.rgb * base.rgb) + overlay.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlay.a), base.a);\n }\n " -public let ExposureFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform highp float exposure;\n \n void main()\n {\n highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = vec4(textureColor.rgb * pow(2.0, exposure), textureColor.w);\n }\n " -public let FalseColorFragmentShader = "precision lowp float;\n \n varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float intensity;\n uniform vec3 firstColor;\n uniform vec3 secondColor;\n \n const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n float luminance = dot(textureColor.rgb, luminanceWeighting);\n \n gl_FragColor = vec4( mix(firstColor.rgb, secondColor.rgb, luminance), textureColor.a);\n }\n " -public let FiveInputVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n attribute vec4 inputTextureCoordinate2;\n attribute vec4 inputTextureCoordinate3;\n attribute vec4 inputTextureCoordinate4;\n attribute vec4 inputTextureCoordinate5;\n \n varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n varying vec2 textureCoordinate3;\n varying vec2 textureCoordinate4;\n varying vec2 textureCoordinate5;\n \n void main()\n {\n gl_Position = position;\n textureCoordinate = inputTextureCoordinate.xy;\n textureCoordinate2 = inputTextureCoordinate2.xy;\n textureCoordinate3 = inputTextureCoordinate3.xy;\n textureCoordinate4 = inputTextureCoordinate4.xy;\n textureCoordinate5 = inputTextureCoordinate5.xy;\n }\n " -public let FourInputVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n attribute vec4 inputTextureCoordinate2;\n attribute vec4 inputTextureCoordinate3;\n attribute vec4 inputTextureCoordinate4;\n \n varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n varying vec2 textureCoordinate3;\n varying vec2 textureCoordinate4;\n \n void main()\n {\n gl_Position = position;\n textureCoordinate = inputTextureCoordinate.xy;\n textureCoordinate2 = inputTextureCoordinate2.xy;\n textureCoordinate3 = inputTextureCoordinate3.xy;\n textureCoordinate4 = inputTextureCoordinate4.xy;\n }\n " -public let GammaFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform lowp float gamma;\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = vec4(pow(textureColor.rgb, vec3(gamma)), textureColor.w);\n }\n " -public let GlassSphereFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform highp vec2 center;\n uniform highp float radius;\n uniform highp float aspectRatio;\n uniform highp float refractiveIndex;\n // uniform vec3 lightPosition;\n const highp vec3 lightPosition = vec3(-0.5, 0.5, 1.0);\n const highp vec3 ambientLightPosition = vec3(0.0, 0.0, 1.0);\n \n void main()\n {\n highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n highp float distanceFromCenter = distance(center, textureCoordinateToUse);\n lowp float checkForPresenceWithinSphere = step(distanceFromCenter, radius);\n \n distanceFromCenter = distanceFromCenter / radius;\n \n highp float normalizedDepth = radius * sqrt(1.0 - distanceFromCenter * distanceFromCenter);\n highp vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - center, normalizedDepth));\n \n highp vec3 refractedVector = 2.0 * refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex);\n refractedVector.xy = -refractedVector.xy;\n \n highp vec3 finalSphereColor = texture2D(inputImageTexture, (refractedVector.xy + 1.0) * 0.5).rgb;\n \n // Grazing angle lighting\n highp float lightingIntensity = 2.5 * (1.0 - pow(clamp(dot(ambientLightPosition, sphereNormal), 0.0, 1.0), 0.25));\n finalSphereColor += lightingIntensity;\n \n // Specular lighting\n lightingIntensity = clamp(dot(normalize(lightPosition), sphereNormal), 0.0, 1.0);\n lightingIntensity = pow(lightingIntensity, 15.0);\n finalSphereColor += vec3(0.8, 0.8, 0.8) * lightingIntensity;\n \n gl_FragColor = vec4(finalSphereColor, 1.0) * checkForPresenceWithinSphere;\n }\n " -public let HalftoneFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform highp float fractionalWidthOfPixel;\n uniform highp float aspectRatio;\n uniform highp float dotScaling;\n \n const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n highp vec2 sampleDivisor = vec2(fractionalWidthOfPixel, fractionalWidthOfPixel / aspectRatio);\n \n highp vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor) + 0.5 * sampleDivisor;\n highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n highp vec2 adjustedSamplePos = vec2(samplePos.x, (samplePos.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n highp float distanceFromSamplePoint = distance(adjustedSamplePos, textureCoordinateToUse);\n \n lowp vec3 sampledColor = texture2D(inputImageTexture, samplePos ).rgb;\n highp float dotScaling = 1.0 - dot(sampledColor, W);\n \n lowp float checkForPresenceWithinDot = 1.0 - step(distanceFromSamplePoint, (fractionalWidthOfPixel * 0.5) * dotScaling);\n \n gl_FragColor = vec4(vec3(checkForPresenceWithinDot), 1.0);\n }\n " -public let HardLightBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n mediump vec4 base = texture2D(inputImageTexture, textureCoordinate);\n mediump vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n highp float ra;\n if (2.0 * overlay.r < overlay.a) {\n ra = 2.0 * overlay.r * base.r + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n } else {\n ra = overlay.a * base.a - 2.0 * (base.a - base.r) * (overlay.a - overlay.r) + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n }\n \n highp float ga;\n if (2.0 * overlay.g < overlay.a) {\n ga = 2.0 * overlay.g * base.g + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n } else {\n ga = overlay.a * base.a - 2.0 * (base.a - base.g) * (overlay.a - overlay.g) + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n }\n \n highp float ba;\n if (2.0 * overlay.b < overlay.a) {\n ba = 2.0 * overlay.b * base.b + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n } else {\n ba = overlay.a * base.a - 2.0 * (base.a - base.b) * (overlay.a - overlay.b) + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n }\n \n gl_FragColor = vec4(ra, ga, ba, 1.0);\n }\n " -public let HarrisCornerDetectorFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform lowp float sensitivity;\n \n const mediump float harrisConstant = 0.04;\n \n void main()\n {\n mediump vec3 derivativeElements = texture2D(inputImageTexture, textureCoordinate).rgb;\n \n mediump float derivativeSum = derivativeElements.x + derivativeElements.y;\n \n mediump float zElement = (derivativeElements.z * 2.0) - 1.0;\n \n // R = Ix^2 * Iy^2 - Ixy * Ixy - k * (Ix^2 + Iy^2)^2\n mediump float cornerness = derivativeElements.x * derivativeElements.y - (zElement * zElement) - harrisConstant * derivativeSum * derivativeSum;\n \n gl_FragColor = vec4(vec3(cornerness * sensitivity), 1.0);\n }\n " -public let HazeFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform lowp float hazeDistance;\n uniform highp float slope;\n \n void main()\n {\n //todo reconsider precision modifiers\n highp vec4 color = vec4(1.0);//todo reimplement as a parameter\n \n highp float d = textureCoordinate.y * slope + hazeDistance;\n \n highp vec4 c = texture2D(inputImageTexture, textureCoordinate) ; // consider using unpremultiply\n \n c = (c - d * color) / (1.0 -d);\n \n gl_FragColor = c; //consider using premultiply(c);\n }\n " -public let HighlightShadowTintFragmentShader = "precision lowp float;\n \n varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform lowp float shadowTintIntensity;\n uniform lowp float highlightTintIntensity;\n uniform highp vec3 shadowTintColor;\n uniform highp vec3 highlightTintColor;\n \n const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n highp float luminance = dot(textureColor.rgb, luminanceWeighting);\n \n highp vec4 shadowResult = mix(textureColor, max(textureColor, vec4( mix(shadowTintColor, textureColor.rgb, luminance), textureColor.a)), shadowTintIntensity);\n highp vec4 highlightResult = mix(textureColor, min(shadowResult, vec4( mix(shadowResult.rgb, highlightTintColor, luminance), textureColor.a)), highlightTintIntensity);\n \n gl_FragColor = vec4( mix(shadowResult.rgb, highlightResult.rgb, luminance), textureColor.a);\n }\n " -public let HighlightShadowFragmentShader = "uniform sampler2D inputImageTexture;\n varying highp vec2 textureCoordinate;\n \n uniform lowp float shadows;\n uniform lowp float highlights;\n \n const mediump vec3 luminanceWeighting = vec3(0.3, 0.3, 0.3);\n \n void main()\n {\n lowp vec4 source = texture2D(inputImageTexture, textureCoordinate);\n mediump float luminance = dot(source.rgb, luminanceWeighting);\n \n mediump float shadow = clamp((pow(luminance, 1.0/(shadows+1.0)) + (-0.76)*pow(luminance, 2.0/(shadows+1.0))) - luminance, 0.0, 1.0);\n mediump float highlight = clamp((1.0 - (pow(1.0-luminance, 1.0/(2.0-highlights)) + (-0.8)*pow(1.0-luminance, 2.0/(2.0-highlights)))) - luminance, -1.0, 0.0);\n lowp vec3 result = vec3(0.0, 0.0, 0.0) + ((luminance + shadow + highlight) - 0.0) * ((source.rgb - vec3(0.0, 0.0, 0.0))/(luminance - 0.0));\n gl_FragColor = vec4(result.rgb, source.a);\n }\n " -public let HistogramAccumulationFragmentShader = "const lowp float scalingFactor = 1.0 / 256.0;\n \n varying lowp vec3 colorFactor;\n \n void main()\n {\n gl_FragColor = vec4(colorFactor * scalingFactor , 1.0);\n }\n " -public let HistogramBlueSamplingVertexShader = "attribute vec4 position;\n \n varying vec3 colorFactor;\n \n void main()\n {\n colorFactor = vec3(0.0, 0.0, 1.0);\n gl_Position = vec4(-1.0 + (position.z * 0.0078125), 0.0, 0.0, 1.0);\n gl_PointSize = 1.0;\n }\n " -public let HistogramDisplayVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n varying vec2 textureCoordinate;\n varying float height;\n \n void main()\n {\n gl_Position = position;\n textureCoordinate = vec2(inputTextureCoordinate.x, 0.5);\n height = 1.0 - inputTextureCoordinate.y;\n }\n " -public let HistogramDisplayFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp float height;\n \n uniform sampler2D inputImageTexture;\n lowp vec4 backgroundColor = vec4(0.0, 0.0, 0.0, 0.0);\n \n void main()\n {\n lowp vec3 colorChannels = texture2D(inputImageTexture, textureCoordinate).rgb;\n lowp vec4 heightTest = vec4(step(height, colorChannels), 1.0);\n gl_FragColor = mix(backgroundColor, heightTest, heightTest.r + heightTest.g + heightTest.b);\n }\n " -public let HistogramEqualizationBlueFragmentShader = "varying highp vec2 textureCoordinate;\n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n lowp float blueCurveValue = texture2D(inputImageTexture2, vec2(textureColor.b, 0.0)).b;\n \n gl_FragColor = vec4(textureColor.r, textureColor.g, blueCurveValue, textureColor.a);\n }\n " -public let HistogramEqualizationGreenFragmentShader = "varying highp vec2 textureCoordinate;\n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n lowp float greenCurveValue = texture2D(inputImageTexture2, vec2(textureColor.g, 0.0)).g;\n \n gl_FragColor = vec4(textureColor.r, greenCurveValue, textureColor.b, textureColor.a);\n }\n " -public let HistogramEqualizationLuminanceFragmentShader = "varying highp vec2 textureCoordinate;\n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n const lowp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n lowp float luminance = dot(textureColor.rgb, W);\n lowp float newLuminance = texture2D(inputImageTexture2, vec2(luminance, 0.0)).r;\n lowp float deltaLuminance = newLuminance - luminance;\n \n lowp float red = clamp(textureColor.r + deltaLuminance, 0.0, 1.0);\n lowp float green = clamp(textureColor.g + deltaLuminance, 0.0, 1.0);\n lowp float blue = clamp(textureColor.b + deltaLuminance, 0.0, 1.0);\n \n gl_FragColor = vec4(red, green, blue, textureColor.a);\n }\n " -public let HistogramEqualizationRGBFragmentShader = "varying highp vec2 textureCoordinate; \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n lowp float redCurveValue = texture2D(inputImageTexture2, vec2(textureColor.r, 0.0)).r;\n lowp float greenCurveValue = texture2D(inputImageTexture2, vec2(textureColor.g, 0.0)).g;\n lowp float blueCurveValue = texture2D(inputImageTexture2, vec2(textureColor.b, 0.0)).b;\n \n gl_FragColor = vec4(redCurveValue, greenCurveValue, blueCurveValue, textureColor.a);\n }\n " -public let HistogramEqualizationRedFragmentShader = "varying highp vec2 textureCoordinate;\n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n lowp float redCurveValue = texture2D(inputImageTexture2, vec2(textureColor.r, 0.0)).r;\n \n gl_FragColor = vec4(redCurveValue, textureColor.g, textureColor.b, textureColor.a);\n }\n " -public let HistogramGreenSamplingVertexShader = "attribute vec4 position;\n \n varying vec3 colorFactor;\n \n void main()\n {\n colorFactor = vec3(0.0, 1.0, 0.0);\n gl_Position = vec4(-1.0 + (position.y * 0.0078125), 0.0, 0.0, 1.0);\n gl_PointSize = 1.0;\n }\n " -public let HistogramLuminanceSamplingVertexShader = "attribute vec4 position;\n \n varying vec3 colorFactor;\n \n const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n float luminance = dot(position.xyz, W);\n \n colorFactor = vec3(1.0, 1.0, 1.0);\n gl_Position = vec4(-1.0 + (luminance * 0.0078125), 0.0, 0.0, 1.0);\n gl_PointSize = 1.0;\n }\n " -public let HistogramRedSamplingVertexShader = "attribute vec4 position;\n \n varying vec3 colorFactor;\n \n void main()\n {\n colorFactor = vec3(1.0, 0.0, 0.0);\n gl_Position = vec4(-1.0 + (position.x * 0.0078125), 0.0, 0.0, 1.0);\n gl_PointSize = 1.0;\n }\n " -public let HueBlendFragmentShader = "// Hue blend mode based upon pseudo code from the PDF specification.\n \n varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n highp float lum(lowp vec3 c) {\n return dot(c, vec3(0.3, 0.59, 0.11));\n }\n \n lowp vec3 clipcolor(lowp vec3 c) {\n highp float l = lum(c);\n lowp float n = min(min(c.r, c.g), c.b);\n lowp float x = max(max(c.r, c.g), c.b);\n \n if (n < 0.0) {\n c.r = l + ((c.r - l) * l) / (l - n);\n c.g = l + ((c.g - l) * l) / (l - n);\n c.b = l + ((c.b - l) * l) / (l - n);\n }\n if (x > 1.0) {\n c.r = l + ((c.r - l) * (1.0 - l)) / (x - l);\n c.g = l + ((c.g - l) * (1.0 - l)) / (x - l);\n c.b = l + ((c.b - l) * (1.0 - l)) / (x - l);\n }\n \n return c;\n }\n \n lowp vec3 setlum(lowp vec3 c, highp float l) {\n highp float d = l - lum(c);\n c = c + vec3(d);\n return clipcolor(c);\n }\n \n highp float sat(lowp vec3 c) {\n lowp float n = min(min(c.r, c.g), c.b);\n lowp float x = max(max(c.r, c.g), c.b);\n return x - n;\n }\n \n lowp float mid(lowp float cmin, lowp float cmid, lowp float cmax, highp float s) {\n return ((cmid - cmin) * s) / (cmax - cmin);\n }\n \n lowp vec3 setsat(lowp vec3 c, highp float s) {\n if (c.r > c.g) {\n if (c.r > c.b) {\n if (c.g > c.b) {\n /* g is mid, b is min */\n c.g = mid(c.b, c.g, c.r, s);\n c.b = 0.0;\n } else {\n /* b is mid, g is min */\n c.b = mid(c.g, c.b, c.r, s);\n c.g = 0.0;\n }\n c.r = s;\n } else {\n /* b is max, r is mid, g is min */\n c.r = mid(c.g, c.r, c.b, s);\n c.b = s;\n c.r = 0.0;\n }\n } else if (c.r > c.b) {\n /* g is max, r is mid, b is min */\n c.r = mid(c.b, c.r, c.g, s);\n c.g = s;\n c.b = 0.0;\n } else if (c.g > c.b) {\n /* g is max, b is mid, r is min */\n c.b = mid(c.r, c.b, c.g, s);\n c.g = s;\n c.r = 0.0;\n } else if (c.b > c.g) {\n /* b is max, g is mid, r is min */\n c.g = mid(c.r, c.g, c.b, s);\n c.b = s;\n c.r = 0.0;\n } else {\n c = vec3(0.0);\n }\n return c;\n }\n \n void main()\n {\n highp vec4 baseColor = texture2D(inputImageTexture, textureCoordinate);\n highp vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(setsat(overlayColor.rgb, sat(baseColor.rgb)), lum(baseColor.rgb)) * overlayColor.a, baseColor.a);\n }\n " -public let HueFragmentShader = "precision highp float;\n varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform mediump float hueAdjust;\n const highp vec4 kRGBToYPrime = vec4 (0.299, 0.587, 0.114, 0.0);\n const highp vec4 kRGBToI = vec4 (0.595716, -0.274453, -0.321263, 0.0);\n const highp vec4 kRGBToQ = vec4 (0.211456, -0.522591, 0.31135, 0.0);\n \n const highp vec4 kYIQToR = vec4 (1.0, 0.9563, 0.6210, 0.0);\n const highp vec4 kYIQToG = vec4 (1.0, -0.2721, -0.6474, 0.0);\n const highp vec4 kYIQToB = vec4 (1.0, -1.1070, 1.7046, 0.0);\n \n void main ()\n {\n // Sample the input pixel\n highp vec4 color = texture2D(inputImageTexture, textureCoordinate);\n \n // Convert to YIQ\n highp float YPrime = dot (color, kRGBToYPrime);\n highp float I = dot (color, kRGBToI);\n highp float Q = dot (color, kRGBToQ);\n \n // Calculate the hue and chroma\n highp float hue = atan (Q, I);\n highp float chroma = sqrt (I * I + Q * Q);\n \n // Make the user's adjustments\n hue += (-hueAdjust); //why negative rotation?\n \n // Convert back to YIQ\n Q = chroma * sin (hue);\n I = chroma * cos (hue);\n \n // Convert back to RGB\n highp vec4 yIQ = vec4 (YPrime, I, Q, 0.0);\n color.r = dot (yIQ, kYIQToR);\n color.g = dot (yIQ, kYIQToG);\n color.b = dot (yIQ, kYIQToB);\n \n // Save the result\n gl_FragColor = color;\n }\n " -public let KuwaharaRadius3FragmentShader = "// Sourced from Kyprianidis, J. E., Kang, H., and Doellner, J. \"Anisotropic Kuwahara Filtering on the GPU,\" GPU Pro p.247 (2010).\n // \n // Original header:\n // \n // Anisotropic Kuwahara Filtering on the GPU\n // by Jan Eric Kyprianidis \n \n varying highp vec2 textureCoordinate;\n uniform sampler2D inputImageTexture;\n \n precision highp float;\n \n const vec2 src_size = vec2 (1.0 / 768.0, 1.0 / 1024.0);\n \n void main (void)\n {\n vec2 uv = textureCoordinate;\n float n = float(16); // radius is assumed to be 3\n vec3 m0 = vec3(0.0); vec3 m1 = vec3(0.0); vec3 m2 = vec3(0.0); vec3 m3 = vec3(0.0);\n vec3 s0 = vec3(0.0); vec3 s1 = vec3(0.0); vec3 s2 = vec3(0.0); vec3 s3 = vec3(0.0);\n vec3 c;\n vec3 cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(-3,-3) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-3,-2) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-3,-1) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-3,0) * src_size).rgb;\n cSq = c * c;\n m0 += c;\n s0 += cSq;\n m1 += c;\n s1 += cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(-2,-3) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-2,-2) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-2,-1) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-2,0) * src_size).rgb;\n cSq = c * c;\n m0 += c;\n s0 += cSq;\n m1 += c;\n s1 += cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(-1,-3) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-1,-2) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-1,-1) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-1,0) * src_size).rgb;\n cSq = c * c;\n m0 += c;\n s0 += cSq;\n m1 += c;\n s1 += cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(0,-3) * src_size).rgb;\n cSq = c * c;\n m0 += c;\n s0 += cSq;\n m3 += c;\n s3 += cSq;\n c = texture2D(inputImageTexture, uv + vec2(0,-2) * src_size).rgb;\n cSq = c * c;\n m0 += c;\n s0 += cSq;\n m3 += c;\n s3 += cSq;\n c = texture2D(inputImageTexture, uv + vec2(0,-1) * src_size).rgb;\n cSq = c * c;\n m0 += c;\n s0 += cSq;\n m3 += c;\n s3 += cSq;\n c = texture2D(inputImageTexture, uv + vec2(0,0) * src_size).rgb;\n cSq = c * c;\n m0 += c;\n s0 += cSq;\n m1 += c;\n s1 += cSq;\n m2 += c;\n s2 += cSq;\n m3 += c;\n s3 += cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(-3,3) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-3,2) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-3,1) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n \n c = texture2D(inputImageTexture, uv + vec2(-2,3) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-2,2) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-2,1) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n \n c = texture2D(inputImageTexture, uv + vec2(-1,3) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-1,2) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(-1,1) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n \n c = texture2D(inputImageTexture, uv + vec2(0,3) * src_size).rgb;\n cSq = c * c;\n m1 += c;\n s1 += cSq;\n m2 += c;\n s2 += cSq;\n c = texture2D(inputImageTexture, uv + vec2(0,2) * src_size).rgb;\n cSq = c * c;\n m1 += c;\n s1 += cSq;\n m2 += c;\n s2 += cSq;\n c = texture2D(inputImageTexture, uv + vec2(0,1) * src_size).rgb;\n cSq = c * c;\n m1 += c;\n s1 += cSq;\n m2 += c;\n s2 += cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(3,3) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(3,2) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(3,1) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(3,0) * src_size).rgb;\n cSq = c * c;\n m2 += c;\n s2 += cSq;\n m3 += c;\n s3 += cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(2,3) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(2,2) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(2,1) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(2,0) * src_size).rgb;\n cSq = c * c;\n m2 += c;\n s2 += cSq;\n m3 += c;\n s3 += cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(1,3) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(1,2) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(1,1) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(1,0) * src_size).rgb;\n cSq = c * c;\n m2 += c;\n s2 += cSq;\n m3 += c;\n s3 += cSq;\n \n c = texture2D(inputImageTexture, uv + vec2(3,-3) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(3,-2) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(3,-1) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n \n c = texture2D(inputImageTexture, uv + vec2(2,-3) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(2,-2) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(2,-1) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n \n c = texture2D(inputImageTexture, uv + vec2(1,-3) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(1,-2) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n c = texture2D(inputImageTexture, uv + vec2(1,-1) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n \n float min_sigma2 = 1e+2;\n m0 /= n;\n s0 = abs(s0 / n - m0 * m0);\n \n float sigma2 = s0.r + s0.g + s0.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n gl_FragColor = vec4(m0, 1.0);\n }\n \n m1 /= n;\n s1 = abs(s1 / n - m1 * m1);\n \n sigma2 = s1.r + s1.g + s1.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n gl_FragColor = vec4(m1, 1.0);\n }\n \n m2 /= n;\n s2 = abs(s2 / n - m2 * m2);\n \n sigma2 = s2.r + s2.g + s2.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n gl_FragColor = vec4(m2, 1.0);\n }\n \n m3 /= n;\n s3 = abs(s3 / n - m3 * m3);\n \n sigma2 = s3.r + s3.g + s3.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n gl_FragColor = vec4(m3, 1.0);\n }\n }\n " -public let KuwaharaFragmentShader = "// Sourced from Kyprianidis, J. E., Kang, H., and Doellner, J. \"Anisotropic Kuwahara Filtering on the GPU,\" GPU Pro p.247 (2010).\n // \n // Original header:\n // \n // Anisotropic Kuwahara Filtering on the GPU\n // by Jan Eric Kyprianidis \n \n varying highp vec2 textureCoordinate;\n uniform sampler2D inputImageTexture;\n uniform int radius;\n \n precision highp float;\n \n const vec2 src_size = vec2 (1.0 / 768.0, 1.0 / 1024.0);\n \n void main (void) \n {\n vec2 uv = textureCoordinate;\n float n = float((radius + 1) * (radius + 1));\n int i; int j;\n vec3 m0 = vec3(0.0); vec3 m1 = vec3(0.0); vec3 m2 = vec3(0.0); vec3 m3 = vec3(0.0);\n vec3 s0 = vec3(0.0); vec3 s1 = vec3(0.0); vec3 s2 = vec3(0.0); vec3 s3 = vec3(0.0);\n vec3 c;\n \n for (j = -radius; j <= 0; ++j) {\n for (i = -radius; i <= 0; ++i) {\n c = texture2D(inputImageTexture, uv + vec2(i,j) * src_size).rgb;\n m0 += c;\n s0 += c * c;\n }\n }\n \n for (j = -radius; j <= 0; ++j) {\n for (i = 0; i <= radius; ++i) {\n c = texture2D(inputImageTexture, uv + vec2(i,j) * src_size).rgb;\n m1 += c;\n s1 += c * c;\n }\n }\n \n for (j = 0; j <= radius; ++j) {\n for (i = 0; i <= radius; ++i) {\n c = texture2D(inputImageTexture, uv + vec2(i,j) * src_size).rgb;\n m2 += c;\n s2 += c * c;\n }\n }\n \n for (j = 0; j <= radius; ++j) {\n for (i = -radius; i <= 0; ++i) {\n c = texture2D(inputImageTexture, uv + vec2(i,j) * src_size).rgb;\n m3 += c;\n s3 += c * c;\n }\n }\n \n \n float min_sigma2 = 1e+2;\n m0 /= n;\n s0 = abs(s0 / n - m0 * m0);\n \n float sigma2 = s0.r + s0.g + s0.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n gl_FragColor = vec4(m0, 1.0);\n }\n \n m1 /= n;\n s1 = abs(s1 / n - m1 * m1);\n \n sigma2 = s1.r + s1.g + s1.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n gl_FragColor = vec4(m1, 1.0);\n }\n \n m2 /= n;\n s2 = abs(s2 / n - m2 * m2);\n \n sigma2 = s2.r + s2.g + s2.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n gl_FragColor = vec4(m2, 1.0);\n }\n \n m3 /= n;\n s3 = abs(s3 / n - m3 * m3);\n \n sigma2 = s3.r + s3.g + s3.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n gl_FragColor = vec4(m3, 1.0);\n }\n }\n " -public let LanczosResamplingVertexShader = "attribute vec4 position;\n attribute vec2 inputTextureCoordinate;\n \n uniform float texelWidth;\n uniform float texelHeight;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepLeftTextureCoordinate;\n varying vec2 twoStepsLeftTextureCoordinate;\n varying vec2 threeStepsLeftTextureCoordinate;\n varying vec2 fourStepsLeftTextureCoordinate;\n varying vec2 oneStepRightTextureCoordinate;\n varying vec2 twoStepsRightTextureCoordinate;\n varying vec2 threeStepsRightTextureCoordinate;\n varying vec2 fourStepsRightTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n vec2 firstOffset = vec2(texelWidth, texelHeight);\n vec2 secondOffset = vec2(2.0 * texelWidth, 2.0 * texelHeight);\n vec2 thirdOffset = vec2(3.0 * texelWidth, 3.0 * texelHeight);\n vec2 fourthOffset = vec2(4.0 * texelWidth, 4.0 * texelHeight);\n \n centerTextureCoordinate = inputTextureCoordinate;\n oneStepLeftTextureCoordinate = inputTextureCoordinate - firstOffset;\n twoStepsLeftTextureCoordinate = inputTextureCoordinate - secondOffset;\n threeStepsLeftTextureCoordinate = inputTextureCoordinate - thirdOffset;\n fourStepsLeftTextureCoordinate = inputTextureCoordinate - fourthOffset;\n oneStepRightTextureCoordinate = inputTextureCoordinate + firstOffset;\n twoStepsRightTextureCoordinate = inputTextureCoordinate + secondOffset;\n threeStepsRightTextureCoordinate = inputTextureCoordinate + thirdOffset;\n fourStepsRightTextureCoordinate = inputTextureCoordinate + fourthOffset;\n }\n " -public let LanczosResamplingFragmentShader = "precision highp float;\n \n uniform sampler2D inputImageTexture;\n \n varying vec2 centerTextureCoordinate;\n varying vec2 oneStepLeftTextureCoordinate;\n varying vec2 twoStepsLeftTextureCoordinate;\n varying vec2 threeStepsLeftTextureCoordinate;\n varying vec2 fourStepsLeftTextureCoordinate;\n varying vec2 oneStepRightTextureCoordinate;\n varying vec2 twoStepsRightTextureCoordinate;\n varying vec2 threeStepsRightTextureCoordinate;\n varying vec2 fourStepsRightTextureCoordinate;\n \n // sinc(x) * sinc(x/a) = (a * sin(pi * x) * sin(pi * x / a)) / (pi^2 * x^2)\n // Assuming a Lanczos constant of 2.0, and scaling values to max out at x = +/- 1.5\n \n void main()\n {\n lowp vec4 fragmentColor = texture2D(inputImageTexture, centerTextureCoordinate) * 0.38026;\n \n fragmentColor += texture2D(inputImageTexture, oneStepLeftTextureCoordinate) * 0.27667;\n fragmentColor += texture2D(inputImageTexture, oneStepRightTextureCoordinate) * 0.27667;\n \n fragmentColor += texture2D(inputImageTexture, twoStepsLeftTextureCoordinate) * 0.08074;\n fragmentColor += texture2D(inputImageTexture, twoStepsRightTextureCoordinate) * 0.08074;\n \n fragmentColor += texture2D(inputImageTexture, threeStepsLeftTextureCoordinate) * -0.02612;\n fragmentColor += texture2D(inputImageTexture, threeStepsRightTextureCoordinate) * -0.02612;\n \n fragmentColor += texture2D(inputImageTexture, fourStepsLeftTextureCoordinate) * -0.02143;\n fragmentColor += texture2D(inputImageTexture, fourStepsRightTextureCoordinate) * -0.02143;\n \n gl_FragColor = fragmentColor;\n }\n " -public let LaplacianFragmentShader = "precision highp float;\n \n uniform sampler2D inputImageTexture;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n void main()\n {\n mediump vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;\n mediump vec3 bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb;\n mediump vec3 bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb;\n mediump vec4 centerColor = texture2D(inputImageTexture, textureCoordinate);\n mediump vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb;\n mediump vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb;\n mediump vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb;\n mediump vec3 topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).rgb;\n mediump vec3 topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb;\n \n mediump vec3 resultColor = topLeftColor * 0.5 + topColor * 1.0 + topRightColor * 0.5;\n resultColor += leftColor * 1.0 + centerColor.rgb * (-6.0) + rightColor * 1.0;\n resultColor += bottomLeftColor * 0.5 + bottomColor * 1.0 + bottomRightColor * 0.5;\n \n // Normalize the results to allow for negative gradients in the 0.0-1.0 colorspace\n resultColor = resultColor + 0.5;\n \n gl_FragColor = vec4(resultColor, centerColor.a);\n }\n " -public let LevelsFragmentShader = "/*\n ** Gamma correction\n ** Details: http://blog.mouaif.org/2009/01/22/photoshop-gamma-correction-shader/\n */\n \n #define GammaCorrection(color, gamma) pow(color, 1.0 / gamma)\n \n /*\n ** Levels control (input (+gamma), output)\n ** Details: http://blog.mouaif.org/2009/01/28/levels-control-shader/\n */\n \n #define LevelsControlInputRange(color, minInput, maxInput) min(max(color - minInput, vec3(0.0)) / (maxInput - minInput), vec3(1.0))\n #define LevelsControlInput(color, minInput, gamma, maxInput) GammaCorrection(LevelsControlInputRange(color, minInput, maxInput), gamma)\n #define LevelsControlOutputRange(color, minOutput, maxOutput) mix(minOutput, maxOutput, color)\n #define LevelsControl(color, minInput, gamma, maxInput, minOutput, maxOutput) LevelsControlOutputRange(LevelsControlInput(color, minInput, gamma, maxInput), minOutput, maxOutput)\n \n varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform mediump vec3 levelMinimum;\n uniform mediump vec3 levelMiddle;\n uniform mediump vec3 levelMaximum;\n uniform mediump vec3 minOutput;\n uniform mediump vec3 maxOutput;\n \n void main()\n {\n mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = vec4(LevelsControl(textureColor.rgb, levelMinimum, levelMiddle, levelMaximum, minOutput, maxOutput), textureColor.a);\n }\n " -public let LightenBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = max(textureColor, textureColor2);\n }\n " -public let LineVertexShader = "attribute vec4 position;\n \n void main()\n {\n gl_Position = position;\n }\n " -public let LineFragmentShader = "uniform lowp vec3 lineColor;\n \n void main()\n {\n gl_FragColor = vec4(lineColor, 1.0);\n }\n " -public let LinearBurnBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(clamp(textureColor.rgb + textureColor2.rgb - vec3(1.0), vec3(0.0), vec3(1.0)), textureColor.a);\n }\n " -public let LocalBinaryPatternFragmentShader = "precision highp float;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n lowp float centerIntensity = texture2D(inputImageTexture, textureCoordinate).r;\n lowp float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n lowp float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n lowp float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n lowp float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n lowp float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n lowp float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n lowp float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n lowp float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n \n lowp float byteTally = 1.0 / 255.0 * step(centerIntensity, topRightIntensity);\n byteTally += 2.0 / 255.0 * step(centerIntensity, topIntensity);\n byteTally += 4.0 / 255.0 * step(centerIntensity, topLeftIntensity);\n byteTally += 8.0 / 255.0 * step(centerIntensity, leftIntensity);\n byteTally += 16.0 / 255.0 * step(centerIntensity, bottomLeftIntensity);\n byteTally += 32.0 / 255.0 * step(centerIntensity, bottomIntensity);\n byteTally += 64.0 / 255.0 * step(centerIntensity, bottomRightIntensity);\n byteTally += 128.0 / 255.0 * step(centerIntensity, rightIntensity);\n \n // TODO: Replace the above with a dot product and two vec4s\n // TODO: Apply step to a matrix, rather than individually\n \n gl_FragColor = vec4(byteTally, byteTally, byteTally, 1.0);\n }\n " -public let LookupFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2; // lookup texture\n \n uniform lowp float intensity;\n \n void main()\n {\n highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n highp float blueColor = textureColor.b * 63.0;\n \n highp vec2 quad1;\n quad1.y = floor(floor(blueColor) / 8.0);\n quad1.x = floor(blueColor) - (quad1.y * 8.0);\n \n highp vec2 quad2;\n quad2.y = floor(ceil(blueColor) / 8.0);\n quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n \n highp vec2 texPos1;\n texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);\n texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);\n \n highp vec2 texPos2;\n texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);\n texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);\n \n lowp vec4 newColor1 = texture2D(inputImageTexture2, texPos1);\n lowp vec4 newColor2 = texture2D(inputImageTexture2, texPos2);\n \n lowp vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n gl_FragColor = mix(textureColor, vec4(newColor.rgb, textureColor.w), intensity);\n }\n " -public let LuminanceRangeFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform lowp float rangeReduction;\n \n // Values from \"Graphics Shaders: Theory and Practice\" by Bailey and Cunningham\n const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n mediump float luminance = dot(textureColor.rgb, luminanceWeighting);\n mediump float luminanceRatio = ((0.5 - luminance) * rangeReduction);\n \n gl_FragColor = vec4((textureColor.rgb) + (luminanceRatio), textureColor.w);\n }\n " -public let LuminanceThresholdFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform highp float threshold;\n \n const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n highp float luminance = dot(textureColor.rgb, W);\n highp float thresholdResult = step(threshold, luminance);\n \n gl_FragColor = vec4(vec3(thresholdResult), textureColor.w);\n }\n " -public let LuminanceFragmentShader = "precision highp float;\n \n varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n // Values from \"Graphics Shaders: Theory and Practice\" by Bailey and Cunningham\n const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n float luminance = dot(textureColor.rgb, W);\n \n gl_FragColor = vec4(vec3(luminance), textureColor.a);\n }\n " -public let LuminosityBlendFragmentShader = "// Luminosity blend mode based upon pseudo code from the PDF specification.\n \n varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n highp float lum(lowp vec3 c) {\n return dot(c, vec3(0.3, 0.59, 0.11));\n }\n \n lowp vec3 clipcolor(lowp vec3 c) {\n highp float l = lum(c);\n lowp float n = min(min(c.r, c.g), c.b);\n lowp float x = max(max(c.r, c.g), c.b);\n \n if (n < 0.0) {\n c.r = l + ((c.r - l) * l) / (l - n);\n c.g = l + ((c.g - l) * l) / (l - n);\n c.b = l + ((c.b - l) * l) / (l - n);\n }\n if (x > 1.0) {\n c.r = l + ((c.r - l) * (1.0 - l)) / (x - l);\n c.g = l + ((c.g - l) * (1.0 - l)) / (x - l);\n c.b = l + ((c.b - l) * (1.0 - l)) / (x - l);\n }\n \n return c;\n }\n \n lowp vec3 setlum(lowp vec3 c, highp float l) {\n highp float d = l - lum(c);\n c = c + vec3(d);\n return clipcolor(c);\n }\n \n void main()\n {\n highp vec4 baseColor = texture2D(inputImageTexture, textureCoordinate);\n highp vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(baseColor.rgb, lum(overlayColor.rgb)) * overlayColor.a, baseColor.a);\n }\n " -public let MedianFragmentShader = "/*\n 3x3 median filter, adapted from \"A Fast, Small-Radius GPU Median Filter\" by Morgan McGuire in ShaderX6\n http://graphics.cs.williams.edu/papers/MedianShaderX6/\n \n Morgan McGuire and Kyle Whitson\n Williams College\n \n Register allocation tips by Victor Huang Xiaohuang\n University of Illinois at Urbana-Champaign\n \n http://graphics.cs.williams.edu\n \n \n Copyright (c) Morgan McGuire and Williams College, 2006\n All rights reserved.\n \n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are\n met:\n \n Redistributions of source code must retain the above copyright notice,\n this list of conditions and the following disclaimer.\n \n Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in the\n documentation and/or other materials provided with the distribution.\n \n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n \n precision highp float;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n #define s2(a, b) temp = a; a = min(a, b); b = max(temp, b);\n #define mn3(a, b, c) s2(a, b); s2(a, c);\n #define mx3(a, b, c) s2(b, c); s2(a, c);\n \n #define mnmx3(a, b, c) mx3(a, b, c); s2(a, b); // 3 exchanges\n #define mnmx4(a, b, c, d) s2(a, b); s2(c, d); s2(a, c); s2(b, d); // 4 exchanges\n #define mnmx5(a, b, c, d, e) s2(a, b); s2(c, d); mn3(a, c, e); mx3(b, d, e); // 6 exchanges\n #define mnmx6(a, b, c, d, e, f) s2(a, d); s2(b, e); s2(c, f); mn3(a, b, c); mx3(d, e, f); // 7 exchanges\n \n void main()\n {\n vec3 v[6];\n \n v[0] = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb;\n v[1] = texture2D(inputImageTexture, topRightTextureCoordinate).rgb;\n v[2] = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb;\n v[3] = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb;\n v[4] = texture2D(inputImageTexture, leftTextureCoordinate).rgb;\n v[5] = texture2D(inputImageTexture, rightTextureCoordinate).rgb;\n // v[6] = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;\n // v[7] = texture2D(inputImageTexture, topTextureCoordinate).rgb;\n vec3 temp;\n \n mnmx6(v[0], v[1], v[2], v[3], v[4], v[5]);\n \n v[5] = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;\n \n mnmx5(v[1], v[2], v[3], v[4], v[5]);\n \n v[5] = texture2D(inputImageTexture, topTextureCoordinate).rgb;\n \n mnmx4(v[2], v[3], v[4], v[5]);\n \n v[5] = texture2D(inputImageTexture, textureCoordinate).rgb;\n \n mnmx3(v[3], v[4], v[5]);\n \n gl_FragColor = vec4(v[4], 1.0);\n }\n " -public let MonochromeFragmentShader = "precision lowp float;\n \n varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float intensity;\n uniform vec3 filterColor;\n \n const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n //desat, then apply overlay blend\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n float luminance = dot(textureColor.rgb, luminanceWeighting);\n \n lowp vec4 desat = vec4(vec3(luminance), 1.0);\n \n //overlay\n lowp vec4 outputColor = vec4(\n (desat.r < 0.5 ? (2.0 * desat.r * filterColor.r) : (1.0 - 2.0 * (1.0 - desat.r) * (1.0 - filterColor.r))),\n (desat.g < 0.5 ? (2.0 * desat.g * filterColor.g) : (1.0 - 2.0 * (1.0 - desat.g) * (1.0 - filterColor.g))),\n (desat.b < 0.5 ? (2.0 * desat.b * filterColor.b) : (1.0 - 2.0 * (1.0 - desat.b) * (1.0 - filterColor.b))),\n 1.0\n );\n \n //which is better, or are they equal?\n gl_FragColor = vec4( mix(textureColor.rgb, outputColor.rgb, intensity), textureColor.a);\n }\n " -public let MotionBlurVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n uniform vec2 directionalTexelStep;\n \n varying vec2 textureCoordinate;\n varying vec2 oneStepBackTextureCoordinate;\n varying vec2 twoStepsBackTextureCoordinate;\n varying vec2 threeStepsBackTextureCoordinate;\n varying vec2 fourStepsBackTextureCoordinate;\n varying vec2 oneStepForwardTextureCoordinate;\n varying vec2 twoStepsForwardTextureCoordinate;\n varying vec2 threeStepsForwardTextureCoordinate;\n varying vec2 fourStepsForwardTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n textureCoordinate = inputTextureCoordinate.xy;\n oneStepBackTextureCoordinate = inputTextureCoordinate.xy - directionalTexelStep;\n twoStepsBackTextureCoordinate = inputTextureCoordinate.xy - 2.0 * directionalTexelStep;\n threeStepsBackTextureCoordinate = inputTextureCoordinate.xy - 3.0 * directionalTexelStep;\n fourStepsBackTextureCoordinate = inputTextureCoordinate.xy - 4.0 * directionalTexelStep;\n oneStepForwardTextureCoordinate = inputTextureCoordinate.xy + directionalTexelStep;\n twoStepsForwardTextureCoordinate = inputTextureCoordinate.xy + 2.0 * directionalTexelStep;\n threeStepsForwardTextureCoordinate = inputTextureCoordinate.xy + 3.0 * directionalTexelStep;\n fourStepsForwardTextureCoordinate = inputTextureCoordinate.xy + 4.0 * directionalTexelStep;\n }\n " -public let MotionBlurFragmentShader = "precision highp float;\n \n uniform sampler2D inputImageTexture;\n \n varying vec2 textureCoordinate;\n varying vec2 oneStepBackTextureCoordinate;\n varying vec2 twoStepsBackTextureCoordinate;\n varying vec2 threeStepsBackTextureCoordinate;\n varying vec2 fourStepsBackTextureCoordinate;\n varying vec2 oneStepForwardTextureCoordinate;\n varying vec2 twoStepsForwardTextureCoordinate;\n varying vec2 threeStepsForwardTextureCoordinate;\n varying vec2 fourStepsForwardTextureCoordinate;\n \n void main()\n {\n lowp vec4 fragmentColor = texture2D(inputImageTexture, textureCoordinate) * 0.18;\n fragmentColor += texture2D(inputImageTexture, oneStepBackTextureCoordinate) * 0.15;\n fragmentColor += texture2D(inputImageTexture, twoStepsBackTextureCoordinate) * 0.12;\n fragmentColor += texture2D(inputImageTexture, threeStepsBackTextureCoordinate) * 0.09;\n fragmentColor += texture2D(inputImageTexture, fourStepsBackTextureCoordinate) * 0.05;\n fragmentColor += texture2D(inputImageTexture, oneStepForwardTextureCoordinate) * 0.15;\n fragmentColor += texture2D(inputImageTexture, twoStepsForwardTextureCoordinate) * 0.12;\n fragmentColor += texture2D(inputImageTexture, threeStepsForwardTextureCoordinate) * 0.09;\n fragmentColor += texture2D(inputImageTexture, fourStepsForwardTextureCoordinate) * 0.05;\n \n gl_FragColor = fragmentColor;\n }\n " -public let MotionComparisonFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform highp float intensity;\n \n void main()\n {\n lowp vec3 currentImageColor = texture2D(inputImageTexture, textureCoordinate).rgb;\n lowp vec3 lowPassImageColor = texture2D(inputImageTexture2, textureCoordinate2).rgb;\n \n mediump float colorDistance = distance(currentImageColor, lowPassImageColor); // * 0.57735\n lowp float movementThreshold = step(0.2, colorDistance);\n \n gl_FragColor = movementThreshold * vec4(textureCoordinate2.x, textureCoordinate2.y, 1.0, 1.0);\n }\n " -public let MultiplyBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n lowp vec4 base = texture2D(inputImageTexture, textureCoordinate);\n lowp vec4 overlayer = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = overlayer * base + overlayer * (1.0 - base.a) + base * (1.0 - overlayer.a);\n }\n " -public let NearbyTexelSamplingVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n uniform float texelWidth;\n uniform float texelHeight; \n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n vec2 widthStep = vec2(texelWidth, 0.0);\n vec2 heightStep = vec2(0.0, texelHeight);\n vec2 widthHeightStep = vec2(texelWidth, texelHeight);\n vec2 widthNegativeHeightStep = vec2(texelWidth, -texelHeight);\n \n textureCoordinate = inputTextureCoordinate.xy;\n leftTextureCoordinate = inputTextureCoordinate.xy - widthStep;\n rightTextureCoordinate = inputTextureCoordinate.xy + widthStep;\n \n topTextureCoordinate = inputTextureCoordinate.xy - heightStep;\n topLeftTextureCoordinate = inputTextureCoordinate.xy - widthHeightStep;\n topRightTextureCoordinate = inputTextureCoordinate.xy + widthNegativeHeightStep;\n \n bottomTextureCoordinate = inputTextureCoordinate.xy + heightStep;\n bottomLeftTextureCoordinate = inputTextureCoordinate.xy - widthNegativeHeightStep;\n bottomRightTextureCoordinate = inputTextureCoordinate.xy + widthHeightStep;\n }\n " -public let NobleCornerDetectorFragmentShader = " varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform lowp float sensitivity;\n \n void main()\n {\n mediump vec3 derivativeElements = texture2D(inputImageTexture, textureCoordinate).rgb;\n \n mediump float derivativeSum = derivativeElements.x + derivativeElements.y;\n \n // R = (Ix^2 * Iy^2 - Ixy * Ixy) / (Ix^2 + Iy^2)\n mediump float zElement = (derivativeElements.z * 2.0) - 1.0;\n // mediump float harrisIntensity = (derivativeElements.x * derivativeElements.y - (derivativeElements.z * derivativeElements.z)) / (derivativeSum);\n mediump float cornerness = (derivativeElements.x * derivativeElements.y - (zElement * zElement)) / (derivativeSum);\n \n // Original Harris detector\n // R = Ix^2 * Iy^2 - Ixy * Ixy - k * (Ix^2 + Iy^2)^2\n // highp float harrisIntensity = derivativeElements.x * derivativeElements.y - (derivativeElements.z * derivativeElements.z) - harrisConstant * derivativeSum * derivativeSum;\n \n // gl_FragColor = vec4(vec3(harrisIntensity * 7.0), 1.0);\n gl_FragColor = vec4(vec3(cornerness * sensitivity), 1.0);\n }\n " -public let NormalBlendFragmentShader = "/*\n This equation is a simplification of the general blending equation. It assumes the destination color is opaque, and therefore drops the destination color's alpha term.\n \n D = C1 * C1a + C2 * C2a * (1 - C1a)\n where D is the resultant color, C1 is the color of the first element, C1a is the alpha of the first element, C2 is the second element color, C2a is the alpha of the second element. The destination alpha is calculated with:\n \n Da = C1a + C2a * (1 - C1a)\n The resultant color is premultiplied with the alpha. To restore the color to the unmultiplied values, just divide by Da, the resultant alpha.\n \n http://stackoverflow.com/questions/1724946/blend-mode-on-a-transparent-and-semi-transparent-background\n \n For some reason Photoshop behaves \n D = C1 + C2 * C2a * (1 - C1a)\n */\n \n varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n lowp vec4 c2 = texture2D(inputImageTexture, textureCoordinate);\n lowp vec4 c1 = texture2D(inputImageTexture2, textureCoordinate2);\n \n lowp vec4 outputColor;\n \n // outputColor.r = c1.r + c2.r * c2.a * (1.0 - c1.a);\n // outputColor.g = c1.g + c2.g * c2.a * (1.0 - c1.a);\n // outputColor.b = c1.b + c2.b * c2.a * (1.0 - c1.a);\n // outputColor.a = c1.a + c2.a * (1.0 - c1.a);\n \n lowp float a = c1.a + c2.a * (1.0 - c1.a);\n lowp float alphaDivisor = a + step(a, 0.0); // Protect against a divide-by-zero blacking out things in the output\n \n outputColor.r = (c1.r * c1.a + c2.r * c2.a * (1.0 - c1.a))/alphaDivisor;\n outputColor.g = (c1.g * c1.a + c2.g * c2.a * (1.0 - c1.a))/alphaDivisor;\n outputColor.b = (c1.b * c1.a + c2.b * c2.a * (1.0 - c1.a))/alphaDivisor;\n outputColor.a = a;\n \n gl_FragColor = outputColor;\n }\n " -public let OneInputVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n varying vec2 textureCoordinate;\n \n void main()\n {\n gl_Position = position;\n textureCoordinate = inputTextureCoordinate.xy;\n }\n " -public let OpacityFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform lowp float opacity;\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = vec4(textureColor.rgb, textureColor.a * opacity);\n }\n " -public let OverlayBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n mediump vec4 base = texture2D(inputImageTexture, textureCoordinate);\n mediump vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n mediump float ra;\n if (2.0 * base.r < base.a) {\n ra = 2.0 * overlay.r * base.r + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n } else {\n ra = overlay.a * base.a - 2.0 * (base.a - base.r) * (overlay.a - overlay.r) + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n }\n \n mediump float ga;\n if (2.0 * base.g < base.a) {\n ga = 2.0 * overlay.g * base.g + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n } else {\n ga = overlay.a * base.a - 2.0 * (base.a - base.g) * (overlay.a - overlay.g) + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n }\n \n mediump float ba;\n if (2.0 * base.b < base.a) {\n ba = 2.0 * overlay.b * base.b + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n } else {\n ba = overlay.a * base.a - 2.0 * (base.a - base.b) * (overlay.a - overlay.b) + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n }\n \n gl_FragColor = vec4(ra, ga, ba, 1.0);\n }\n " -public let PassthroughFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n gl_FragColor = texture2D(inputImageTexture, textureCoordinate);\n }\n " -public let PinchDistortionFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform highp float aspectRatio;\n uniform highp vec2 center;\n uniform highp float radius;\n uniform highp float scale;\n \n void main()\n {\n highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n highp float dist = distance(center, textureCoordinateToUse);\n textureCoordinateToUse = textureCoordinate;\n \n if (dist < radius)\n {\n textureCoordinateToUse -= center;\n highp float percent = 1.0 + ((0.5 - dist) / 0.5) * scale;\n textureCoordinateToUse = textureCoordinateToUse * percent;\n textureCoordinateToUse += center;\n \n gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse );\n }\n else\n {\n gl_FragColor = texture2D(inputImageTexture, textureCoordinate );\n }\n }\n " -public let PixellateFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform highp float fractionalWidthOfPixel;\n uniform highp float aspectRatio;\n \n void main()\n {\n highp vec2 sampleDivisor = vec2(fractionalWidthOfPixel, fractionalWidthOfPixel / aspectRatio);\n \n highp vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor) + 0.5 * sampleDivisor;\n gl_FragColor = texture2D(inputImageTexture, samplePos );\n }\n " -public let PolarPixellateFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform highp vec2 center;\n uniform highp vec2 pixelSize;\n \n \n void main()\n {\n highp vec2 normCoord = 2.0 * textureCoordinate - 1.0;\n highp vec2 normCenter = 2.0 * center - 1.0;\n \n normCoord -= normCenter;\n \n highp float r = length(normCoord); // to polar coords \n highp float phi = atan(normCoord.y, normCoord.x); // to polar coords \n \n r = r - mod(r, pixelSize.x) + 0.03;\n phi = phi - mod(phi, pixelSize.y);\n \n normCoord.x = r * cos(phi);\n normCoord.y = r * sin(phi);\n \n normCoord += normCenter;\n \n mediump vec2 textureCoordinateToUse = normCoord / 2.0 + 0.5;\n \n gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse );\n \n }\n " -public let PolkaDotFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform highp float fractionalWidthOfPixel;\n uniform highp float aspectRatio;\n uniform highp float dotScaling;\n \n void main()\n {\n highp vec2 sampleDivisor = vec2(fractionalWidthOfPixel, fractionalWidthOfPixel / aspectRatio);\n \n highp vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor) + 0.5 * sampleDivisor;\n highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n highp vec2 adjustedSamplePos = vec2(samplePos.x, (samplePos.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n highp float distanceFromSamplePoint = distance(adjustedSamplePos, textureCoordinateToUse);\n lowp float checkForPresenceWithinDot = step(distanceFromSamplePoint, (fractionalWidthOfPixel * 0.5) * dotScaling);\n \n lowp vec4 inputColor = texture2D(inputImageTexture, samplePos);\n \n gl_FragColor = vec4(inputColor.rgb * checkForPresenceWithinDot, inputColor.a);\n }\n " -public let PosterizeFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform highp float colorLevels;\n \n void main()\n {\n highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = floor((textureColor * colorLevels) + vec4(0.5)) / colorLevels;\n }\n " -public let PrewittEdgeDetectionFragmentShader = "precision highp float;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float edgeStrength;\n \n void main()\n {\n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n float h = -topLeftIntensity - topIntensity - topRightIntensity + bottomLeftIntensity + bottomIntensity + bottomRightIntensity;\n float v = -bottomLeftIntensity - leftIntensity - topLeftIntensity + bottomRightIntensity + rightIntensity + topRightIntensity;\n \n float mag = length(vec2(h, v)) * edgeStrength;\n \n gl_FragColor = vec4(vec3(mag), 1.0);\n }\n " -public let RGBAdjustmentFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform highp float redAdjustment;\n uniform highp float greenAdjustment;\n uniform highp float blueAdjustment;\n \n void main()\n {\n highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n gl_FragColor = vec4(textureColor.r * redAdjustment, textureColor.g * greenAdjustment, textureColor.b * blueAdjustment, textureColor.a);\n }\n " -public let SaturationBlendFragmentShader = "// Saturation blend mode based upon pseudo code from the PDF specification.\n \n varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n highp float lum(lowp vec3 c) {\n return dot(c, vec3(0.3, 0.59, 0.11));\n }\n \n lowp vec3 clipcolor(lowp vec3 c) {\n highp float l = lum(c);\n lowp float n = min(min(c.r, c.g), c.b);\n lowp float x = max(max(c.r, c.g), c.b);\n \n if (n < 0.0) {\n c.r = l + ((c.r - l) * l) / (l - n);\n c.g = l + ((c.g - l) * l) / (l - n);\n c.b = l + ((c.b - l) * l) / (l - n);\n }\n if (x > 1.0) {\n c.r = l + ((c.r - l) * (1.0 - l)) / (x - l);\n c.g = l + ((c.g - l) * (1.0 - l)) / (x - l);\n c.b = l + ((c.b - l) * (1.0 - l)) / (x - l);\n }\n \n return c;\n }\n \n lowp vec3 setlum(lowp vec3 c, highp float l) {\n highp float d = l - lum(c);\n c = c + vec3(d);\n return clipcolor(c);\n }\n \n highp float sat(lowp vec3 c) {\n lowp float n = min(min(c.r, c.g), c.b);\n lowp float x = max(max(c.r, c.g), c.b);\n return x - n;\n }\n \n lowp float mid(lowp float cmin, lowp float cmid, lowp float cmax, highp float s) {\n return ((cmid - cmin) * s) / (cmax - cmin);\n }\n \n lowp vec3 setsat(lowp vec3 c, highp float s) {\n if (c.r > c.g) {\n if (c.r > c.b) {\n if (c.g > c.b) {\n /* g is mid, b is min */\n c.g = mid(c.b, c.g, c.r, s);\n c.b = 0.0;\n } else {\n /* b is mid, g is min */\n c.b = mid(c.g, c.b, c.r, s);\n c.g = 0.0;\n }\n c.r = s;\n } else {\n /* b is max, r is mid, g is min */\n c.r = mid(c.g, c.r, c.b, s);\n c.b = s;\n c.r = 0.0;\n }\n } else if (c.r > c.b) {\n /* g is max, r is mid, b is min */\n c.r = mid(c.b, c.r, c.g, s);\n c.g = s;\n c.b = 0.0;\n } else if (c.g > c.b) {\n /* g is max, b is mid, r is min */\n c.b = mid(c.r, c.b, c.g, s);\n c.g = s;\n c.r = 0.0;\n } else if (c.b > c.g) {\n /* b is max, g is mid, r is min */\n c.g = mid(c.r, c.g, c.b, s);\n c.b = s;\n c.r = 0.0;\n } else {\n c = vec3(0.0);\n }\n return c;\n }\n \n void main()\n {\n highp vec4 baseColor = texture2D(inputImageTexture, textureCoordinate);\n highp vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(setsat(baseColor.rgb, sat(overlayColor.rgb)), lum(baseColor.rgb)) * overlayColor.a, baseColor.a);\n }\n " -public let SaturationFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform lowp float saturation;\n \n // Values from \"Graphics Shaders: Theory and Practice\" by Bailey and Cunningham\n const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n lowp float luminance = dot(textureColor.rgb, luminanceWeighting);\n lowp vec3 greyScaleColor = vec3(luminance);\n gl_FragColor = vec4(mix(greyScaleColor, textureColor.rgb, saturation), textureColor.w);\n }\n " -public let ScreenBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n mediump vec4 whiteColor = vec4(1.0);\n gl_FragColor = whiteColor - ((whiteColor - textureColor2) * (whiteColor - textureColor));\n }\n " -public let SharpenVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n uniform float texelWidth; \n uniform float texelHeight; \n uniform float sharpness;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate; \n varying vec2 topTextureCoordinate;\n varying vec2 bottomTextureCoordinate;\n \n varying float centerMultiplier;\n varying float edgeMultiplier;\n \n void main()\n {\n gl_Position = position;\n \n vec2 widthStep = vec2(texelWidth, 0.0);\n vec2 heightStep = vec2(0.0, texelHeight);\n \n textureCoordinate = inputTextureCoordinate.xy;\n leftTextureCoordinate = inputTextureCoordinate.xy - widthStep;\n rightTextureCoordinate = inputTextureCoordinate.xy + widthStep;\n topTextureCoordinate = inputTextureCoordinate.xy + heightStep; \n bottomTextureCoordinate = inputTextureCoordinate.xy - heightStep;\n \n centerMultiplier = 1.0 + 4.0 * sharpness;\n edgeMultiplier = sharpness;\n }\n " -public let SharpenFragmentShader = "precision highp float;\n \n varying highp vec2 textureCoordinate;\n varying highp vec2 leftTextureCoordinate;\n varying highp vec2 rightTextureCoordinate; \n varying highp vec2 topTextureCoordinate;\n varying highp vec2 bottomTextureCoordinate;\n \n varying highp float centerMultiplier;\n varying highp float edgeMultiplier;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n mediump vec3 textureColor = texture2D(inputImageTexture, textureCoordinate).rgb;\n mediump vec3 leftTextureColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb;\n mediump vec3 rightTextureColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb;\n mediump vec3 topTextureColor = texture2D(inputImageTexture, topTextureCoordinate).rgb;\n mediump vec3 bottomTextureColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;\n \n gl_FragColor = vec4((textureColor * centerMultiplier - (leftTextureColor * edgeMultiplier + rightTextureColor * edgeMultiplier + topTextureColor * edgeMultiplier + bottomTextureColor * edgeMultiplier)), texture2D(inputImageTexture, bottomTextureCoordinate).w);\n }\n " -public let ShiTomasiFeatureDetectorFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform lowp float sensitivity;\n \n void main()\n {\n mediump vec3 derivativeElements = texture2D(inputImageTexture, textureCoordinate).rgb;\n \n mediump float derivativeDifference = derivativeElements.x - derivativeElements.y;\n mediump float zElement = (derivativeElements.z * 2.0) - 1.0;\n \n // R = Ix^2 + Iy^2 - sqrt( (Ix^2 - Iy^2)^2 + 4 * Ixy * Ixy)\n mediump float cornerness = derivativeElements.x + derivativeElements.y - sqrt(derivativeDifference * derivativeDifference + 4.0 * zElement * zElement);\n \n gl_FragColor = vec4(vec3(cornerness * sensitivity), 1.0);\n }\n " -public let SketchFragmentShader = "precision mediump float;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform float edgeStrength;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n \n float mag = 1.0 - (length(vec2(h, v)) * edgeStrength);\n \n gl_FragColor = vec4(vec3(mag), 1.0);\n }\n " -public let SobelEdgeDetectionFragmentShader = "// Code from \"Graphics Shaders: Theory and Practice\" by M. Bailey and S. Cunningham \n \n precision mediump float;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float edgeStrength;\n \n void main()\n {\n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n \n float mag = length(vec2(h, v)) * edgeStrength;\n \n gl_FragColor = vec4(vec3(mag), 1.0);\n }\n " -public let SoftLightBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n mediump vec4 base = texture2D(inputImageTexture, textureCoordinate);\n mediump vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n lowp float alphaDivisor = base.a + step(base.a, 0.0); // Protect against a divide-by-zero blacking out things in the output\n gl_FragColor = base * (overlay.a * (base / alphaDivisor) + (2.0 * overlay * (1.0 - (base / alphaDivisor)))) + overlay * (1.0 - base.a) + base * (1.0 - overlay.a);\n }\n " -public let SolarizeFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform highp float threshold;\n \n const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n highp float luminance = dot(textureColor.rgb, W);\n highp float thresholdResult = step(luminance, threshold);\n highp vec3 finalColor = abs(thresholdResult - textureColor.rgb);\n \n gl_FragColor = vec4(finalColor, textureColor.w);\n }\n " -public let SourceOverBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate);\n \n gl_FragColor = mix(textureColor, textureColor2, textureColor2.a);\n }\n " -public let SphereRefractionFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform highp vec2 center;\n uniform highp float radius;\n uniform highp float aspectRatio;\n uniform highp float refractiveIndex;\n \n void main()\n {\n highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n highp float distanceFromCenter = distance(center, textureCoordinateToUse);\n lowp float checkForPresenceWithinSphere = step(distanceFromCenter, radius);\n \n distanceFromCenter = distanceFromCenter / radius;\n \n highp float normalizedDepth = radius * sqrt(1.0 - distanceFromCenter * distanceFromCenter);\n highp vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - center, normalizedDepth));\n \n highp vec3 refractedVector = refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex);\n \n gl_FragColor = texture2D(inputImageTexture, (refractedVector.xy + 1.0) * 0.5) * checkForPresenceWithinSphere; \n }\n " -public let StretchDistortionFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform highp vec2 center;\n \n void main()\n {\n highp vec2 normCoord = 2.0 * textureCoordinate - 1.0;\n highp vec2 normCenter = 2.0 * center - 1.0;\n \n normCoord -= normCenter;\n mediump vec2 s = sign(normCoord);\n normCoord = abs(normCoord);\n normCoord = 0.5 * normCoord + 0.5 * smoothstep(0.25, 0.5, normCoord) * normCoord;\n normCoord = s * normCoord;\n \n normCoord += normCenter;\n \n mediump vec2 textureCoordinateToUse = normCoord / 2.0 + 0.5;\n \n \n gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse );\n \n }\n " -public let SubtractBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(textureColor.rgb - textureColor2.rgb, textureColor.a);\n }\n " -public let SwirlFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform highp vec2 center;\n uniform highp float radius;\n uniform highp float angle;\n \n void main()\n {\n highp vec2 textureCoordinateToUse = textureCoordinate;\n highp float dist = distance(center, textureCoordinate);\n if (dist < radius)\n {\n textureCoordinateToUse -= center;\n highp float percent = (radius - dist) / radius;\n highp float theta = percent * percent * angle * 8.0;\n highp float s = sin(theta);\n highp float c = cos(theta);\n textureCoordinateToUse = vec2(dot(textureCoordinateToUse, vec2(c, -s)), dot(textureCoordinateToUse, vec2(s, c)));\n textureCoordinateToUse += center;\n }\n \n gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse );\n \n }\n " -public let ThreeInputVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n attribute vec4 inputTextureCoordinate2;\n attribute vec4 inputTextureCoordinate3;\n \n varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n varying vec2 textureCoordinate3;\n \n void main()\n {\n gl_Position = position;\n textureCoordinate = inputTextureCoordinate.xy;\n textureCoordinate2 = inputTextureCoordinate2.xy;\n textureCoordinate3 = inputTextureCoordinate3.xy;\n }\n " -public let ThresholdEdgeDetectionFragmentShader = "precision highp float;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float threshold;\n \n uniform float edgeStrength;\n \n void main()\n {\n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n h = max(0.0, h);\n float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n v = max(0.0, v);\n \n float mag = length(vec2(h, v)) * edgeStrength;\n mag = step(threshold, mag);\n \n gl_FragColor = vec4(vec3(mag), 1.0);\n }\n " -public let ThresholdSketchFragmentShader = "precision highp float;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform float threshold;\n \n uniform float edgeStrength;\n \n void main()\n {\n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n \n float mag = length(vec2(h, v)) * edgeStrength;\n mag = 1.0 - step(threshold, mag);\n \n gl_FragColor = vec4(vec3(mag), 1.0);\n }\n " -public let ThresholdedNonMaximumSuppressionFragmentShader = " uniform sampler2D inputImageTexture;\n \n varying highp vec2 textureCoordinate;\n varying highp vec2 leftTextureCoordinate;\n varying highp vec2 rightTextureCoordinate;\n \n varying highp vec2 topTextureCoordinate;\n varying highp vec2 topLeftTextureCoordinate;\n varying highp vec2 topRightTextureCoordinate;\n \n varying highp vec2 bottomTextureCoordinate;\n varying highp vec2 bottomLeftTextureCoordinate;\n varying highp vec2 bottomRightTextureCoordinate;\n \n uniform lowp float threshold;\n \n void main()\n {\n lowp float bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n lowp float bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n lowp float bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n lowp vec4 centerColor = texture2D(inputImageTexture, textureCoordinate);\n lowp float leftColor = texture2D(inputImageTexture, leftTextureCoordinate).r;\n lowp float rightColor = texture2D(inputImageTexture, rightTextureCoordinate).r;\n lowp float topColor = texture2D(inputImageTexture, topTextureCoordinate).r;\n lowp float topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n lowp float topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n \n // Use a tiebreaker for pixels to the left and immediately above this one\n lowp float multiplier = 1.0 - step(centerColor.r, topColor);\n multiplier = multiplier * (1.0 - step(centerColor.r, topLeftColor));\n multiplier = multiplier * (1.0 - step(centerColor.r, leftColor));\n multiplier = multiplier * (1.0 - step(centerColor.r, bottomLeftColor));\n \n lowp float maxValue = max(centerColor.r, bottomColor);\n maxValue = max(maxValue, bottomRightColor);\n maxValue = max(maxValue, rightColor);\n maxValue = max(maxValue, topRightColor);\n \n lowp float finalValue = centerColor.r * step(maxValue, centerColor.r) * multiplier;\n finalValue = step(threshold, finalValue);\n \n gl_FragColor = vec4(finalValue, finalValue, finalValue, 1.0);\n //\n // gl_FragColor = vec4((centerColor.rgb * step(maxValue, step(threshold, centerColor.r)) * multiplier), 1.0);\n }\n " -public let TiltShiftFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2; \n \n uniform highp float topFocusLevel;\n uniform highp float bottomFocusLevel;\n uniform highp float focusFallOffRate;\n \n void main()\n {\n lowp vec4 sharpImageColor = texture2D(inputImageTexture, textureCoordinate);\n lowp vec4 blurredImageColor = texture2D(inputImageTexture2, textureCoordinate2);\n \n lowp float blurIntensity = 1.0 - smoothstep(topFocusLevel - focusFallOffRate, topFocusLevel, textureCoordinate2.y);\n blurIntensity += smoothstep(bottomFocusLevel, bottomFocusLevel + focusFallOffRate, textureCoordinate2.y);\n \n gl_FragColor = mix(sharpImageColor, blurredImageColor, blurIntensity);\n }\n " -public let ToonFragmentShader = "precision highp float;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform highp float intensity;\n uniform highp float threshold;\n uniform highp float quantizationLevels;\n \n const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n \n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n \n float mag = length(vec2(h, v));\n \n vec3 posterizedImageColor = floor((textureColor.rgb * quantizationLevels) + 0.5) / quantizationLevels;\n \n float thresholdTest = 1.0 - step(threshold, mag);\n \n gl_FragColor = vec4(posterizedImageColor * thresholdTest, textureColor.a);\n }\n " -public let TransformVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n uniform mat4 transformMatrix;\n uniform mat4 orthographicMatrix;\n \n varying vec2 textureCoordinate;\n \n void main()\n {\n gl_Position = transformMatrix * vec4(position.xyz, 1.0) * orthographicMatrix;\n textureCoordinate = inputTextureCoordinate.xy;\n }\n " -public let TwoInputVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n attribute vec4 inputTextureCoordinate2;\n \n varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n void main()\n {\n gl_Position = position;\n textureCoordinate = inputTextureCoordinate.xy;\n textureCoordinate2 = inputTextureCoordinate2.xy;\n }\n " -public let UnsharpMaskFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2; \n \n uniform highp float intensity;\n \n void main()\n {\n lowp vec4 sharpImageColor = texture2D(inputImageTexture, textureCoordinate);\n lowp vec3 blurredImageColor = texture2D(inputImageTexture2, textureCoordinate2).rgb;\n \n gl_FragColor = vec4(sharpImageColor.rgb * intensity + blurredImageColor * (1.0 - intensity), sharpImageColor.a);\n }\n " -public let VibranceFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n uniform lowp float vibrance;\n \n void main() {\n lowp vec4 color = texture2D(inputImageTexture, textureCoordinate);\n lowp float average = (color.r + color.g + color.b) / 3.0;\n lowp float mx = max(color.r, max(color.g, color.b));\n lowp float amt = (mx - average) * (-vibrance * 3.0);\n color.rgb = mix(color.rgb, vec3(mx), amt);\n gl_FragColor = color;\n }\n " -public let VignetteFragmentShader = "uniform sampler2D inputImageTexture;\n varying highp vec2 textureCoordinate;\n \n uniform lowp vec2 vignetteCenter;\n uniform lowp vec3 vignetteColor;\n uniform highp float vignetteStart;\n uniform highp float vignetteEnd;\n \n void main()\n {\n lowp vec4 sourceImageColor = texture2D(inputImageTexture, textureCoordinate);\n lowp float d = distance(textureCoordinate, vec2(vignetteCenter.x, vignetteCenter.y));\n lowp float percent = smoothstep(vignetteStart, vignetteEnd, d);\n gl_FragColor = vec4(mix(sourceImageColor.rgb, vignetteColor, percent), sourceImageColor.a);\n }\n " -public let WeakPixelInclusionFragmentShader = "precision lowp float;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n float centerIntensity = texture2D(inputImageTexture, textureCoordinate).r;\n \n float pixelIntensitySum = bottomLeftIntensity + topRightIntensity + topLeftIntensity + bottomRightIntensity + leftIntensity + rightIntensity + bottomIntensity + topIntensity + centerIntensity;\n float sumTest = step(1.5, pixelIntensitySum);\n float pixelTest = step(0.01, centerIntensity);\n \n gl_FragColor = vec4(vec3(sumTest * pixelTest), 1.0);\n }\n " -public let WhiteBalanceFragmentShader = "uniform sampler2D inputImageTexture;\n varying highp vec2 textureCoordinate;\n \n uniform lowp float temperature;\n uniform lowp float tint;\n \n const lowp vec3 warmFilter = vec3(0.93, 0.54, 0.0);\n \n const mediump mat3 RGBtoYIQ = mat3(0.299, 0.587, 0.114, 0.596, -0.274, -0.322, 0.212, -0.523, 0.311);\n const mediump mat3 YIQtoRGB = mat3(1.0, 0.956, 0.621, 1.0, -0.272, -0.647, 1.0, -1.105, 1.702);\n \n void main()\n {\n lowp vec4 source = texture2D(inputImageTexture, textureCoordinate);\n \n mediump vec3 yiq = RGBtoYIQ * source.rgb; //adjusting tint\n yiq.b = clamp(yiq.b + tint*0.5226*0.1, -0.5226, 0.5226);\n lowp vec3 rgb = YIQtoRGB * yiq;\n \n lowp vec3 processed = vec3(\n (rgb.r < 0.5 ? (2.0 * rgb.r * warmFilter.r) : (1.0 - 2.0 * (1.0 - rgb.r) * (1.0 - warmFilter.r))), //adjusting temperature\n (rgb.g < 0.5 ? (2.0 * rgb.g * warmFilter.g) : (1.0 - 2.0 * (1.0 - rgb.g) * (1.0 - warmFilter.g))), \n (rgb.b < 0.5 ? (2.0 * rgb.b * warmFilter.b) : (1.0 - 2.0 * (1.0 - rgb.b) * (1.0 - warmFilter.b))));\n \n gl_FragColor = vec4(mix(rgb, processed, temperature), source.a);\n }\n " -public let XYDerivativeFragmentShader = "// I'm using the Prewitt operator to obtain the derivative, then squaring the X and Y components and placing the product of the two in Z.\n // In tests, Prewitt seemed to be tied with Sobel for the best, and it's just a little cheaper to compute.\n // This is primarily intended to be used with corner detection filters.\n \n precision highp float;\n \n varying vec2 textureCoordinate;\n varying vec2 leftTextureCoordinate;\n varying vec2 rightTextureCoordinate;\n \n varying vec2 topTextureCoordinate;\n varying vec2 topLeftTextureCoordinate;\n varying vec2 topRightTextureCoordinate;\n \n varying vec2 bottomTextureCoordinate;\n varying vec2 bottomLeftTextureCoordinate;\n varying vec2 bottomRightTextureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n \n float verticalDerivative = -topLeftIntensity - topIntensity - topRightIntensity + bottomLeftIntensity + bottomIntensity + bottomRightIntensity;\n float horizontalDerivative = -bottomLeftIntensity - leftIntensity - topLeftIntensity + bottomRightIntensity + rightIntensity + topRightIntensity;\n verticalDerivative = verticalDerivative;\n horizontalDerivative = horizontalDerivative;\n \n // Scaling the X * Y operation so that negative numbers are not clipped in the 0..1 range. This will be expanded in the corner detection filter\n gl_FragColor = vec4(horizontalDerivative * horizontalDerivative, verticalDerivative * verticalDerivative, ((verticalDerivative * horizontalDerivative) + 1.0) / 2.0, 1.0);\n }\n " -public let YUVConversionFullRangeUVPlanarFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n varying highp vec2 textureCoordinate3;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n uniform sampler2D inputImageTexture3;\n \n uniform mediump mat3 colorConversionMatrix;\n \n void main()\n {\n mediump vec3 yuv;\n \n yuv.x = texture2D(inputImageTexture, textureCoordinate).r;\n yuv.y = texture2D(inputImageTexture2, textureCoordinate).r - 0.5;\n yuv.z = texture2D(inputImageTexture3, textureCoordinate).r - 0.5;\n lowp vec3 rgb = colorConversionMatrix * yuv;\n \n gl_FragColor = vec4(rgb, 1.0);\n }\n " -public let YUVConversionFullRangeFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform mediump mat3 colorConversionMatrix;\n \n void main()\n {\n mediump vec3 yuv;\n \n yuv.x = texture2D(inputImageTexture, textureCoordinate).r;\n yuv.yz = texture2D(inputImageTexture2, textureCoordinate).ra - vec2(0.5, 0.5);\n lowp vec3 rgb = colorConversionMatrix * yuv;\n \n gl_FragColor = vec4(rgb, 1.0);\n }\n " -public let YUVConversionVideoRangeFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform mediump mat3 colorConversionMatrix;\n \n void main()\n {\n mediump vec3 yuv;\n \n yuv.x = texture2D(inputImageTexture, textureCoordinate).r - (16.0/255.0);\n yuv.yz = texture2D(inputImageTexture2, textureCoordinate).ra - vec2(0.5, 0.5);\n lowp vec3 rgb = colorConversionMatrix * yuv;\n \n gl_FragColor = vec4(rgb, 1.0);\n }\n " -public let ZoomBlurFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform highp vec2 blurCenter;\n uniform highp float blurSize;\n \n void main()\n {\n // TODO: Do a more intelligent scaling based on resolution here\n highp vec2 samplingOffset = 1.0/100.0 * (blurCenter - textureCoordinate) * blurSize;\n \n lowp vec4 fragmentColor = texture2D(inputImageTexture, textureCoordinate) * 0.18;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate + samplingOffset) * 0.15;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate + (2.0 * samplingOffset)) * 0.12;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate + (3.0 * samplingOffset)) * 0.09;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate + (4.0 * samplingOffset)) * 0.05;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate - samplingOffset) * 0.15;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate - (2.0 * samplingOffset)) * 0.12;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate - (3.0 * samplingOffset)) * 0.09;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate - (4.0 * samplingOffset)) * 0.05;\n \n gl_FragColor = fragmentColor;\n }\n " +public let AdaptiveThresholdFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + highp float blurredInput = texture2D(inputImageTexture, textureCoordinate).r; + highp float localLuminance = texture2D(inputImageTexture2, textureCoordinate2).r; + highp float thresholdResult = step(blurredInput - 0.05, localLuminance); + + gl_FragColor = vec4(vec3(thresholdResult), 1.0); +} +""" +public let AddBlendFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + lowp vec4 base = texture2D(inputImageTexture, textureCoordinate); + lowp vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2); + + mediump float r; + if (overlay.r * base.a + base.r * overlay.a >= overlay.a * base.a) { + r = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a); + } else { + r = overlay.r + base.r; + } + + mediump float g; + if (overlay.g * base.a + base.g * overlay.a >= overlay.a * base.a) { + g = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a); + } else { + g = overlay.g + base.g; + } + + mediump float b; + if (overlay.b * base.a + base.b * overlay.a >= overlay.a * base.a) { + b = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a); + } else { + b = overlay.b + base.b; + } + + mediump float a = overlay.a + base.a - overlay.a * base.a; + + gl_FragColor = vec4(r, g, b, a); +} + +""" +public let AlphaBlendFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +uniform lowp float mixturePercent; + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = vec4(mix(textureColor.rgb, textureColor2.rgb, textureColor2.a * mixturePercent), textureColor.a); +} +""" +public let AlphaTestFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + lowp vec4 color = texture2D(inputImageTexture, textureCoordinate); + if (color.a < 0.5) + { + discard; + } + else + { + gl_FragColor = color; + } +} +""" +public let AverageColorVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 upperLeftInputTextureCoordinate; +varying vec2 upperRightInputTextureCoordinate; +varying vec2 lowerLeftInputTextureCoordinate; +varying vec2 lowerRightInputTextureCoordinate; + +void main() +{ + gl_Position = position; + + upperLeftInputTextureCoordinate = inputTextureCoordinate.xy + vec2(-texelWidth, -texelHeight); + upperRightInputTextureCoordinate = inputTextureCoordinate.xy + vec2(texelWidth, -texelHeight); + lowerLeftInputTextureCoordinate = inputTextureCoordinate.xy + vec2(-texelWidth, texelHeight); + lowerRightInputTextureCoordinate = inputTextureCoordinate.xy + vec2(texelWidth, texelHeight); +} +""" +public let AverageColorFragmentShader = """ +precision highp float; + +uniform sampler2D inputImageTexture; + +varying highp vec2 outputTextureCoordinate; + +varying highp vec2 upperLeftInputTextureCoordinate; +varying highp vec2 upperRightInputTextureCoordinate; +varying highp vec2 lowerLeftInputTextureCoordinate; +varying highp vec2 lowerRightInputTextureCoordinate; + +void main() +{ + highp vec4 upperLeftColor = texture2D(inputImageTexture, upperLeftInputTextureCoordinate); + highp vec4 upperRightColor = texture2D(inputImageTexture, upperRightInputTextureCoordinate); + highp vec4 lowerLeftColor = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate); + highp vec4 lowerRightColor = texture2D(inputImageTexture, lowerRightInputTextureCoordinate); + + gl_FragColor = 0.25 * (upperLeftColor + upperRightColor + lowerLeftColor + lowerRightColor); +} +""" +public let AverageLuminanceFragmentShader = """ +precision highp float; + +uniform sampler2D inputImageTexture; + +varying highp vec2 outputTextureCoordinate; + +varying highp vec2 upperLeftInputTextureCoordinate; +varying highp vec2 upperRightInputTextureCoordinate; +varying highp vec2 lowerLeftInputTextureCoordinate; +varying highp vec2 lowerRightInputTextureCoordinate; + +void main() +{ + highp float upperLeftLuminance = texture2D(inputImageTexture, upperLeftInputTextureCoordinate).r; + highp float upperRightLuminance = texture2D(inputImageTexture, upperRightInputTextureCoordinate).r; + highp float lowerLeftLuminance = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate).r; + highp float lowerRightLuminance = texture2D(inputImageTexture, lowerRightInputTextureCoordinate).r; + + highp float luminosity = 0.25 * (upperLeftLuminance + upperRightLuminance + lowerLeftLuminance + lowerRightLuminance); + gl_FragColor = vec4(luminosity, luminosity, luminosity, 1.0); +} +""" +public let BilateralBlurVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; + +const int GAUSSIAN_SAMPLES = 9; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 textureCoordinate; +varying vec2 blurCoordinates[GAUSSIAN_SAMPLES]; + +void main() +{ + gl_Position = position; + textureCoordinate = inputTextureCoordinate.xy; + + // Calculate the positions for the blur + int multiplier = 0; + vec2 blurStep; + vec2 singleStepOffset = vec2(texelWidth, texelHeight); + + for (int i = 0; i < GAUSSIAN_SAMPLES; i++) + { + multiplier = (i - ((GAUSSIAN_SAMPLES - 1) / 2)); + // Blur in x (horizontal) + blurStep = float(multiplier) * singleStepOffset; + blurCoordinates[i] = inputTextureCoordinate.xy + blurStep; + } +} +""" +public let BilateralBlurFragmentShader = """ +uniform sampler2D inputImageTexture; + +const lowp int GAUSSIAN_SAMPLES = 9; + +varying highp vec2 textureCoordinate; +varying highp vec2 blurCoordinates[GAUSSIAN_SAMPLES]; + +uniform mediump float distanceNormalizationFactor; + +void main() +{ + lowp vec4 centralColor; + lowp float gaussianWeightTotal; + lowp vec4 sum; + lowp vec4 sampleColor; + lowp float distanceFromCentralColor; + lowp float gaussianWeight; + + centralColor = texture2D(inputImageTexture, blurCoordinates[4]); + gaussianWeightTotal = 0.18; + sum = centralColor * 0.18; + + sampleColor = texture2D(inputImageTexture, blurCoordinates[0]); + distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0); + gaussianWeight = 0.05 * (1.0 - distanceFromCentralColor); + gaussianWeightTotal += gaussianWeight; + sum += sampleColor * gaussianWeight; + + sampleColor = texture2D(inputImageTexture, blurCoordinates[1]); + distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0); + gaussianWeight = 0.09 * (1.0 - distanceFromCentralColor); + gaussianWeightTotal += gaussianWeight; + sum += sampleColor * gaussianWeight; + + sampleColor = texture2D(inputImageTexture, blurCoordinates[2]); + distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0); + gaussianWeight = 0.12 * (1.0 - distanceFromCentralColor); + gaussianWeightTotal += gaussianWeight; + sum += sampleColor * gaussianWeight; + + sampleColor = texture2D(inputImageTexture, blurCoordinates[3]); + distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0); + gaussianWeight = 0.15 * (1.0 - distanceFromCentralColor); + gaussianWeightTotal += gaussianWeight; + sum += sampleColor * gaussianWeight; + + sampleColor = texture2D(inputImageTexture, blurCoordinates[5]); + distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0); + gaussianWeight = 0.15 * (1.0 - distanceFromCentralColor); + gaussianWeightTotal += gaussianWeight; + sum += sampleColor * gaussianWeight; + + sampleColor = texture2D(inputImageTexture, blurCoordinates[6]); + distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0); + gaussianWeight = 0.12 * (1.0 - distanceFromCentralColor); + gaussianWeightTotal += gaussianWeight; + sum += sampleColor * gaussianWeight; + + sampleColor = texture2D(inputImageTexture, blurCoordinates[7]); + distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0); + gaussianWeight = 0.09 * (1.0 - distanceFromCentralColor); + gaussianWeightTotal += gaussianWeight; + sum += sampleColor * gaussianWeight; + + sampleColor = texture2D(inputImageTexture, blurCoordinates[8]); + distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0); + gaussianWeight = 0.05 * (1.0 - distanceFromCentralColor); + gaussianWeightTotal += gaussianWeight; + sum += sampleColor * gaussianWeight; + + gl_FragColor = sum / gaussianWeightTotal; +} +""" +public let BrightnessFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform lowp float brightness; + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = vec4((textureColor.rgb + vec3(brightness)), textureColor.w); +} + +""" +public let BulgeDistortionFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform highp float aspectRatio; +uniform highp vec2 center; +uniform highp float radius; +uniform highp float scale; + +void main() +{ + highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, ((textureCoordinate.y - center.y) * aspectRatio) + center.y); + highp float dist = distance(center, textureCoordinateToUse); + textureCoordinateToUse = textureCoordinate; + + if (dist < radius) + { + textureCoordinateToUse -= center; + highp float percent = 1.0 - ((radius - dist) / radius) * scale; + percent = percent * percent; + + textureCoordinateToUse = textureCoordinateToUse * percent; + textureCoordinateToUse += center; + } + + gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse ); +} +""" +public let CGAColorspaceFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + highp vec2 sampleDivisor = vec2(1.0 / 200.0, 1.0 / 320.0); + //highp vec4 colorDivisor = vec4(colorDepth); + + highp vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor); + highp vec4 color = texture2D(inputImageTexture, samplePos ); + + //gl_FragColor = texture2D(inputImageTexture, samplePos ); + mediump vec4 colorCyan = vec4(85.0 / 255.0, 1.0, 1.0, 1.0); + mediump vec4 colorMagenta = vec4(1.0, 85.0 / 255.0, 1.0, 1.0); + mediump vec4 colorWhite = vec4(1.0, 1.0, 1.0, 1.0); + mediump vec4 colorBlack = vec4(0.0, 0.0, 0.0, 1.0); + + mediump vec4 endColor; + highp float blackDistance = distance(color, colorBlack); + highp float whiteDistance = distance(color, colorWhite); + highp float magentaDistance = distance(color, colorMagenta); + highp float cyanDistance = distance(color, colorCyan); + + mediump vec4 finalColor; + + highp float colorDistance = min(magentaDistance, cyanDistance); + colorDistance = min(colorDistance, whiteDistance); + colorDistance = min(colorDistance, blackDistance); + + if (colorDistance == blackDistance) { + finalColor = colorBlack; + } else if (colorDistance == whiteDistance) { + finalColor = colorWhite; + } else if (colorDistance == cyanDistance) { + finalColor = colorCyan; + } else { + finalColor = colorMagenta; + } + + gl_FragColor = finalColor; +} +""" +public let ChromaKeyBlendFragmentShader = """ +// Shader code based on Apple's CIChromaKeyFilter example: https://developer.apple.com/library/mac/#samplecode/CIChromaKeyFilter/Introduction/Intro.html + + precision highp float; + + varying highp vec2 textureCoordinate; + varying highp vec2 textureCoordinate2; + + uniform float thresholdSensitivity; + uniform float smoothing; + uniform vec3 colorToReplace; + uniform sampler2D inputImageTexture; + uniform sampler2D inputImageTexture2; + + void main() + { + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + + float maskY = 0.2989 * colorToReplace.r + 0.5866 * colorToReplace.g + 0.1145 * colorToReplace.b; + float maskCr = 0.7132 * (colorToReplace.r - maskY); + float maskCb = 0.5647 * (colorToReplace.b - maskY); + + float Y = 0.2989 * textureColor.r + 0.5866 * textureColor.g + 0.1145 * textureColor.b; + float Cr = 0.7132 * (textureColor.r - Y); + float Cb = 0.5647 * (textureColor.b - Y); + +// float blendValue = 1.0 - smoothstep(thresholdSensitivity - smoothing, thresholdSensitivity , abs(Cr - maskCr) + abs(Cb - maskCb)); + float blendValue = 1.0 - smoothstep(thresholdSensitivity, thresholdSensitivity + smoothing, distance(vec2(Cr, Cb), vec2(maskCr, maskCb))); + gl_FragColor = mix(textureColor, textureColor2, blendValue); + } + +""" +public let ChromaKeyFragmentShader = """ +// Shader code based on Apple's CIChromaKeyFilter example: https://developer.apple.com/library/mac/#samplecode/CIChromaKeyFilter/Introduction/Intro.html + +precision highp float; + +varying highp vec2 textureCoordinate; + +uniform float thresholdSensitivity; +uniform float smoothing; +uniform vec3 colorToReplace; +uniform sampler2D inputImageTexture; + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + float maskY = 0.2989 * colorToReplace.r + 0.5866 * colorToReplace.g + 0.1145 * colorToReplace.b; + float maskCr = 0.7132 * (colorToReplace.r - maskY); + float maskCb = 0.5647 * (colorToReplace.b - maskY); + + float Y = 0.2989 * textureColor.r + 0.5866 * textureColor.g + 0.1145 * textureColor.b; + float Cr = 0.7132 * (textureColor.r - Y); + float Cb = 0.5647 * (textureColor.b - Y); + + // float blendValue = 1.0 - smoothstep(thresholdSensitivity - smoothing, thresholdSensitivity , abs(Cr - maskCr) + abs(Cb - maskCb)); + float blendValue = smoothstep(thresholdSensitivity, thresholdSensitivity + smoothing, distance(vec2(Cr, Cb), vec2(maskCr, maskCb))); + gl_FragColor = vec4(textureColor.rgb, textureColor.a * blendValue); +} +""" +public let CircleVertexShader = """ +attribute vec4 position; +varying vec2 currentPosition; +uniform float aspectRatio; + +void main() +{ + currentPosition = vec2(position.x, position.y * aspectRatio); + gl_Position = position; +} +""" +public let CircleFragmentShader = """ +uniform lowp vec4 circleColor; +uniform lowp vec4 backgroundColor; +uniform highp vec2 center; +uniform highp float radius; + +varying highp vec2 currentPosition; + +void main() +{ + highp float distanceFromCenter = distance(center, currentPosition); + highp float checkForPresenceWithinCircle = step(distanceFromCenter, radius); + + gl_FragColor = mix(backgroundColor, circleColor, checkForPresenceWithinCircle); +} +""" +public let ColorBlendFragmentShader = """ +// Color blend mode based upon pseudo code from the PDF specification. + +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +highp float lum(lowp vec3 c) { + return dot(c, vec3(0.3, 0.59, 0.11)); +} + +lowp vec3 clipcolor(lowp vec3 c) { + highp float l = lum(c); + lowp float n = min(min(c.r, c.g), c.b); + lowp float x = max(max(c.r, c.g), c.b); + + if (n < 0.0) { + c.r = l + ((c.r - l) * l) / (l - n); + c.g = l + ((c.g - l) * l) / (l - n); + c.b = l + ((c.b - l) * l) / (l - n); + } + if (x > 1.0) { + c.r = l + ((c.r - l) * (1.0 - l)) / (x - l); + c.g = l + ((c.g - l) * (1.0 - l)) / (x - l); + c.b = l + ((c.b - l) * (1.0 - l)) / (x - l); + } + + return c; +} + +lowp vec3 setlum(lowp vec3 c, highp float l) { + highp float d = l - lum(c); + c = c + vec3(d); + return clipcolor(c); +} + +void main() +{ + highp vec4 baseColor = texture2D(inputImageTexture, textureCoordinate); + highp vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(overlayColor.rgb, lum(baseColor.rgb)) * overlayColor.a, baseColor.a); +} +""" +public let ColorBurnBlendFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + mediump vec4 whiteColor = vec4(1.0); + gl_FragColor = whiteColor - (whiteColor - textureColor) / textureColor2; +} +""" +public let ColorDodgeBlendFragmentShader = """ +precision mediump float; + +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + vec4 base = texture2D(inputImageTexture, textureCoordinate); + vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2); + + vec3 baseOverlayAlphaProduct = vec3(overlay.a * base.a); + vec3 rightHandProduct = overlay.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlay.a); + + vec3 firstBlendColor = baseOverlayAlphaProduct + rightHandProduct; + vec3 overlayRGB = clamp((overlay.rgb / clamp(overlay.a, 0.01, 1.0)) * step(0.0, overlay.a), 0.0, 0.99); + + vec3 secondBlendColor = (base.rgb * overlay.a) / (1.0 - overlayRGB) + rightHandProduct; + + vec3 colorChoice = step((overlay.rgb * base.a + base.rgb * overlay.a), baseOverlayAlphaProduct); + + gl_FragColor = vec4(mix(firstBlendColor, secondBlendColor, colorChoice), 1.0); +} +""" +public let ColorInvertFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = vec4((1.0 - textureColor.rgb), textureColor.w); +} +""" +public let ColorLocalBinaryPatternFragmentShader = """ +precision highp float; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + lowp vec3 centerColor = texture2D(inputImageTexture, textureCoordinate).rgb; + lowp vec3 bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb; + lowp vec3 topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).rgb; + lowp vec3 topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb; + lowp vec3 bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb; + lowp vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb; + lowp vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb; + lowp vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb; + lowp vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb; + + lowp float redByteTally = 1.0 / 255.0 * step(centerColor.r, topRightColor.r); + redByteTally += 2.0 / 255.0 * step(centerColor.r, topColor.r); + redByteTally += 4.0 / 255.0 * step(centerColor.r, topLeftColor.r); + redByteTally += 8.0 / 255.0 * step(centerColor.r, leftColor.r); + redByteTally += 16.0 / 255.0 * step(centerColor.r, bottomLeftColor.r); + redByteTally += 32.0 / 255.0 * step(centerColor.r, bottomColor.r); + redByteTally += 64.0 / 255.0 * step(centerColor.r, bottomRightColor.r); + redByteTally += 128.0 / 255.0 * step(centerColor.r, rightColor.r); + + lowp float blueByteTally = 1.0 / 255.0 * step(centerColor.b, topRightColor.b); + blueByteTally += 2.0 / 255.0 * step(centerColor.b, topColor.b); + blueByteTally += 4.0 / 255.0 * step(centerColor.b, topLeftColor.b); + blueByteTally += 8.0 / 255.0 * step(centerColor.b, leftColor.b); + blueByteTally += 16.0 / 255.0 * step(centerColor.b, bottomLeftColor.b); + blueByteTally += 32.0 / 255.0 * step(centerColor.b, bottomColor.b); + blueByteTally += 64.0 / 255.0 * step(centerColor.b, bottomRightColor.b); + blueByteTally += 128.0 / 255.0 * step(centerColor.b, rightColor.b); + + lowp float greenByteTally = 1.0 / 255.0 * step(centerColor.g, topRightColor.g); + greenByteTally += 2.0 / 255.0 * step(centerColor.g, topColor.g); + greenByteTally += 4.0 / 255.0 * step(centerColor.g, topLeftColor.g); + greenByteTally += 8.0 / 255.0 * step(centerColor.g, leftColor.g); + greenByteTally += 16.0 / 255.0 * step(centerColor.g, bottomLeftColor.g); + greenByteTally += 32.0 / 255.0 * step(centerColor.g, bottomColor.g); + greenByteTally += 64.0 / 255.0 * step(centerColor.g, bottomRightColor.g); + greenByteTally += 128.0 / 255.0 * step(centerColor.g, rightColor.g); + + // TODO: Replace the above with a dot product and two vec4s + // TODO: Apply step to a matrix, rather than individually + + gl_FragColor = vec4(redByteTally, blueByteTally, greenByteTally, 1.0); +} +""" +public let ColorMatrixFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform lowp mat4 colorMatrix; +uniform lowp float intensity; + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + lowp vec4 outputColor = textureColor * colorMatrix; + + gl_FragColor = (intensity * outputColor) + ((1.0 - intensity) * textureColor); +} +""" +public let ColorSwizzlingFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + gl_FragColor = texture2D(inputImageTexture, textureCoordinate).bgra; +} +""" +public let ColourFASTDecriptorVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; +attribute vec4 inputTextureCoordinate2; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 textureCoordinate; +varying vec2 pointATextureCoordinate; +varying vec2 pointBTextureCoordinate; +varying vec2 pointCTextureCoordinate; +varying vec2 pointDTextureCoordinate; +varying vec2 pointETextureCoordinate; +varying vec2 pointFTextureCoordinate; +varying vec2 pointGTextureCoordinate; +varying vec2 pointHTextureCoordinate; + +void main() +{ + gl_Position = position; + + float tripleTexelWidth = 3.0 * texelWidth; + float tripleTexelHeight = 3.0 * texelHeight; + + textureCoordinate = inputTextureCoordinate.xy; + + pointATextureCoordinate = vec2(inputTextureCoordinate2.x + tripleTexelWidth, textureCoordinate.y + texelHeight); + pointBTextureCoordinate = vec2(inputTextureCoordinate2.x + texelWidth, textureCoordinate.y + tripleTexelHeight); + pointCTextureCoordinate = vec2(inputTextureCoordinate2.x - texelWidth, textureCoordinate.y + tripleTexelHeight); + pointDTextureCoordinate = vec2(inputTextureCoordinate2.x - tripleTexelWidth, textureCoordinate.y + texelHeight); + pointETextureCoordinate = vec2(inputTextureCoordinate2.x - tripleTexelWidth, textureCoordinate.y - texelHeight); + pointFTextureCoordinate = vec2(inputTextureCoordinate2.x - texelWidth, textureCoordinate.y - tripleTexelHeight); + pointGTextureCoordinate = vec2(inputTextureCoordinate2.x + texelWidth, textureCoordinate.y - tripleTexelHeight); + pointHTextureCoordinate = vec2(inputTextureCoordinate2.x + tripleTexelWidth, textureCoordinate.y - texelHeight); +} +""" +public let ColourFASTDecriptorFragmentShader = """ +precision highp float; + +varying vec2 textureCoordinate; +varying vec2 pointATextureCoordinate; +varying vec2 pointBTextureCoordinate; +varying vec2 pointCTextureCoordinate; +varying vec2 pointDTextureCoordinate; +varying vec2 pointETextureCoordinate; +varying vec2 pointFTextureCoordinate; +varying vec2 pointGTextureCoordinate; +varying vec2 pointHTextureCoordinate; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; +const float PITwo = 6.2832; +const float PI = 3.1416; +void main() +{ + vec3 centerColor = texture2D(inputImageTexture, textureCoordinate).rgb; + + vec3 pointAColor = texture2D(inputImageTexture2, pointATextureCoordinate).rgb; + vec3 pointBColor = texture2D(inputImageTexture2, pointBTextureCoordinate).rgb; + vec3 pointCColor = texture2D(inputImageTexture2, pointCTextureCoordinate).rgb; + vec3 pointDColor = texture2D(inputImageTexture2, pointDTextureCoordinate).rgb; + vec3 pointEColor = texture2D(inputImageTexture2, pointETextureCoordinate).rgb; + vec3 pointFColor = texture2D(inputImageTexture2, pointFTextureCoordinate).rgb; + vec3 pointGColor = texture2D(inputImageTexture2, pointGTextureCoordinate).rgb; + vec3 pointHColor = texture2D(inputImageTexture2, pointHTextureCoordinate).rgb; + + vec3 colorComparison = ((pointAColor + pointBColor + pointCColor + pointDColor + pointEColor + pointFColor + pointGColor + pointHColor) * 0.125) - centerColor; + + // Direction calculation drawn from Appendix B of Seth Hall's Ph.D. thesis + + vec3 dirX = (pointAColor*0.94868) + (pointBColor*0.316227) - (pointCColor*0.316227) - (pointDColor*0.94868) - (pointEColor*0.94868) - (pointFColor*0.316227) + (pointGColor*0.316227) + (pointHColor*0.94868); + vec3 dirY = (pointAColor*0.316227) + (pointBColor*0.94868) + (pointCColor*0.94868) + (pointDColor*0.316227) - (pointEColor*0.316227) - (pointFColor*0.94868) - (pointGColor*0.94868) - (pointHColor*0.316227); + vec3 absoluteDifference = abs(colorComparison); + float componentLength = length(colorComparison); + float avgX = dot(absoluteDifference, dirX) / componentLength; + float avgY = dot(absoluteDifference, dirY) / componentLength; + float angle = atan(avgY, avgX); + + vec3 normalizedColorComparison = (colorComparison + 1.0) * 0.5; + + gl_FragColor = vec4(normalizedColorComparison, (angle+PI)/PITwo); +} +""" +public let ContrastFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform lowp float contrast; + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = vec4(((textureColor.rgb - vec3(0.5)) * contrast + vec3(0.5)), textureColor.w); +} +""" +public let Convolution3x3FragmentShader = """ +precision highp float; + +uniform sampler2D inputImageTexture; + +uniform mediump mat3 convolutionMatrix; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +void main() +{ + mediump vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb; + mediump vec3 bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb; + mediump vec3 bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb; + mediump vec4 centerColor = texture2D(inputImageTexture, textureCoordinate); + mediump vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb; + mediump vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb; + mediump vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb; + mediump vec3 topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).rgb; + mediump vec3 topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb; + + mediump vec3 resultColor = topLeftColor * convolutionMatrix[0][0] + topColor * convolutionMatrix[0][1] + topRightColor * convolutionMatrix[0][2]; + resultColor += leftColor * convolutionMatrix[1][0] + centerColor.rgb * convolutionMatrix[1][1] + rightColor * convolutionMatrix[1][2]; + resultColor += bottomLeftColor * convolutionMatrix[2][0] + bottomColor * convolutionMatrix[2][1] + bottomRightColor * convolutionMatrix[2][2]; + + gl_FragColor = vec4(resultColor, centerColor.a); +} +""" +public let CrosshairVertexShader = """ +attribute vec4 position; + +uniform float crosshairWidth; + +varying vec2 centerLocation; +varying float pointSpacing; + +void main() +{ + gl_Position = vec4(((position.xy * 2.0) - 1.0), 0.0, 1.0); + gl_PointSize = crosshairWidth + 1.0; + pointSpacing = 1.0 / crosshairWidth; + centerLocation = vec2(pointSpacing * ceil(crosshairWidth / 2.0), pointSpacing * ceil(crosshairWidth / 2.0)); +} +""" +public let CrosshairFragmentShader = """ +uniform lowp vec3 crosshairColor; + +varying highp vec2 centerLocation; +varying highp float pointSpacing; + +void main() +{ + lowp vec2 distanceFromCenter = abs(centerLocation - gl_PointCoord.xy); + lowp float axisTest = step(pointSpacing, gl_PointCoord.y) * step(distanceFromCenter.x, 0.09) + step(pointSpacing, gl_PointCoord.x) * step(distanceFromCenter.y, 0.09); + + gl_FragColor = vec4(crosshairColor * axisTest, axisTest); +// gl_FragColor = vec4(distanceFromCenterInX, distanceFromCenterInY, 0.0, 1.0); +} +""" +public let CrosshatchFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform highp float crossHatchSpacing; +uniform highp float lineWidth; + +const highp vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + highp float luminance = dot(texture2D(inputImageTexture, textureCoordinate).rgb, W); + + lowp vec4 colorToDisplay = vec4(1.0, 1.0, 1.0, 1.0); + if (luminance < 1.00) + { + if (mod(textureCoordinate.x + textureCoordinate.y, crossHatchSpacing) <= lineWidth) + { + colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0); + } + } + if (luminance < 0.75) + { + if (mod(textureCoordinate.x - textureCoordinate.y, crossHatchSpacing) <= lineWidth) + { + colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0); + } + } + if (luminance < 0.50) + { + if (mod(textureCoordinate.x + textureCoordinate.y - (crossHatchSpacing / 2.0), crossHatchSpacing) <= lineWidth) + { + colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0); + } + } + if (luminance < 0.3) + { + if (mod(textureCoordinate.x - textureCoordinate.y - (crossHatchSpacing / 2.0), crossHatchSpacing) <= lineWidth) + { + colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0); + } + } + + gl_FragColor = colorToDisplay; +} +""" +public let DarkenBlendFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + lowp vec4 base = texture2D(inputImageTexture, textureCoordinate); + lowp vec4 overlayer = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = vec4(min(overlayer.rgb * base.a, base.rgb * overlayer.a) + overlayer.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlayer.a), 1.0); +} +""" +public let DifferenceBlendFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + gl_FragColor = vec4(abs(textureColor2.rgb - textureColor.rgb), textureColor.a); +} +""" +public let Dilation1FragmentShader = """ +precision highp float; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate); + lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate); + lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate); + + lowp vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity); + + gl_FragColor = max(maxValue, oneStepNegativeIntensity); +} +""" +public let Dilation2FragmentShader = """ +precision highp float; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate); + lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate); + lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate); + lowp vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate); + lowp vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate); + + lowp vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity); + maxValue = max(maxValue, oneStepNegativeIntensity); + maxValue = max(maxValue, twoStepsPositiveIntensity); + maxValue = max(maxValue, twoStepsNegativeIntensity); + + gl_FragColor = max(maxValue, twoStepsNegativeIntensity); +} +""" +public let Dilation3FragmentShader = """ +precision highp float; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; +varying vec2 threeStepsPositiveTextureCoordinate; +varying vec2 threeStepsNegativeTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate); + lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate); + lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate); + lowp vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate); + lowp vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate); + lowp vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate); + lowp vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate); + + lowp vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity); + maxValue = max(maxValue, oneStepNegativeIntensity); + maxValue = max(maxValue, twoStepsPositiveIntensity); + maxValue = max(maxValue, twoStepsNegativeIntensity); + maxValue = max(maxValue, threeStepsPositiveIntensity); + + gl_FragColor = max(maxValue, threeStepsNegativeIntensity); +} +""" +public let Dilation4FragmentShader = """ +precision highp float; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; +varying vec2 threeStepsPositiveTextureCoordinate; +varying vec2 threeStepsNegativeTextureCoordinate; +varying vec2 fourStepsPositiveTextureCoordinate; +varying vec2 fourStepsNegativeTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate); + lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate); + lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate); + lowp vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate); + lowp vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate); + lowp vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate); + lowp vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate); + lowp vec4 fourStepsPositiveIntensity = texture2D(inputImageTexture, fourStepsPositiveTextureCoordinate); + lowp vec4 fourStepsNegativeIntensity = texture2D(inputImageTexture, fourStepsNegativeTextureCoordinate); + + lowp vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity); + maxValue = max(maxValue, oneStepNegativeIntensity); + maxValue = max(maxValue, twoStepsPositiveIntensity); + maxValue = max(maxValue, twoStepsNegativeIntensity); + maxValue = max(maxValue, threeStepsPositiveIntensity); + maxValue = max(maxValue, threeStepsNegativeIntensity); + maxValue = max(maxValue, fourStepsPositiveIntensity); + + gl_FragColor = max(maxValue, fourStepsNegativeIntensity); +} +""" +public let DirectionalNonMaximumSuppressionFragmentShader = """ +precision mediump float; + +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform highp float texelWidth; +uniform highp float texelHeight; +uniform mediump float upperThreshold; +uniform mediump float lowerThreshold; + +void main() +{ + vec3 currentGradientAndDirection = texture2D(inputImageTexture, textureCoordinate).rgb; + vec2 gradientDirection = ((currentGradientAndDirection.gb * 2.0) - 1.0) * vec2(texelWidth, texelHeight); + + float firstSampledGradientMagnitude = texture2D(inputImageTexture, textureCoordinate + gradientDirection).r; + float secondSampledGradientMagnitude = texture2D(inputImageTexture, textureCoordinate - gradientDirection).r; + + float multiplier = step(firstSampledGradientMagnitude, currentGradientAndDirection.r); + multiplier = multiplier * step(secondSampledGradientMagnitude, currentGradientAndDirection.r); + + float thresholdCompliance = smoothstep(lowerThreshold, upperThreshold, currentGradientAndDirection.r); + multiplier = multiplier * thresholdCompliance; + + gl_FragColor = vec4(multiplier, multiplier, multiplier, 1.0); +} +""" +public let DirectionalSobelEdgeDetectionFragmentShader = """ +precision mediump float; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + + vec2 gradientDirection; + gradientDirection.x = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity; + gradientDirection.y = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity; + + float gradientMagnitude = length(gradientDirection); + vec2 normalizedDirection = normalize(gradientDirection); + normalizedDirection = sign(normalizedDirection) * floor(abs(normalizedDirection) + 0.617316); // Offset by 1-sin(pi/8) to set to 0 if near axis, 1 if away + normalizedDirection = (normalizedDirection + 1.0) * 0.5; // Place -1.0 - 1.0 within 0 - 1.0 + + gl_FragColor = vec4(gradientMagnitude, normalizedDirection.x, normalizedDirection.y, 1.0); +} +""" +public let DissolveBlendFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; +uniform lowp float mixturePercent; + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = mix(textureColor, textureColor2, mixturePercent); +} +""" +public let DivideBlendFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + mediump vec4 base = texture2D(inputImageTexture, textureCoordinate); + mediump vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2); + + mediump float ra; + if (overlay.a == 0.0 || ((base.r / overlay.r) > (base.a / overlay.a))) + ra = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a); + else + ra = (base.r * overlay.a * overlay.a) / overlay.r + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a); + + + mediump float ga; + if (overlay.a == 0.0 || ((base.g / overlay.g) > (base.a / overlay.a))) + ga = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a); + else + ga = (base.g * overlay.a * overlay.a) / overlay.g + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a); + + + mediump float ba; + if (overlay.a == 0.0 || ((base.b / overlay.b) > (base.a / overlay.a))) + ba = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a); + else + ba = (base.b * overlay.a * overlay.a) / overlay.b + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a); + + mediump float a = overlay.a + base.a - overlay.a * base.a; + + gl_FragColor = vec4(ra, ga, ba, a); +} +""" +public let Erosion1FragmentShader = """ +precision highp float; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate); + lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate); + lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate); + + lowp vec4 minValue = min(centerIntensity, oneStepPositiveIntensity); + + gl_FragColor = min(minValue, oneStepNegativeIntensity); +} +""" +public let Erosion2FragmentShader = """ +precision highp float; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate); + lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate); + lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate); + lowp vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate); + lowp vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate); + + lowp vec4 minValue = min(centerIntensity, oneStepPositiveIntensity); + minValue = min(minValue, oneStepNegativeIntensity); + minValue = min(minValue, twoStepsPositiveIntensity); + + gl_FragColor = min(minValue, twoStepsNegativeIntensity); +} +""" +public let Erosion3FragmentShader = """ +precision highp float; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; +varying vec2 threeStepsPositiveTextureCoordinate; +varying vec2 threeStepsNegativeTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate); + lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate); + lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate); + lowp vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate); + lowp vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate); + lowp vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate); + lowp vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate); + + lowp vec4 minValue = min(centerIntensity, oneStepPositiveIntensity); + minValue = min(minValue, oneStepNegativeIntensity); + minValue = min(minValue, twoStepsPositiveIntensity); + minValue = min(minValue, twoStepsNegativeIntensity); + minValue = min(minValue, threeStepsPositiveIntensity); + + gl_FragColor = min(minValue, threeStepsNegativeIntensity); +} +""" +public let Erosion4FragmentShader = """ +precision highp float; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; +varying vec2 threeStepsPositiveTextureCoordinate; +varying vec2 threeStepsNegativeTextureCoordinate; +varying vec2 fourStepsPositiveTextureCoordinate; +varying vec2 fourStepsNegativeTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate); + lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate); + lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate); + lowp vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate); + lowp vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate); + lowp vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate); + lowp vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate); + lowp vec4 fourStepsPositiveIntensity = texture2D(inputImageTexture, fourStepsPositiveTextureCoordinate); + lowp vec4 fourStepsNegativeIntensity = texture2D(inputImageTexture, fourStepsNegativeTextureCoordinate); + + lowp vec4 minValue = min(centerIntensity, oneStepPositiveIntensity); + minValue = min(minValue, oneStepNegativeIntensity); + minValue = min(minValue, twoStepsPositiveIntensity); + minValue = min(minValue, twoStepsNegativeIntensity); + minValue = min(minValue, threeStepsPositiveIntensity); + minValue = min(minValue, threeStepsNegativeIntensity); + minValue = min(minValue, fourStepsPositiveIntensity); + + gl_FragColor = min(minValue, fourStepsNegativeIntensity); +} +""" +public let ErosionDilation1VertexShader = """ +attribute vec4 position; +attribute vec2 inputTextureCoordinate; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; + +void main() +{ + gl_Position = position; + + vec2 offset = vec2(texelWidth, texelHeight); + + centerTextureCoordinate = inputTextureCoordinate; + oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset; + oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset; +} +""" +public let ErosionDilation2VertexShader = """ +attribute vec4 position; +attribute vec2 inputTextureCoordinate; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; + +void main() +{ + gl_Position = position; + + vec2 offset = vec2(texelWidth, texelHeight); + + centerTextureCoordinate = inputTextureCoordinate; + oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset; + oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset; + twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0); + twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0); +} +""" +public let ErosionDilation3VertexShader = """ +attribute vec4 position; +attribute vec2 inputTextureCoordinate; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; +varying vec2 threeStepsPositiveTextureCoordinate; +varying vec2 threeStepsNegativeTextureCoordinate; + +void main() +{ + gl_Position = position; + + vec2 offset = vec2(texelWidth, texelHeight); + + centerTextureCoordinate = inputTextureCoordinate; + oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset; + oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset; + twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0); + twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0); + threeStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 3.0); + threeStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 3.0); +} +""" +public let ErosionDilation4VertexShader = """ +attribute vec4 position; +attribute vec2 inputTextureCoordinate; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepPositiveTextureCoordinate; +varying vec2 oneStepNegativeTextureCoordinate; +varying vec2 twoStepsPositiveTextureCoordinate; +varying vec2 twoStepsNegativeTextureCoordinate; +varying vec2 threeStepsPositiveTextureCoordinate; +varying vec2 threeStepsNegativeTextureCoordinate; +varying vec2 fourStepsPositiveTextureCoordinate; +varying vec2 fourStepsNegativeTextureCoordinate; + +void main() +{ + gl_Position = position; + + vec2 offset = vec2(texelWidth, texelHeight); + + centerTextureCoordinate = inputTextureCoordinate; + oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset; + oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset; + twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0); + twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0); + threeStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 3.0); + threeStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 3.0); + fourStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 4.0); + fourStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 4.0); +} +""" +public let ExclusionBlendFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + mediump vec4 base = texture2D(inputImageTexture, textureCoordinate); + mediump vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2); + + // Dca = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa) + + gl_FragColor = vec4((overlay.rgb * base.a + base.rgb * overlay.a - 2.0 * overlay.rgb * base.rgb) + overlay.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlay.a), base.a); +} +""" +public let ExposureFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform highp float exposure; + +void main() +{ + highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = vec4(textureColor.rgb * pow(2.0, exposure), textureColor.w); +} +""" +public let FalseColorFragmentShader = """ +precision lowp float; + +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float intensity; +uniform vec3 firstColor; +uniform vec3 secondColor; + +const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + float luminance = dot(textureColor.rgb, luminanceWeighting); + + gl_FragColor = vec4( mix(firstColor.rgb, secondColor.rgb, luminance), textureColor.a); +} +""" +public let FiveInputVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; +attribute vec4 inputTextureCoordinate2; +attribute vec4 inputTextureCoordinate3; +attribute vec4 inputTextureCoordinate4; +attribute vec4 inputTextureCoordinate5; + +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; +varying vec2 textureCoordinate3; +varying vec2 textureCoordinate4; +varying vec2 textureCoordinate5; + +void main() +{ + gl_Position = position; + textureCoordinate = inputTextureCoordinate.xy; + textureCoordinate2 = inputTextureCoordinate2.xy; + textureCoordinate3 = inputTextureCoordinate3.xy; + textureCoordinate4 = inputTextureCoordinate4.xy; + textureCoordinate5 = inputTextureCoordinate5.xy; +} +""" +public let FourInputVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; +attribute vec4 inputTextureCoordinate2; +attribute vec4 inputTextureCoordinate3; +attribute vec4 inputTextureCoordinate4; + +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; +varying vec2 textureCoordinate3; +varying vec2 textureCoordinate4; + +void main() +{ + gl_Position = position; + textureCoordinate = inputTextureCoordinate.xy; + textureCoordinate2 = inputTextureCoordinate2.xy; + textureCoordinate3 = inputTextureCoordinate3.xy; + textureCoordinate4 = inputTextureCoordinate4.xy; +} +""" +public let GammaFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform lowp float gamma; + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = vec4(pow(textureColor.rgb, vec3(gamma)), textureColor.w); +} +""" +public let GlassSphereFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform highp vec2 center; +uniform highp float radius; +uniform highp float aspectRatio; +uniform highp float refractiveIndex; +// uniform vec3 lightPosition; +const highp vec3 lightPosition = vec3(-0.5, 0.5, 1.0); +const highp vec3 ambientLightPosition = vec3(0.0, 0.0, 1.0); + +void main() +{ + highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); + highp float distanceFromCenter = distance(center, textureCoordinateToUse); + lowp float checkForPresenceWithinSphere = step(distanceFromCenter, radius); + + distanceFromCenter = distanceFromCenter / radius; + + highp float normalizedDepth = radius * sqrt(1.0 - distanceFromCenter * distanceFromCenter); + highp vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - center, normalizedDepth)); + + highp vec3 refractedVector = 2.0 * refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex); + refractedVector.xy = -refractedVector.xy; + + highp vec3 finalSphereColor = texture2D(inputImageTexture, (refractedVector.xy + 1.0) * 0.5).rgb; + + // Grazing angle lighting + highp float lightingIntensity = 2.5 * (1.0 - pow(clamp(dot(ambientLightPosition, sphereNormal), 0.0, 1.0), 0.25)); + finalSphereColor += lightingIntensity; + + // Specular lighting + lightingIntensity = clamp(dot(normalize(lightPosition), sphereNormal), 0.0, 1.0); + lightingIntensity = pow(lightingIntensity, 15.0); + finalSphereColor += vec3(0.8, 0.8, 0.8) * lightingIntensity; + + gl_FragColor = vec4(finalSphereColor, 1.0) * checkForPresenceWithinSphere; +} +""" +public let HalftoneFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform highp float fractionalWidthOfPixel; +uniform highp float aspectRatio; +uniform highp float dotScaling; + +const highp vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + highp vec2 sampleDivisor = vec2(fractionalWidthOfPixel, fractionalWidthOfPixel / aspectRatio); + + highp vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor) + 0.5 * sampleDivisor; + highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); + highp vec2 adjustedSamplePos = vec2(samplePos.x, (samplePos.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); + highp float distanceFromSamplePoint = distance(adjustedSamplePos, textureCoordinateToUse); + + lowp vec3 sampledColor = texture2D(inputImageTexture, samplePos ).rgb; + highp float dotScaling = 1.0 - dot(sampledColor, W); + + lowp float checkForPresenceWithinDot = 1.0 - step(distanceFromSamplePoint, (fractionalWidthOfPixel * 0.5) * dotScaling); + + gl_FragColor = vec4(vec3(checkForPresenceWithinDot), 1.0); +} +""" +public let HardLightBlendFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +const highp vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + mediump vec4 base = texture2D(inputImageTexture, textureCoordinate); + mediump vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2); + + highp float ra; + if (2.0 * overlay.r < overlay.a) { + ra = 2.0 * overlay.r * base.r + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a); + } else { + ra = overlay.a * base.a - 2.0 * (base.a - base.r) * (overlay.a - overlay.r) + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a); + } + + highp float ga; + if (2.0 * overlay.g < overlay.a) { + ga = 2.0 * overlay.g * base.g + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a); + } else { + ga = overlay.a * base.a - 2.0 * (base.a - base.g) * (overlay.a - overlay.g) + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a); + } + + highp float ba; + if (2.0 * overlay.b < overlay.a) { + ba = 2.0 * overlay.b * base.b + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a); + } else { + ba = overlay.a * base.a - 2.0 * (base.a - base.b) * (overlay.a - overlay.b) + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a); + } + + gl_FragColor = vec4(ra, ga, ba, 1.0); +} +""" +public let HarrisCornerDetectorFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform lowp float sensitivity; + +const mediump float harrisConstant = 0.04; + +void main() +{ + mediump vec3 derivativeElements = texture2D(inputImageTexture, textureCoordinate).rgb; + + mediump float derivativeSum = derivativeElements.x + derivativeElements.y; + + mediump float zElement = (derivativeElements.z * 2.0) - 1.0; + + // R = Ix^2 * Iy^2 - Ixy * Ixy - k * (Ix^2 + Iy^2)^2 + mediump float cornerness = derivativeElements.x * derivativeElements.y - (zElement * zElement) - harrisConstant * derivativeSum * derivativeSum; + + gl_FragColor = vec4(vec3(cornerness * sensitivity), 1.0); +} +""" +public let HazeFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform lowp float hazeDistance; +uniform highp float slope; + +void main() +{ +//todo reconsider precision modifiers + highp vec4 color = vec4(1.0);//todo reimplement as a parameter + + highp float d = textureCoordinate.y * slope + hazeDistance; + + highp vec4 c = texture2D(inputImageTexture, textureCoordinate) ; // consider using unpremultiply + + c = (c - d * color) / (1.0 -d); + + gl_FragColor = c; //consider using premultiply(c); +} +""" +public let HighlightShadowTintFragmentShader = """ +precision lowp float; + +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform lowp float shadowTintIntensity; +uniform lowp float highlightTintIntensity; +uniform highp vec3 shadowTintColor; +uniform highp vec3 highlightTintColor; + +const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + highp float luminance = dot(textureColor.rgb, luminanceWeighting); + + highp vec4 shadowResult = mix(textureColor, max(textureColor, vec4( mix(shadowTintColor, textureColor.rgb, luminance), textureColor.a)), shadowTintIntensity); + highp vec4 highlightResult = mix(textureColor, min(shadowResult, vec4( mix(shadowResult.rgb, highlightTintColor, luminance), textureColor.a)), highlightTintIntensity); + + gl_FragColor = vec4( mix(shadowResult.rgb, highlightResult.rgb, luminance), textureColor.a); +} +""" +public let HighlightShadowFragmentShader = """ +uniform sampler2D inputImageTexture; +varying highp vec2 textureCoordinate; + +uniform lowp float shadows; +uniform lowp float highlights; + +const mediump vec3 luminanceWeighting = vec3(0.3, 0.3, 0.3); + +void main() +{ + lowp vec4 source = texture2D(inputImageTexture, textureCoordinate); + mediump float luminance = dot(source.rgb, luminanceWeighting); + + mediump float shadow = clamp((pow(luminance, 1.0/(shadows+1.0)) + (-0.76)*pow(luminance, 2.0/(shadows+1.0))) - luminance, 0.0, 1.0); + mediump float highlight = clamp((1.0 - (pow(1.0-luminance, 1.0/(2.0-highlights)) + (-0.8)*pow(1.0-luminance, 2.0/(2.0-highlights)))) - luminance, -1.0, 0.0); + lowp vec3 result = vec3(0.0, 0.0, 0.0) + ((luminance + shadow + highlight) - 0.0) * ((source.rgb - vec3(0.0, 0.0, 0.0))/(luminance - 0.0)); + gl_FragColor = vec4(result.rgb, source.a); +} +""" +public let HistogramAccumulationFragmentShader = """ +const lowp float scalingFactor = 1.0 / 256.0; + +varying lowp vec3 colorFactor; + +void main() +{ + gl_FragColor = vec4(colorFactor * scalingFactor , 1.0); +} +""" +public let HistogramBlueSamplingVertexShader = """ +attribute vec4 position; + +varying vec3 colorFactor; + +void main() +{ + colorFactor = vec3(0.0, 0.0, 1.0); + gl_Position = vec4(-1.0 + (position.z * 0.0078125), 0.0, 0.0, 1.0); + gl_PointSize = 1.0; +} +""" +public let HistogramDisplayVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; + +varying vec2 textureCoordinate; +varying float height; + +void main() +{ + gl_Position = position; + textureCoordinate = vec2(inputTextureCoordinate.x, 0.5); + height = 1.0 - inputTextureCoordinate.y; +} +""" +public let HistogramDisplayFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp float height; + +uniform sampler2D inputImageTexture; +lowp vec4 backgroundColor = vec4(0.0, 0.0, 0.0, 0.0); + +void main() +{ + lowp vec3 colorChannels = texture2D(inputImageTexture, textureCoordinate).rgb; + lowp vec4 heightTest = vec4(step(height, colorChannels), 1.0); + gl_FragColor = mix(backgroundColor, heightTest, heightTest.r + heightTest.g + heightTest.b); +} +""" +public let HistogramEqualizationBlueFragmentShader = """ +varying highp vec2 textureCoordinate; +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + lowp float blueCurveValue = texture2D(inputImageTexture2, vec2(textureColor.b, 0.0)).b; + + gl_FragColor = vec4(textureColor.r, textureColor.g, blueCurveValue, textureColor.a); +} +""" +public let HistogramEqualizationGreenFragmentShader = """ +varying highp vec2 textureCoordinate; +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + lowp float greenCurveValue = texture2D(inputImageTexture2, vec2(textureColor.g, 0.0)).g; + + gl_FragColor = vec4(textureColor.r, greenCurveValue, textureColor.b, textureColor.a); +} +""" +public let HistogramEqualizationLuminanceFragmentShader = """ +varying highp vec2 textureCoordinate; +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +const lowp vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + lowp float luminance = dot(textureColor.rgb, W); + lowp float newLuminance = texture2D(inputImageTexture2, vec2(luminance, 0.0)).r; + lowp float deltaLuminance = newLuminance - luminance; + + lowp float red = clamp(textureColor.r + deltaLuminance, 0.0, 1.0); + lowp float green = clamp(textureColor.g + deltaLuminance, 0.0, 1.0); + lowp float blue = clamp(textureColor.b + deltaLuminance, 0.0, 1.0); + + gl_FragColor = vec4(red, green, blue, textureColor.a); +} +""" +public let HistogramEqualizationRGBFragmentShader = """ +varying highp vec2 textureCoordinate; +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + lowp float redCurveValue = texture2D(inputImageTexture2, vec2(textureColor.r, 0.0)).r; + lowp float greenCurveValue = texture2D(inputImageTexture2, vec2(textureColor.g, 0.0)).g; + lowp float blueCurveValue = texture2D(inputImageTexture2, vec2(textureColor.b, 0.0)).b; + + gl_FragColor = vec4(redCurveValue, greenCurveValue, blueCurveValue, textureColor.a); +} +""" +public let HistogramEqualizationRedFragmentShader = """ +varying highp vec2 textureCoordinate; +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + lowp float redCurveValue = texture2D(inputImageTexture2, vec2(textureColor.r, 0.0)).r; + + gl_FragColor = vec4(redCurveValue, textureColor.g, textureColor.b, textureColor.a); +} +""" +public let HistogramGreenSamplingVertexShader = """ +attribute vec4 position; + +varying vec3 colorFactor; + +void main() +{ + colorFactor = vec3(0.0, 1.0, 0.0); + gl_Position = vec4(-1.0 + (position.y * 0.0078125), 0.0, 0.0, 1.0); + gl_PointSize = 1.0; +} +""" +public let HistogramLuminanceSamplingVertexShader = """ +attribute vec4 position; + +varying vec3 colorFactor; + +const vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + float luminance = dot(position.xyz, W); + + colorFactor = vec3(1.0, 1.0, 1.0); + gl_Position = vec4(-1.0 + (luminance * 0.0078125), 0.0, 0.0, 1.0); + gl_PointSize = 1.0; +} +""" +public let HistogramRedSamplingVertexShader = """ +attribute vec4 position; + +varying vec3 colorFactor; + +void main() +{ + colorFactor = vec3(1.0, 0.0, 0.0); + gl_Position = vec4(-1.0 + (position.x * 0.0078125), 0.0, 0.0, 1.0); + gl_PointSize = 1.0; +} +""" +public let HueBlendFragmentShader = """ +// Hue blend mode based upon pseudo code from the PDF specification. + +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +highp float lum(lowp vec3 c) { + return dot(c, vec3(0.3, 0.59, 0.11)); +} + +lowp vec3 clipcolor(lowp vec3 c) { + highp float l = lum(c); + lowp float n = min(min(c.r, c.g), c.b); + lowp float x = max(max(c.r, c.g), c.b); + + if (n < 0.0) { + c.r = l + ((c.r - l) * l) / (l - n); + c.g = l + ((c.g - l) * l) / (l - n); + c.b = l + ((c.b - l) * l) / (l - n); + } + if (x > 1.0) { + c.r = l + ((c.r - l) * (1.0 - l)) / (x - l); + c.g = l + ((c.g - l) * (1.0 - l)) / (x - l); + c.b = l + ((c.b - l) * (1.0 - l)) / (x - l); + } + + return c; +} + +lowp vec3 setlum(lowp vec3 c, highp float l) { + highp float d = l - lum(c); + c = c + vec3(d); + return clipcolor(c); +} + +highp float sat(lowp vec3 c) { + lowp float n = min(min(c.r, c.g), c.b); + lowp float x = max(max(c.r, c.g), c.b); + return x - n; +} + +lowp float mid(lowp float cmin, lowp float cmid, lowp float cmax, highp float s) { + return ((cmid - cmin) * s) / (cmax - cmin); +} + +lowp vec3 setsat(lowp vec3 c, highp float s) { + if (c.r > c.g) { + if (c.r > c.b) { + if (c.g > c.b) { + /* g is mid, b is min */ + c.g = mid(c.b, c.g, c.r, s); + c.b = 0.0; + } else { + /* b is mid, g is min */ + c.b = mid(c.g, c.b, c.r, s); + c.g = 0.0; + } + c.r = s; + } else { + /* b is max, r is mid, g is min */ + c.r = mid(c.g, c.r, c.b, s); + c.b = s; + c.r = 0.0; + } + } else if (c.r > c.b) { + /* g is max, r is mid, b is min */ + c.r = mid(c.b, c.r, c.g, s); + c.g = s; + c.b = 0.0; + } else if (c.g > c.b) { + /* g is max, b is mid, r is min */ + c.b = mid(c.r, c.b, c.g, s); + c.g = s; + c.r = 0.0; + } else if (c.b > c.g) { + /* b is max, g is mid, r is min */ + c.g = mid(c.r, c.g, c.b, s); + c.b = s; + c.r = 0.0; + } else { + c = vec3(0.0); + } + return c; +} + +void main() +{ + highp vec4 baseColor = texture2D(inputImageTexture, textureCoordinate); + highp vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(setsat(overlayColor.rgb, sat(baseColor.rgb)), lum(baseColor.rgb)) * overlayColor.a, baseColor.a); +} + +""" +public let HueFragmentShader = """ +precision highp float; +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform mediump float hueAdjust; +const highp vec4 kRGBToYPrime = vec4 (0.299, 0.587, 0.114, 0.0); +const highp vec4 kRGBToI = vec4 (0.595716, -0.274453, -0.321263, 0.0); +const highp vec4 kRGBToQ = vec4 (0.211456, -0.522591, 0.31135, 0.0); + +const highp vec4 kYIQToR = vec4 (1.0, 0.9563, 0.6210, 0.0); +const highp vec4 kYIQToG = vec4 (1.0, -0.2721, -0.6474, 0.0); +const highp vec4 kYIQToB = vec4 (1.0, -1.1070, 1.7046, 0.0); + +void main () +{ + // Sample the input pixel + highp vec4 color = texture2D(inputImageTexture, textureCoordinate); + + // Convert to YIQ + highp float YPrime = dot (color, kRGBToYPrime); + highp float I = dot (color, kRGBToI); + highp float Q = dot (color, kRGBToQ); + + // Calculate the hue and chroma + highp float hue = atan (Q, I); + highp float chroma = sqrt (I * I + Q * Q); + + // Make the user's adjustments + hue += (-hueAdjust); //why negative rotation? + + // Convert back to YIQ + Q = chroma * sin (hue); + I = chroma * cos (hue); + + // Convert back to RGB + highp vec4 yIQ = vec4 (YPrime, I, Q, 0.0); + color.r = dot (yIQ, kYIQToR); + color.g = dot (yIQ, kYIQToG); + color.b = dot (yIQ, kYIQToB); + + // Save the result + gl_FragColor = color; +} +""" +public let KuwaharaRadius3FragmentShader = """ +// Sourced from Kyprianidis, J. E., Kang, H., and Doellner, J. "Anisotropic Kuwahara Filtering on the GPU," GPU Pro p.247 (2010). +// +// Original header: +// +// Anisotropic Kuwahara Filtering on the GPU +// by Jan Eric Kyprianidis + +varying highp vec2 textureCoordinate; +uniform sampler2D inputImageTexture; + +precision highp float; + +const vec2 src_size = vec2 (1.0 / 768.0, 1.0 / 1024.0); + +void main (void) +{ + vec2 uv = textureCoordinate; + float n = float(16); // radius is assumed to be 3 + vec3 m0 = vec3(0.0); vec3 m1 = vec3(0.0); vec3 m2 = vec3(0.0); vec3 m3 = vec3(0.0); + vec3 s0 = vec3(0.0); vec3 s1 = vec3(0.0); vec3 s2 = vec3(0.0); vec3 s3 = vec3(0.0); + vec3 c; + vec3 cSq; + + c = texture2D(inputImageTexture, uv + vec2(-3,-3) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-3,-2) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-3,-1) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-3,0) * src_size).rgb; + cSq = c * c; + m0 += c; + s0 += cSq; + m1 += c; + s1 += cSq; + + c = texture2D(inputImageTexture, uv + vec2(-2,-3) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-2,-2) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-2,-1) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-2,0) * src_size).rgb; + cSq = c * c; + m0 += c; + s0 += cSq; + m1 += c; + s1 += cSq; + + c = texture2D(inputImageTexture, uv + vec2(-1,-3) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-1,-2) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-1,-1) * src_size).rgb; + m0 += c; + s0 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-1,0) * src_size).rgb; + cSq = c * c; + m0 += c; + s0 += cSq; + m1 += c; + s1 += cSq; + + c = texture2D(inputImageTexture, uv + vec2(0,-3) * src_size).rgb; + cSq = c * c; + m0 += c; + s0 += cSq; + m3 += c; + s3 += cSq; + c = texture2D(inputImageTexture, uv + vec2(0,-2) * src_size).rgb; + cSq = c * c; + m0 += c; + s0 += cSq; + m3 += c; + s3 += cSq; + c = texture2D(inputImageTexture, uv + vec2(0,-1) * src_size).rgb; + cSq = c * c; + m0 += c; + s0 += cSq; + m3 += c; + s3 += cSq; + c = texture2D(inputImageTexture, uv + vec2(0,0) * src_size).rgb; + cSq = c * c; + m0 += c; + s0 += cSq; + m1 += c; + s1 += cSq; + m2 += c; + s2 += cSq; + m3 += c; + s3 += cSq; + + c = texture2D(inputImageTexture, uv + vec2(-3,3) * src_size).rgb; + m1 += c; + s1 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-3,2) * src_size).rgb; + m1 += c; + s1 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-3,1) * src_size).rgb; + m1 += c; + s1 += c * c; + + c = texture2D(inputImageTexture, uv + vec2(-2,3) * src_size).rgb; + m1 += c; + s1 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-2,2) * src_size).rgb; + m1 += c; + s1 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-2,1) * src_size).rgb; + m1 += c; + s1 += c * c; + + c = texture2D(inputImageTexture, uv + vec2(-1,3) * src_size).rgb; + m1 += c; + s1 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-1,2) * src_size).rgb; + m1 += c; + s1 += c * c; + c = texture2D(inputImageTexture, uv + vec2(-1,1) * src_size).rgb; + m1 += c; + s1 += c * c; + + c = texture2D(inputImageTexture, uv + vec2(0,3) * src_size).rgb; + cSq = c * c; + m1 += c; + s1 += cSq; + m2 += c; + s2 += cSq; + c = texture2D(inputImageTexture, uv + vec2(0,2) * src_size).rgb; + cSq = c * c; + m1 += c; + s1 += cSq; + m2 += c; + s2 += cSq; + c = texture2D(inputImageTexture, uv + vec2(0,1) * src_size).rgb; + cSq = c * c; + m1 += c; + s1 += cSq; + m2 += c; + s2 += cSq; + + c = texture2D(inputImageTexture, uv + vec2(3,3) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(3,2) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(3,1) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(3,0) * src_size).rgb; + cSq = c * c; + m2 += c; + s2 += cSq; + m3 += c; + s3 += cSq; + + c = texture2D(inputImageTexture, uv + vec2(2,3) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(2,2) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(2,1) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(2,0) * src_size).rgb; + cSq = c * c; + m2 += c; + s2 += cSq; + m3 += c; + s3 += cSq; + + c = texture2D(inputImageTexture, uv + vec2(1,3) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(1,2) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(1,1) * src_size).rgb; + m2 += c; + s2 += c * c; + c = texture2D(inputImageTexture, uv + vec2(1,0) * src_size).rgb; + cSq = c * c; + m2 += c; + s2 += cSq; + m3 += c; + s3 += cSq; + + c = texture2D(inputImageTexture, uv + vec2(3,-3) * src_size).rgb; + m3 += c; + s3 += c * c; + c = texture2D(inputImageTexture, uv + vec2(3,-2) * src_size).rgb; + m3 += c; + s3 += c * c; + c = texture2D(inputImageTexture, uv + vec2(3,-1) * src_size).rgb; + m3 += c; + s3 += c * c; + + c = texture2D(inputImageTexture, uv + vec2(2,-3) * src_size).rgb; + m3 += c; + s3 += c * c; + c = texture2D(inputImageTexture, uv + vec2(2,-2) * src_size).rgb; + m3 += c; + s3 += c * c; + c = texture2D(inputImageTexture, uv + vec2(2,-1) * src_size).rgb; + m3 += c; + s3 += c * c; + + c = texture2D(inputImageTexture, uv + vec2(1,-3) * src_size).rgb; + m3 += c; + s3 += c * c; + c = texture2D(inputImageTexture, uv + vec2(1,-2) * src_size).rgb; + m3 += c; + s3 += c * c; + c = texture2D(inputImageTexture, uv + vec2(1,-1) * src_size).rgb; + m3 += c; + s3 += c * c; + + float min_sigma2 = 1e+2; + m0 /= n; + s0 = abs(s0 / n - m0 * m0); + + float sigma2 = s0.r + s0.g + s0.b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + gl_FragColor = vec4(m0, 1.0); + } + + m1 /= n; + s1 = abs(s1 / n - m1 * m1); + + sigma2 = s1.r + s1.g + s1.b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + gl_FragColor = vec4(m1, 1.0); + } + + m2 /= n; + s2 = abs(s2 / n - m2 * m2); + + sigma2 = s2.r + s2.g + s2.b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + gl_FragColor = vec4(m2, 1.0); + } + + m3 /= n; + s3 = abs(s3 / n - m3 * m3); + + sigma2 = s3.r + s3.g + s3.b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + gl_FragColor = vec4(m3, 1.0); + } +} +""" +public let KuwaharaFragmentShader = """ +// Sourced from Kyprianidis, J. E., Kang, H., and Doellner, J. "Anisotropic Kuwahara Filtering on the GPU," GPU Pro p.247 (2010). +// +// Original header: +// +// Anisotropic Kuwahara Filtering on the GPU +// by Jan Eric Kyprianidis + +varying highp vec2 textureCoordinate; +uniform sampler2D inputImageTexture; +uniform int radius; + +precision highp float; + +const vec2 src_size = vec2 (1.0 / 768.0, 1.0 / 1024.0); + +void main (void) +{ + vec2 uv = textureCoordinate; + float n = float((radius + 1) * (radius + 1)); + int i; int j; + vec3 m0 = vec3(0.0); vec3 m1 = vec3(0.0); vec3 m2 = vec3(0.0); vec3 m3 = vec3(0.0); + vec3 s0 = vec3(0.0); vec3 s1 = vec3(0.0); vec3 s2 = vec3(0.0); vec3 s3 = vec3(0.0); + vec3 c; + + for (j = -radius; j <= 0; ++j) { + for (i = -radius; i <= 0; ++i) { + c = texture2D(inputImageTexture, uv + vec2(i,j) * src_size).rgb; + m0 += c; + s0 += c * c; + } + } + + for (j = -radius; j <= 0; ++j) { + for (i = 0; i <= radius; ++i) { + c = texture2D(inputImageTexture, uv + vec2(i,j) * src_size).rgb; + m1 += c; + s1 += c * c; + } + } + + for (j = 0; j <= radius; ++j) { + for (i = 0; i <= radius; ++i) { + c = texture2D(inputImageTexture, uv + vec2(i,j) * src_size).rgb; + m2 += c; + s2 += c * c; + } + } + + for (j = 0; j <= radius; ++j) { + for (i = -radius; i <= 0; ++i) { + c = texture2D(inputImageTexture, uv + vec2(i,j) * src_size).rgb; + m3 += c; + s3 += c * c; + } + } + + + float min_sigma2 = 1e+2; + m0 /= n; + s0 = abs(s0 / n - m0 * m0); + + float sigma2 = s0.r + s0.g + s0.b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + gl_FragColor = vec4(m0, 1.0); + } + + m1 /= n; + s1 = abs(s1 / n - m1 * m1); + + sigma2 = s1.r + s1.g + s1.b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + gl_FragColor = vec4(m1, 1.0); + } + + m2 /= n; + s2 = abs(s2 / n - m2 * m2); + + sigma2 = s2.r + s2.g + s2.b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + gl_FragColor = vec4(m2, 1.0); + } + + m3 /= n; + s3 = abs(s3 / n - m3 * m3); + + sigma2 = s3.r + s3.g + s3.b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + gl_FragColor = vec4(m3, 1.0); + } +} +""" +public let LanczosResamplingVertexShader = """ +attribute vec4 position; +attribute vec2 inputTextureCoordinate; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepLeftTextureCoordinate; +varying vec2 twoStepsLeftTextureCoordinate; +varying vec2 threeStepsLeftTextureCoordinate; +varying vec2 fourStepsLeftTextureCoordinate; +varying vec2 oneStepRightTextureCoordinate; +varying vec2 twoStepsRightTextureCoordinate; +varying vec2 threeStepsRightTextureCoordinate; +varying vec2 fourStepsRightTextureCoordinate; + +void main() +{ + gl_Position = position; + + vec2 firstOffset = vec2(texelWidth, texelHeight); + vec2 secondOffset = vec2(2.0 * texelWidth, 2.0 * texelHeight); + vec2 thirdOffset = vec2(3.0 * texelWidth, 3.0 * texelHeight); + vec2 fourthOffset = vec2(4.0 * texelWidth, 4.0 * texelHeight); + + centerTextureCoordinate = inputTextureCoordinate; + oneStepLeftTextureCoordinate = inputTextureCoordinate - firstOffset; + twoStepsLeftTextureCoordinate = inputTextureCoordinate - secondOffset; + threeStepsLeftTextureCoordinate = inputTextureCoordinate - thirdOffset; + fourStepsLeftTextureCoordinate = inputTextureCoordinate - fourthOffset; + oneStepRightTextureCoordinate = inputTextureCoordinate + firstOffset; + twoStepsRightTextureCoordinate = inputTextureCoordinate + secondOffset; + threeStepsRightTextureCoordinate = inputTextureCoordinate + thirdOffset; + fourStepsRightTextureCoordinate = inputTextureCoordinate + fourthOffset; +} +""" +public let LanczosResamplingFragmentShader = """ +precision highp float; + +uniform sampler2D inputImageTexture; + +varying vec2 centerTextureCoordinate; +varying vec2 oneStepLeftTextureCoordinate; +varying vec2 twoStepsLeftTextureCoordinate; +varying vec2 threeStepsLeftTextureCoordinate; +varying vec2 fourStepsLeftTextureCoordinate; +varying vec2 oneStepRightTextureCoordinate; +varying vec2 twoStepsRightTextureCoordinate; +varying vec2 threeStepsRightTextureCoordinate; +varying vec2 fourStepsRightTextureCoordinate; + +// sinc(x) * sinc(x/a) = (a * sin(pi * x) * sin(pi * x / a)) / (pi^2 * x^2) +// Assuming a Lanczos constant of 2.0, and scaling values to max out at x = +/- 1.5 + +void main() +{ + lowp vec4 fragmentColor = texture2D(inputImageTexture, centerTextureCoordinate) * 0.38026; + + fragmentColor += texture2D(inputImageTexture, oneStepLeftTextureCoordinate) * 0.27667; + fragmentColor += texture2D(inputImageTexture, oneStepRightTextureCoordinate) * 0.27667; + + fragmentColor += texture2D(inputImageTexture, twoStepsLeftTextureCoordinate) * 0.08074; + fragmentColor += texture2D(inputImageTexture, twoStepsRightTextureCoordinate) * 0.08074; + + fragmentColor += texture2D(inputImageTexture, threeStepsLeftTextureCoordinate) * -0.02612; + fragmentColor += texture2D(inputImageTexture, threeStepsRightTextureCoordinate) * -0.02612; + + fragmentColor += texture2D(inputImageTexture, fourStepsLeftTextureCoordinate) * -0.02143; + fragmentColor += texture2D(inputImageTexture, fourStepsRightTextureCoordinate) * -0.02143; + + gl_FragColor = fragmentColor; +} +""" +public let LaplacianFragmentShader = """ +precision highp float; + +uniform sampler2D inputImageTexture; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +void main() +{ + mediump vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb; + mediump vec3 bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb; + mediump vec3 bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb; + mediump vec4 centerColor = texture2D(inputImageTexture, textureCoordinate); + mediump vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb; + mediump vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb; + mediump vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb; + mediump vec3 topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).rgb; + mediump vec3 topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb; + + mediump vec3 resultColor = topLeftColor * 0.5 + topColor * 1.0 + topRightColor * 0.5; + resultColor += leftColor * 1.0 + centerColor.rgb * (-6.0) + rightColor * 1.0; + resultColor += bottomLeftColor * 0.5 + bottomColor * 1.0 + bottomRightColor * 0.5; + + // Normalize the results to allow for negative gradients in the 0.0-1.0 colorspace + resultColor = resultColor + 0.5; + + gl_FragColor = vec4(resultColor, centerColor.a); +} +""" +public let LevelsFragmentShader = """ +/* + ** Gamma correction + ** Details: http://blog.mouaif.org/2009/01/22/photoshop-gamma-correction-shader/ + */ + +#define GammaCorrection(color, gamma) pow(color, 1.0 / gamma) + +/* + ** Levels control (input (+gamma), output) + ** Details: http://blog.mouaif.org/2009/01/28/levels-control-shader/ + */ + +#define LevelsControlInputRange(color, minInput, maxInput) min(max(color - minInput, vec3(0.0)) / (maxInput - minInput), vec3(1.0)) +#define LevelsControlInput(color, minInput, gamma, maxInput) GammaCorrection(LevelsControlInputRange(color, minInput, maxInput), gamma) +#define LevelsControlOutputRange(color, minOutput, maxOutput) mix(minOutput, maxOutput, color) +#define LevelsControl(color, minInput, gamma, maxInput, minOutput, maxOutput) LevelsControlOutputRange(LevelsControlInput(color, minInput, gamma, maxInput), minOutput, maxOutput) + +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform mediump vec3 levelMinimum; +uniform mediump vec3 levelMiddle; +uniform mediump vec3 levelMaximum; +uniform mediump vec3 minOutput; +uniform mediump vec3 maxOutput; + +void main() +{ + mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = vec4(LevelsControl(textureColor.rgb, levelMinimum, levelMiddle, levelMaximum, minOutput, maxOutput), textureColor.a); +} + +""" +public let LightenBlendFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = max(textureColor, textureColor2); +} +""" +public let LineVertexShader = """ +attribute vec4 position; + +void main() +{ + gl_Position = position; +} +""" +public let LineFragmentShader = """ +uniform lowp vec3 lineColor; + +void main() +{ + gl_FragColor = vec4(lineColor, 1.0); +} +""" +public let LinearBurnBlendFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = vec4(clamp(textureColor.rgb + textureColor2.rgb - vec3(1.0), vec3(0.0), vec3(1.0)), textureColor.a); +} +""" +public let LocalBinaryPatternFragmentShader = """ +precision highp float; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + lowp float centerIntensity = texture2D(inputImageTexture, textureCoordinate).r; + lowp float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + lowp float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + lowp float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + lowp float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + lowp float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + lowp float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + lowp float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + lowp float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + + lowp float byteTally = 1.0 / 255.0 * step(centerIntensity, topRightIntensity); + byteTally += 2.0 / 255.0 * step(centerIntensity, topIntensity); + byteTally += 4.0 / 255.0 * step(centerIntensity, topLeftIntensity); + byteTally += 8.0 / 255.0 * step(centerIntensity, leftIntensity); + byteTally += 16.0 / 255.0 * step(centerIntensity, bottomLeftIntensity); + byteTally += 32.0 / 255.0 * step(centerIntensity, bottomIntensity); + byteTally += 64.0 / 255.0 * step(centerIntensity, bottomRightIntensity); + byteTally += 128.0 / 255.0 * step(centerIntensity, rightIntensity); + + // TODO: Replace the above with a dot product and two vec4s + // TODO: Apply step to a matrix, rather than individually + + gl_FragColor = vec4(byteTally, byteTally, byteTally, 1.0); +} +""" +public let LookupFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; // lookup texture + +uniform lowp float intensity; + +void main() +{ + highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + highp float blueColor = textureColor.b * 63.0; + + highp vec2 quad1; + quad1.y = floor(floor(blueColor) / 8.0); + quad1.x = floor(blueColor) - (quad1.y * 8.0); + + highp vec2 quad2; + quad2.y = floor(ceil(blueColor) / 8.0); + quad2.x = ceil(blueColor) - (quad2.y * 8.0); + + highp vec2 texPos1; + texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r); + texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g); + + highp vec2 texPos2; + texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r); + texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g); + + lowp vec4 newColor1 = texture2D(inputImageTexture2, texPos1); + lowp vec4 newColor2 = texture2D(inputImageTexture2, texPos2); + + lowp vec4 newColor = mix(newColor1, newColor2, fract(blueColor)); + gl_FragColor = mix(textureColor, vec4(newColor.rgb, textureColor.w), intensity); +} + +""" +public let LuminanceRangeFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform lowp float rangeReduction; + +// Values from "Graphics Shaders: Theory and Practice" by Bailey and Cunningham +const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + mediump float luminance = dot(textureColor.rgb, luminanceWeighting); + mediump float luminanceRatio = ((0.5 - luminance) * rangeReduction); + + gl_FragColor = vec4((textureColor.rgb) + (luminanceRatio), textureColor.w); +} +""" +public let LuminanceThresholdFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform highp float threshold; + +const highp vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + highp float luminance = dot(textureColor.rgb, W); + highp float thresholdResult = step(threshold, luminance); + + gl_FragColor = vec4(vec3(thresholdResult), textureColor.w); +} +""" +public let LuminanceFragmentShader = """ +precision highp float; + +varying vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +// Values from "Graphics Shaders: Theory and Practice" by Bailey and Cunningham +const highp vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + float luminance = dot(textureColor.rgb, W); + + gl_FragColor = vec4(vec3(luminance), textureColor.a); +} + +""" +public let LuminosityBlendFragmentShader = """ +// Luminosity blend mode based upon pseudo code from the PDF specification. + +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +highp float lum(lowp vec3 c) { + return dot(c, vec3(0.3, 0.59, 0.11)); +} + +lowp vec3 clipcolor(lowp vec3 c) { + highp float l = lum(c); + lowp float n = min(min(c.r, c.g), c.b); + lowp float x = max(max(c.r, c.g), c.b); + + if (n < 0.0) { + c.r = l + ((c.r - l) * l) / (l - n); + c.g = l + ((c.g - l) * l) / (l - n); + c.b = l + ((c.b - l) * l) / (l - n); + } + if (x > 1.0) { + c.r = l + ((c.r - l) * (1.0 - l)) / (x - l); + c.g = l + ((c.g - l) * (1.0 - l)) / (x - l); + c.b = l + ((c.b - l) * (1.0 - l)) / (x - l); + } + + return c; +} + +lowp vec3 setlum(lowp vec3 c, highp float l) { + highp float d = l - lum(c); + c = c + vec3(d); + return clipcolor(c); +} + +void main() +{ + highp vec4 baseColor = texture2D(inputImageTexture, textureCoordinate); + highp vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(baseColor.rgb, lum(overlayColor.rgb)) * overlayColor.a, baseColor.a); +} + +""" +public let MedianFragmentShader = """ +/* + 3x3 median filter, adapted from "A Fast, Small-Radius GPU Median Filter" by Morgan McGuire in ShaderX6 + http://graphics.cs.williams.edu/papers/MedianShaderX6/ + + Morgan McGuire and Kyle Whitson + Williams College + + Register allocation tips by Victor Huang Xiaohuang + University of Illinois at Urbana-Champaign + + http://graphics.cs.williams.edu + + + Copyright (c) Morgan McGuire and Williams College, 2006 + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + precision highp float; + + varying vec2 textureCoordinate; + varying vec2 leftTextureCoordinate; + varying vec2 rightTextureCoordinate; + + varying vec2 topTextureCoordinate; + varying vec2 topLeftTextureCoordinate; + varying vec2 topRightTextureCoordinate; + + varying vec2 bottomTextureCoordinate; + varying vec2 bottomLeftTextureCoordinate; + varying vec2 bottomRightTextureCoordinate; + + uniform sampler2D inputImageTexture; + +#define s2(a, b) temp = a; a = min(a, b); b = max(temp, b); +#define mn3(a, b, c) s2(a, b); s2(a, c); +#define mx3(a, b, c) s2(b, c); s2(a, c); + +#define mnmx3(a, b, c) mx3(a, b, c); s2(a, b); // 3 exchanges +#define mnmx4(a, b, c, d) s2(a, b); s2(c, d); s2(a, c); s2(b, d); // 4 exchanges +#define mnmx5(a, b, c, d, e) s2(a, b); s2(c, d); mn3(a, c, e); mx3(b, d, e); // 6 exchanges +#define mnmx6(a, b, c, d, e, f) s2(a, d); s2(b, e); s2(c, f); mn3(a, b, c); mx3(d, e, f); // 7 exchanges + + void main() + { + vec3 v[6]; + + v[0] = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb; + v[1] = texture2D(inputImageTexture, topRightTextureCoordinate).rgb; + v[2] = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb; + v[3] = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb; + v[4] = texture2D(inputImageTexture, leftTextureCoordinate).rgb; + v[5] = texture2D(inputImageTexture, rightTextureCoordinate).rgb; +// v[6] = texture2D(inputImageTexture, bottomTextureCoordinate).rgb; +// v[7] = texture2D(inputImageTexture, topTextureCoordinate).rgb; + vec3 temp; + + mnmx6(v[0], v[1], v[2], v[3], v[4], v[5]); + + v[5] = texture2D(inputImageTexture, bottomTextureCoordinate).rgb; + + mnmx5(v[1], v[2], v[3], v[4], v[5]); + + v[5] = texture2D(inputImageTexture, topTextureCoordinate).rgb; + + mnmx4(v[2], v[3], v[4], v[5]); + + v[5] = texture2D(inputImageTexture, textureCoordinate).rgb; + + mnmx3(v[3], v[4], v[5]); + + gl_FragColor = vec4(v[4], 1.0); + } +""" +public let MonochromeFragmentShader = """ +precision lowp float; + +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float intensity; +uniform vec3 filterColor; + +const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + //desat, then apply overlay blend + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + float luminance = dot(textureColor.rgb, luminanceWeighting); + + lowp vec4 desat = vec4(vec3(luminance), 1.0); + + //overlay + lowp vec4 outputColor = vec4( + (desat.r < 0.5 ? (2.0 * desat.r * filterColor.r) : (1.0 - 2.0 * (1.0 - desat.r) * (1.0 - filterColor.r))), + (desat.g < 0.5 ? (2.0 * desat.g * filterColor.g) : (1.0 - 2.0 * (1.0 - desat.g) * (1.0 - filterColor.g))), + (desat.b < 0.5 ? (2.0 * desat.b * filterColor.b) : (1.0 - 2.0 * (1.0 - desat.b) * (1.0 - filterColor.b))), + 1.0 + ); + + //which is better, or are they equal? + gl_FragColor = vec4( mix(textureColor.rgb, outputColor.rgb, intensity), textureColor.a); +} +""" +public let MotionBlurVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; + +uniform vec2 directionalTexelStep; + +varying vec2 textureCoordinate; +varying vec2 oneStepBackTextureCoordinate; +varying vec2 twoStepsBackTextureCoordinate; +varying vec2 threeStepsBackTextureCoordinate; +varying vec2 fourStepsBackTextureCoordinate; +varying vec2 oneStepForwardTextureCoordinate; +varying vec2 twoStepsForwardTextureCoordinate; +varying vec2 threeStepsForwardTextureCoordinate; +varying vec2 fourStepsForwardTextureCoordinate; + +void main() +{ + gl_Position = position; + + textureCoordinate = inputTextureCoordinate.xy; + oneStepBackTextureCoordinate = inputTextureCoordinate.xy - directionalTexelStep; + twoStepsBackTextureCoordinate = inputTextureCoordinate.xy - 2.0 * directionalTexelStep; + threeStepsBackTextureCoordinate = inputTextureCoordinate.xy - 3.0 * directionalTexelStep; + fourStepsBackTextureCoordinate = inputTextureCoordinate.xy - 4.0 * directionalTexelStep; + oneStepForwardTextureCoordinate = inputTextureCoordinate.xy + directionalTexelStep; + twoStepsForwardTextureCoordinate = inputTextureCoordinate.xy + 2.0 * directionalTexelStep; + threeStepsForwardTextureCoordinate = inputTextureCoordinate.xy + 3.0 * directionalTexelStep; + fourStepsForwardTextureCoordinate = inputTextureCoordinate.xy + 4.0 * directionalTexelStep; +} +""" +public let MotionBlurFragmentShader = """ +precision highp float; + +uniform sampler2D inputImageTexture; + +varying vec2 textureCoordinate; +varying vec2 oneStepBackTextureCoordinate; +varying vec2 twoStepsBackTextureCoordinate; +varying vec2 threeStepsBackTextureCoordinate; +varying vec2 fourStepsBackTextureCoordinate; +varying vec2 oneStepForwardTextureCoordinate; +varying vec2 twoStepsForwardTextureCoordinate; +varying vec2 threeStepsForwardTextureCoordinate; +varying vec2 fourStepsForwardTextureCoordinate; + +void main() +{ + lowp vec4 fragmentColor = texture2D(inputImageTexture, textureCoordinate) * 0.18; + fragmentColor += texture2D(inputImageTexture, oneStepBackTextureCoordinate) * 0.15; + fragmentColor += texture2D(inputImageTexture, twoStepsBackTextureCoordinate) * 0.12; + fragmentColor += texture2D(inputImageTexture, threeStepsBackTextureCoordinate) * 0.09; + fragmentColor += texture2D(inputImageTexture, fourStepsBackTextureCoordinate) * 0.05; + fragmentColor += texture2D(inputImageTexture, oneStepForwardTextureCoordinate) * 0.15; + fragmentColor += texture2D(inputImageTexture, twoStepsForwardTextureCoordinate) * 0.12; + fragmentColor += texture2D(inputImageTexture, threeStepsForwardTextureCoordinate) * 0.09; + fragmentColor += texture2D(inputImageTexture, fourStepsForwardTextureCoordinate) * 0.05; + + gl_FragColor = fragmentColor; +} +""" +public let MotionComparisonFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +uniform highp float intensity; + +void main() +{ + lowp vec3 currentImageColor = texture2D(inputImageTexture, textureCoordinate).rgb; + lowp vec3 lowPassImageColor = texture2D(inputImageTexture2, textureCoordinate2).rgb; + + mediump float colorDistance = distance(currentImageColor, lowPassImageColor); // * 0.57735 + lowp float movementThreshold = step(0.2, colorDistance); + + gl_FragColor = movementThreshold * vec4(textureCoordinate2.x, textureCoordinate2.y, 1.0, 1.0); +} +""" +public let MultiplyBlendFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + lowp vec4 base = texture2D(inputImageTexture, textureCoordinate); + lowp vec4 overlayer = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = overlayer * base + overlayer * (1.0 - base.a) + base * (1.0 - overlayer.a); +} +""" +public let NearbyTexelSamplingVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; + +uniform float texelWidth; +uniform float texelHeight; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +void main() +{ + gl_Position = position; + + vec2 widthStep = vec2(texelWidth, 0.0); + vec2 heightStep = vec2(0.0, texelHeight); + vec2 widthHeightStep = vec2(texelWidth, texelHeight); + vec2 widthNegativeHeightStep = vec2(texelWidth, -texelHeight); + + textureCoordinate = inputTextureCoordinate.xy; + leftTextureCoordinate = inputTextureCoordinate.xy - widthStep; + rightTextureCoordinate = inputTextureCoordinate.xy + widthStep; + + topTextureCoordinate = inputTextureCoordinate.xy - heightStep; + topLeftTextureCoordinate = inputTextureCoordinate.xy - widthHeightStep; + topRightTextureCoordinate = inputTextureCoordinate.xy + widthNegativeHeightStep; + + bottomTextureCoordinate = inputTextureCoordinate.xy + heightStep; + bottomLeftTextureCoordinate = inputTextureCoordinate.xy - widthNegativeHeightStep; + bottomRightTextureCoordinate = inputTextureCoordinate.xy + widthHeightStep; +} +""" +public let NobleCornerDetectorFragmentShader = """ + varying highp vec2 textureCoordinate; + + uniform sampler2D inputImageTexture; + uniform lowp float sensitivity; + + void main() + { + mediump vec3 derivativeElements = texture2D(inputImageTexture, textureCoordinate).rgb; + + mediump float derivativeSum = derivativeElements.x + derivativeElements.y; + + // R = (Ix^2 * Iy^2 - Ixy * Ixy) / (Ix^2 + Iy^2) + mediump float zElement = (derivativeElements.z * 2.0) - 1.0; + // mediump float harrisIntensity = (derivativeElements.x * derivativeElements.y - (derivativeElements.z * derivativeElements.z)) / (derivativeSum); + mediump float cornerness = (derivativeElements.x * derivativeElements.y - (zElement * zElement)) / (derivativeSum); + + // Original Harris detector + // R = Ix^2 * Iy^2 - Ixy * Ixy - k * (Ix^2 + Iy^2)^2 + // highp float harrisIntensity = derivativeElements.x * derivativeElements.y - (derivativeElements.z * derivativeElements.z) - harrisConstant * derivativeSum * derivativeSum; + + // gl_FragColor = vec4(vec3(harrisIntensity * 7.0), 1.0); + gl_FragColor = vec4(vec3(cornerness * sensitivity), 1.0); + } + +""" +public let NormalBlendFragmentShader = """ +/* + This equation is a simplification of the general blending equation. It assumes the destination color is opaque, and therefore drops the destination color's alpha term. + + D = C1 * C1a + C2 * C2a * (1 - C1a) + where D is the resultant color, C1 is the color of the first element, C1a is the alpha of the first element, C2 is the second element color, C2a is the alpha of the second element. The destination alpha is calculated with: + + Da = C1a + C2a * (1 - C1a) + The resultant color is premultiplied with the alpha. To restore the color to the unmultiplied values, just divide by Da, the resultant alpha. + + http://stackoverflow.com/questions/1724946/blend-mode-on-a-transparent-and-semi-transparent-background + + For some reason Photoshop behaves + D = C1 + C2 * C2a * (1 - C1a) + */ + +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + lowp vec4 c2 = texture2D(inputImageTexture, textureCoordinate); + lowp vec4 c1 = texture2D(inputImageTexture2, textureCoordinate2); + + lowp vec4 outputColor; + +// outputColor.r = c1.r + c2.r * c2.a * (1.0 - c1.a); +// outputColor.g = c1.g + c2.g * c2.a * (1.0 - c1.a); +// outputColor.b = c1.b + c2.b * c2.a * (1.0 - c1.a); +// outputColor.a = c1.a + c2.a * (1.0 - c1.a); + + lowp float a = c1.a + c2.a * (1.0 - c1.a); + lowp float alphaDivisor = a + step(a, 0.0); // Protect against a divide-by-zero blacking out things in the output + + outputColor.r = (c1.r * c1.a + c2.r * c2.a * (1.0 - c1.a))/alphaDivisor; + outputColor.g = (c1.g * c1.a + c2.g * c2.a * (1.0 - c1.a))/alphaDivisor; + outputColor.b = (c1.b * c1.a + c2.b * c2.a * (1.0 - c1.a))/alphaDivisor; + outputColor.a = a; + + gl_FragColor = outputColor; +} +""" +public let OneInputVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; + +varying vec2 textureCoordinate; + +void main() +{ + gl_Position = position; + textureCoordinate = inputTextureCoordinate.xy; +} + +""" +public let OpacityFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform lowp float opacity; + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = vec4(textureColor.rgb, textureColor.a * opacity); +} +""" +public let OverlayBlendFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + mediump vec4 base = texture2D(inputImageTexture, textureCoordinate); + mediump vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2); + + mediump float ra; + if (2.0 * base.r < base.a) { + ra = 2.0 * overlay.r * base.r + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a); + } else { + ra = overlay.a * base.a - 2.0 * (base.a - base.r) * (overlay.a - overlay.r) + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a); + } + + mediump float ga; + if (2.0 * base.g < base.a) { + ga = 2.0 * overlay.g * base.g + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a); + } else { + ga = overlay.a * base.a - 2.0 * (base.a - base.g) * (overlay.a - overlay.g) + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a); + } + + mediump float ba; + if (2.0 * base.b < base.a) { + ba = 2.0 * overlay.b * base.b + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a); + } else { + ba = overlay.a * base.a - 2.0 * (base.a - base.b) * (overlay.a - overlay.b) + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a); + } + + gl_FragColor = vec4(ra, ga, ba, 1.0); +} +""" +public let PassthroughFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + gl_FragColor = texture2D(inputImageTexture, textureCoordinate); +} +""" +public let PinchDistortionFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform highp float aspectRatio; +uniform highp vec2 center; +uniform highp float radius; +uniform highp float scale; + +void main() +{ + highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); + highp float dist = distance(center, textureCoordinateToUse); + textureCoordinateToUse = textureCoordinate; + + if (dist < radius) + { + textureCoordinateToUse -= center; + highp float percent = 1.0 + ((0.5 - dist) / 0.5) * scale; + textureCoordinateToUse = textureCoordinateToUse * percent; + textureCoordinateToUse += center; + + gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse ); + } + else + { + gl_FragColor = texture2D(inputImageTexture, textureCoordinate ); + } +} +""" +public let PixellateFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform highp float fractionalWidthOfPixel; +uniform highp float aspectRatio; + +void main() +{ + highp vec2 sampleDivisor = vec2(fractionalWidthOfPixel, fractionalWidthOfPixel / aspectRatio); + + highp vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor) + 0.5 * sampleDivisor; + gl_FragColor = texture2D(inputImageTexture, samplePos ); +} + +""" +public let PolarPixellateFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform highp vec2 center; +uniform highp vec2 pixelSize; + + +void main() +{ + highp vec2 normCoord = 2.0 * textureCoordinate - 1.0; + highp vec2 normCenter = 2.0 * center - 1.0; + + normCoord -= normCenter; + + highp float r = length(normCoord); // to polar coords + highp float phi = atan(normCoord.y, normCoord.x); // to polar coords + + r = r - mod(r, pixelSize.x) + 0.03; + phi = phi - mod(phi, pixelSize.y); + + normCoord.x = r * cos(phi); + normCoord.y = r * sin(phi); + + normCoord += normCenter; + + mediump vec2 textureCoordinateToUse = normCoord / 2.0 + 0.5; + + gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse ); + +} +""" +public let PolkaDotFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform highp float fractionalWidthOfPixel; +uniform highp float aspectRatio; +uniform highp float dotScaling; + +void main() +{ + highp vec2 sampleDivisor = vec2(fractionalWidthOfPixel, fractionalWidthOfPixel / aspectRatio); + + highp vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor) + 0.5 * sampleDivisor; + highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); + highp vec2 adjustedSamplePos = vec2(samplePos.x, (samplePos.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); + highp float distanceFromSamplePoint = distance(adjustedSamplePos, textureCoordinateToUse); + lowp float checkForPresenceWithinDot = step(distanceFromSamplePoint, (fractionalWidthOfPixel * 0.5) * dotScaling); + + lowp vec4 inputColor = texture2D(inputImageTexture, samplePos); + + gl_FragColor = vec4(inputColor.rgb * checkForPresenceWithinDot, inputColor.a); +} +""" +public let PosterizeFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform highp float colorLevels; + +void main() +{ + highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = floor((textureColor * colorLevels) + vec4(0.5)) / colorLevels; +} +""" +public let PrewittEdgeDetectionFragmentShader = """ +precision highp float; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float edgeStrength; + +void main() +{ + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + float h = -topLeftIntensity - topIntensity - topRightIntensity + bottomLeftIntensity + bottomIntensity + bottomRightIntensity; + float v = -bottomLeftIntensity - leftIntensity - topLeftIntensity + bottomRightIntensity + rightIntensity + topRightIntensity; + + float mag = length(vec2(h, v)) * edgeStrength; + + gl_FragColor = vec4(vec3(mag), 1.0); +} +""" +public let RGBAdjustmentFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform highp float redAdjustment; +uniform highp float greenAdjustment; +uniform highp float blueAdjustment; + +void main() +{ + highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = vec4(textureColor.r * redAdjustment, textureColor.g * greenAdjustment, textureColor.b * blueAdjustment, textureColor.a); +} + +""" +public let SaturationBlendFragmentShader = """ +// Saturation blend mode based upon pseudo code from the PDF specification. + +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +highp float lum(lowp vec3 c) { + return dot(c, vec3(0.3, 0.59, 0.11)); +} + +lowp vec3 clipcolor(lowp vec3 c) { + highp float l = lum(c); + lowp float n = min(min(c.r, c.g), c.b); + lowp float x = max(max(c.r, c.g), c.b); + + if (n < 0.0) { + c.r = l + ((c.r - l) * l) / (l - n); + c.g = l + ((c.g - l) * l) / (l - n); + c.b = l + ((c.b - l) * l) / (l - n); + } + if (x > 1.0) { + c.r = l + ((c.r - l) * (1.0 - l)) / (x - l); + c.g = l + ((c.g - l) * (1.0 - l)) / (x - l); + c.b = l + ((c.b - l) * (1.0 - l)) / (x - l); + } + + return c; +} + +lowp vec3 setlum(lowp vec3 c, highp float l) { + highp float d = l - lum(c); + c = c + vec3(d); + return clipcolor(c); +} + +highp float sat(lowp vec3 c) { + lowp float n = min(min(c.r, c.g), c.b); + lowp float x = max(max(c.r, c.g), c.b); + return x - n; +} + +lowp float mid(lowp float cmin, lowp float cmid, lowp float cmax, highp float s) { + return ((cmid - cmin) * s) / (cmax - cmin); +} + +lowp vec3 setsat(lowp vec3 c, highp float s) { + if (c.r > c.g) { + if (c.r > c.b) { + if (c.g > c.b) { + /* g is mid, b is min */ + c.g = mid(c.b, c.g, c.r, s); + c.b = 0.0; + } else { + /* b is mid, g is min */ + c.b = mid(c.g, c.b, c.r, s); + c.g = 0.0; + } + c.r = s; + } else { + /* b is max, r is mid, g is min */ + c.r = mid(c.g, c.r, c.b, s); + c.b = s; + c.r = 0.0; + } + } else if (c.r > c.b) { + /* g is max, r is mid, b is min */ + c.r = mid(c.b, c.r, c.g, s); + c.g = s; + c.b = 0.0; + } else if (c.g > c.b) { + /* g is max, b is mid, r is min */ + c.b = mid(c.r, c.b, c.g, s); + c.g = s; + c.r = 0.0; + } else if (c.b > c.g) { + /* b is max, g is mid, r is min */ + c.g = mid(c.r, c.g, c.b, s); + c.b = s; + c.r = 0.0; + } else { + c = vec3(0.0); + } + return c; +} + +void main() +{ + highp vec4 baseColor = texture2D(inputImageTexture, textureCoordinate); + highp vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(setsat(baseColor.rgb, sat(overlayColor.rgb)), lum(baseColor.rgb)) * overlayColor.a, baseColor.a); +} +""" +public let SaturationFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform lowp float saturation; + +// Values from "Graphics Shaders: Theory and Practice" by Bailey and Cunningham +const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + lowp float luminance = dot(textureColor.rgb, luminanceWeighting); + lowp vec3 greyScaleColor = vec3(luminance); + gl_FragColor = vec4(mix(greyScaleColor, textureColor.rgb, saturation), textureColor.w); +} +""" +public let ScreenBlendFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + mediump vec4 whiteColor = vec4(1.0); + gl_FragColor = whiteColor - ((whiteColor - textureColor2) * (whiteColor - textureColor)); +} +""" +public let SharpenVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; + +uniform float texelWidth; +uniform float texelHeight; +uniform float sharpness; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; +varying vec2 topTextureCoordinate; +varying vec2 bottomTextureCoordinate; + +varying float centerMultiplier; +varying float edgeMultiplier; + +void main() +{ + gl_Position = position; + + vec2 widthStep = vec2(texelWidth, 0.0); + vec2 heightStep = vec2(0.0, texelHeight); + + textureCoordinate = inputTextureCoordinate.xy; + leftTextureCoordinate = inputTextureCoordinate.xy - widthStep; + rightTextureCoordinate = inputTextureCoordinate.xy + widthStep; + topTextureCoordinate = inputTextureCoordinate.xy + heightStep; + bottomTextureCoordinate = inputTextureCoordinate.xy - heightStep; + + centerMultiplier = 1.0 + 4.0 * sharpness; + edgeMultiplier = sharpness; +} +""" +public let SharpenFragmentShader = """ +precision highp float; + +varying highp vec2 textureCoordinate; +varying highp vec2 leftTextureCoordinate; +varying highp vec2 rightTextureCoordinate; +varying highp vec2 topTextureCoordinate; +varying highp vec2 bottomTextureCoordinate; + +varying highp float centerMultiplier; +varying highp float edgeMultiplier; + +uniform sampler2D inputImageTexture; + +void main() +{ + mediump vec3 textureColor = texture2D(inputImageTexture, textureCoordinate).rgb; + mediump vec3 leftTextureColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb; + mediump vec3 rightTextureColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb; + mediump vec3 topTextureColor = texture2D(inputImageTexture, topTextureCoordinate).rgb; + mediump vec3 bottomTextureColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb; + + gl_FragColor = vec4((textureColor * centerMultiplier - (leftTextureColor * edgeMultiplier + rightTextureColor * edgeMultiplier + topTextureColor * edgeMultiplier + bottomTextureColor * edgeMultiplier)), texture2D(inputImageTexture, bottomTextureCoordinate).w); +} +""" +public let ShiTomasiFeatureDetectorFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform lowp float sensitivity; + +void main() +{ + mediump vec3 derivativeElements = texture2D(inputImageTexture, textureCoordinate).rgb; + + mediump float derivativeDifference = derivativeElements.x - derivativeElements.y; + mediump float zElement = (derivativeElements.z * 2.0) - 1.0; + + // R = Ix^2 + Iy^2 - sqrt( (Ix^2 - Iy^2)^2 + 4 * Ixy * Ixy) + mediump float cornerness = derivativeElements.x + derivativeElements.y - sqrt(derivativeDifference * derivativeDifference + 4.0 * zElement * zElement); + + gl_FragColor = vec4(vec3(cornerness * sensitivity), 1.0); +} +""" +public let SketchFragmentShader = """ +precision mediump float; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform float edgeStrength; + +uniform sampler2D inputImageTexture; + +void main() +{ + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity; + float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity; + + float mag = 1.0 - (length(vec2(h, v)) * edgeStrength); + + gl_FragColor = vec4(vec3(mag), 1.0); +} +""" +public let SobelEdgeDetectionFragmentShader = """ +// Code from "Graphics Shaders: Theory and Practice" by M. Bailey and S. Cunningham + +precision mediump float; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float edgeStrength; + +void main() +{ + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity; + float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity; + + float mag = length(vec2(h, v)) * edgeStrength; + + gl_FragColor = vec4(vec3(mag), 1.0); +} +""" +public let SoftLightBlendFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + mediump vec4 base = texture2D(inputImageTexture, textureCoordinate); + mediump vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2); + + lowp float alphaDivisor = base.a + step(base.a, 0.0); // Protect against a divide-by-zero blacking out things in the output + gl_FragColor = base * (overlay.a * (base / alphaDivisor) + (2.0 * overlay * (1.0 - (base / alphaDivisor)))) + overlay * (1.0 - base.a) + base * (1.0 - overlay.a); +} +""" +public let SolarizeFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform highp float threshold; + +const highp vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + highp float luminance = dot(textureColor.rgb, W); + highp float thresholdResult = step(luminance, threshold); + highp vec3 finalColor = abs(thresholdResult - textureColor.rgb); + + gl_FragColor = vec4(finalColor, textureColor.w); +} +""" +public let SourceOverBlendFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate); + + gl_FragColor = mix(textureColor, textureColor2, textureColor2.a); +} +""" +public let SphereRefractionFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform highp vec2 center; +uniform highp float radius; +uniform highp float aspectRatio; +uniform highp float refractiveIndex; + +void main() +{ + highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); + highp float distanceFromCenter = distance(center, textureCoordinateToUse); + lowp float checkForPresenceWithinSphere = step(distanceFromCenter, radius); + + distanceFromCenter = distanceFromCenter / radius; + + highp float normalizedDepth = radius * sqrt(1.0 - distanceFromCenter * distanceFromCenter); + highp vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - center, normalizedDepth)); + + highp vec3 refractedVector = refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex); + + gl_FragColor = texture2D(inputImageTexture, (refractedVector.xy + 1.0) * 0.5) * checkForPresenceWithinSphere; +} +""" +public let StretchDistortionFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform highp vec2 center; + +void main() +{ + highp vec2 normCoord = 2.0 * textureCoordinate - 1.0; + highp vec2 normCenter = 2.0 * center - 1.0; + + normCoord -= normCenter; + mediump vec2 s = sign(normCoord); + normCoord = abs(normCoord); + normCoord = 0.5 * normCoord + 0.5 * smoothstep(0.25, 0.5, normCoord) * normCoord; + normCoord = s * normCoord; + + normCoord += normCenter; + + mediump vec2 textureCoordinateToUse = normCoord / 2.0 + 0.5; + + + gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse ); + +} +""" +public let SubtractBlendFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); + + gl_FragColor = vec4(textureColor.rgb - textureColor2.rgb, textureColor.a); +} +""" +public let SwirlFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform highp vec2 center; +uniform highp float radius; +uniform highp float angle; + +void main() +{ + highp vec2 textureCoordinateToUse = textureCoordinate; + highp float dist = distance(center, textureCoordinate); + if (dist < radius) + { + textureCoordinateToUse -= center; + highp float percent = (radius - dist) / radius; + highp float theta = percent * percent * angle * 8.0; + highp float s = sin(theta); + highp float c = cos(theta); + textureCoordinateToUse = vec2(dot(textureCoordinateToUse, vec2(c, -s)), dot(textureCoordinateToUse, vec2(s, c))); + textureCoordinateToUse += center; + } + + gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse ); + +} +""" +public let ThreeInputVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; +attribute vec4 inputTextureCoordinate2; +attribute vec4 inputTextureCoordinate3; + +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; +varying vec2 textureCoordinate3; + +void main() +{ + gl_Position = position; + textureCoordinate = inputTextureCoordinate.xy; + textureCoordinate2 = inputTextureCoordinate2.xy; + textureCoordinate3 = inputTextureCoordinate3.xy; +} +""" +public let ThresholdEdgeDetectionFragmentShader = """ +precision highp float; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float threshold; + +uniform float edgeStrength; + +void main() +{ + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity; + h = max(0.0, h); + float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity; + v = max(0.0, v); + + float mag = length(vec2(h, v)) * edgeStrength; + mag = step(threshold, mag); + + gl_FragColor = vec4(vec3(mag), 1.0); +} + +""" +public let ThresholdSketchFragmentShader = """ +precision highp float; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; +uniform float threshold; + +uniform float edgeStrength; + +void main() +{ + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity; + float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity; + + float mag = length(vec2(h, v)) * edgeStrength; + mag = 1.0 - step(threshold, mag); + + gl_FragColor = vec4(vec3(mag), 1.0); +} + +""" +public let ThresholdedNonMaximumSuppressionFragmentShader = """ + uniform sampler2D inputImageTexture; + + varying highp vec2 textureCoordinate; + varying highp vec2 leftTextureCoordinate; + varying highp vec2 rightTextureCoordinate; + + varying highp vec2 topTextureCoordinate; + varying highp vec2 topLeftTextureCoordinate; + varying highp vec2 topRightTextureCoordinate; + + varying highp vec2 bottomTextureCoordinate; + varying highp vec2 bottomLeftTextureCoordinate; + varying highp vec2 bottomRightTextureCoordinate; + + uniform lowp float threshold; + + void main() + { + lowp float bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).r; + lowp float bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + lowp float bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + lowp vec4 centerColor = texture2D(inputImageTexture, textureCoordinate); + lowp float leftColor = texture2D(inputImageTexture, leftTextureCoordinate).r; + lowp float rightColor = texture2D(inputImageTexture, rightTextureCoordinate).r; + lowp float topColor = texture2D(inputImageTexture, topTextureCoordinate).r; + lowp float topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).r; + lowp float topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + + // Use a tiebreaker for pixels to the left and immediately above this one + lowp float multiplier = 1.0 - step(centerColor.r, topColor); + multiplier = multiplier * (1.0 - step(centerColor.r, topLeftColor)); + multiplier = multiplier * (1.0 - step(centerColor.r, leftColor)); + multiplier = multiplier * (1.0 - step(centerColor.r, bottomLeftColor)); + + lowp float maxValue = max(centerColor.r, bottomColor); + maxValue = max(maxValue, bottomRightColor); + maxValue = max(maxValue, rightColor); + maxValue = max(maxValue, topRightColor); + + lowp float finalValue = centerColor.r * step(maxValue, centerColor.r) * multiplier; + finalValue = step(threshold, finalValue); + + gl_FragColor = vec4(finalValue, finalValue, finalValue, 1.0); +// +// gl_FragColor = vec4((centerColor.rgb * step(maxValue, step(threshold, centerColor.r)) * multiplier), 1.0); + } +""" +public let TiltShiftFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +uniform highp float topFocusLevel; +uniform highp float bottomFocusLevel; +uniform highp float focusFallOffRate; + +void main() +{ + lowp vec4 sharpImageColor = texture2D(inputImageTexture, textureCoordinate); + lowp vec4 blurredImageColor = texture2D(inputImageTexture2, textureCoordinate2); + + lowp float blurIntensity = 1.0 - smoothstep(topFocusLevel - focusFallOffRate, topFocusLevel, textureCoordinate2.y); + blurIntensity += smoothstep(bottomFocusLevel, bottomFocusLevel + focusFallOffRate, textureCoordinate2.y); + + gl_FragColor = mix(sharpImageColor, blurredImageColor, blurIntensity); +} +""" +public let ToonFragmentShader = """ +precision highp float; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform highp float intensity; +uniform highp float threshold; +uniform highp float quantizationLevels; + +const highp vec3 W = vec3(0.2125, 0.7154, 0.0721); + +void main() +{ + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity; + float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity; + + float mag = length(vec2(h, v)); + + vec3 posterizedImageColor = floor((textureColor.rgb * quantizationLevels) + 0.5) / quantizationLevels; + + float thresholdTest = 1.0 - step(threshold, mag); + + gl_FragColor = vec4(posterizedImageColor * thresholdTest, textureColor.a); +} +""" +public let TransformVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; + +uniform mat4 transformMatrix; +uniform mat4 orthographicMatrix; + +varying vec2 textureCoordinate; + +void main() +{ + gl_Position = transformMatrix * vec4(position.xyz, 1.0) * orthographicMatrix; + textureCoordinate = inputTextureCoordinate.xy; +} +""" +public let TwoInputVertexShader = """ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; +attribute vec4 inputTextureCoordinate2; + +varying vec2 textureCoordinate; +varying vec2 textureCoordinate2; + +void main() +{ + gl_Position = position; + textureCoordinate = inputTextureCoordinate.xy; + textureCoordinate2 = inputTextureCoordinate2.xy; +} + +""" +public let UnsharpMaskFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +uniform highp float intensity; + +void main() +{ + lowp vec4 sharpImageColor = texture2D(inputImageTexture, textureCoordinate); + lowp vec3 blurredImageColor = texture2D(inputImageTexture2, textureCoordinate2).rgb; + + gl_FragColor = vec4(sharpImageColor.rgb * intensity + blurredImageColor * (1.0 - intensity), sharpImageColor.a); +} + +""" +public let VibranceFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform lowp float vibrance; + +void main() { + lowp vec4 color = texture2D(inputImageTexture, textureCoordinate); + lowp float average = (color.r + color.g + color.b) / 3.0; + lowp float mx = max(color.r, max(color.g, color.b)); + lowp float amt = (mx - average) * (-vibrance * 3.0); + color.rgb = mix(color.rgb, vec3(mx), amt); + gl_FragColor = color; +} +""" +public let VignetteFragmentShader = """ +uniform sampler2D inputImageTexture; +varying highp vec2 textureCoordinate; + +uniform lowp vec2 vignetteCenter; +uniform lowp vec3 vignetteColor; +uniform highp float vignetteStart; +uniform highp float vignetteEnd; + +void main() +{ + lowp vec4 sourceImageColor = texture2D(inputImageTexture, textureCoordinate); + lowp float d = distance(textureCoordinate, vec2(vignetteCenter.x, vignetteCenter.y)); + lowp float percent = smoothstep(vignetteStart, vignetteEnd, d); + gl_FragColor = vec4(mix(sourceImageColor.rgb, vignetteColor, percent), sourceImageColor.a); +} +""" +public let WeakPixelInclusionFragmentShader = """ +precision lowp float; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + float centerIntensity = texture2D(inputImageTexture, textureCoordinate).r; + + float pixelIntensitySum = bottomLeftIntensity + topRightIntensity + topLeftIntensity + bottomRightIntensity + leftIntensity + rightIntensity + bottomIntensity + topIntensity + centerIntensity; + float sumTest = step(1.5, pixelIntensitySum); + float pixelTest = step(0.01, centerIntensity); + + gl_FragColor = vec4(vec3(sumTest * pixelTest), 1.0); +} +""" +public let WhiteBalanceFragmentShader = """ +uniform sampler2D inputImageTexture; +varying highp vec2 textureCoordinate; + +uniform lowp float temperature; +uniform lowp float tint; + +const lowp vec3 warmFilter = vec3(0.93, 0.54, 0.0); + +const mediump mat3 RGBtoYIQ = mat3(0.299, 0.587, 0.114, 0.596, -0.274, -0.322, 0.212, -0.523, 0.311); +const mediump mat3 YIQtoRGB = mat3(1.0, 0.956, 0.621, 1.0, -0.272, -0.647, 1.0, -1.105, 1.702); + +void main() +{ + lowp vec4 source = texture2D(inputImageTexture, textureCoordinate); + + mediump vec3 yiq = RGBtoYIQ * source.rgb; //adjusting tint + yiq.b = clamp(yiq.b + tint*0.5226*0.1, -0.5226, 0.5226); + lowp vec3 rgb = YIQtoRGB * yiq; + + lowp vec3 processed = vec3( + (rgb.r < 0.5 ? (2.0 * rgb.r * warmFilter.r) : (1.0 - 2.0 * (1.0 - rgb.r) * (1.0 - warmFilter.r))), //adjusting temperature + (rgb.g < 0.5 ? (2.0 * rgb.g * warmFilter.g) : (1.0 - 2.0 * (1.0 - rgb.g) * (1.0 - warmFilter.g))), + (rgb.b < 0.5 ? (2.0 * rgb.b * warmFilter.b) : (1.0 - 2.0 * (1.0 - rgb.b) * (1.0 - warmFilter.b)))); + + gl_FragColor = vec4(mix(rgb, processed, temperature), source.a); +} +""" +public let XYDerivativeFragmentShader = """ +// I'm using the Prewitt operator to obtain the derivative, then squaring the X and Y components and placing the product of the two in Z. +// In tests, Prewitt seemed to be tied with Sobel for the best, and it's just a little cheaper to compute. +// This is primarily intended to be used with corner detection filters. + +precision highp float; + +varying vec2 textureCoordinate; +varying vec2 leftTextureCoordinate; +varying vec2 rightTextureCoordinate; + +varying vec2 topTextureCoordinate; +varying vec2 topLeftTextureCoordinate; +varying vec2 topRightTextureCoordinate; + +varying vec2 bottomTextureCoordinate; +varying vec2 bottomLeftTextureCoordinate; +varying vec2 bottomRightTextureCoordinate; + +uniform sampler2D inputImageTexture; + +void main() +{ + float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r; + float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r; + float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r; + float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r; + float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r; + float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r; + float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r; + float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r; + + float verticalDerivative = -topLeftIntensity - topIntensity - topRightIntensity + bottomLeftIntensity + bottomIntensity + bottomRightIntensity; + float horizontalDerivative = -bottomLeftIntensity - leftIntensity - topLeftIntensity + bottomRightIntensity + rightIntensity + topRightIntensity; + verticalDerivative = verticalDerivative; + horizontalDerivative = horizontalDerivative; + + // Scaling the X * Y operation so that negative numbers are not clipped in the 0..1 range. This will be expanded in the corner detection filter + gl_FragColor = vec4(horizontalDerivative * horizontalDerivative, verticalDerivative * verticalDerivative, ((verticalDerivative * horizontalDerivative) + 1.0) / 2.0, 1.0); +} + +""" +public let YUVConversionFullRangeUVPlanarFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; +varying highp vec2 textureCoordinate3; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; +uniform sampler2D inputImageTexture3; + +uniform mediump mat3 colorConversionMatrix; + +void main() +{ + mediump vec3 yuv; + + yuv.x = texture2D(inputImageTexture, textureCoordinate).r; + yuv.y = texture2D(inputImageTexture2, textureCoordinate).r - 0.5; + yuv.z = texture2D(inputImageTexture3, textureCoordinate).r - 0.5; + lowp vec3 rgb = colorConversionMatrix * yuv; + + gl_FragColor = vec4(rgb, 1.0); +} +""" +public let YUVConversionFullRangeFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +uniform mediump mat3 colorConversionMatrix; + +void main() +{ + mediump vec3 yuv; + + yuv.x = texture2D(inputImageTexture, textureCoordinate).r; + yuv.yz = texture2D(inputImageTexture2, textureCoordinate).ra - vec2(0.5, 0.5); + lowp vec3 rgb = colorConversionMatrix * yuv; + + gl_FragColor = vec4(rgb, 1.0); +} +""" +public let YUVConversionVideoRangeFragmentShader = """ +varying highp vec2 textureCoordinate; +varying highp vec2 textureCoordinate2; + +uniform sampler2D inputImageTexture; +uniform sampler2D inputImageTexture2; + +uniform mediump mat3 colorConversionMatrix; + +void main() +{ + mediump vec3 yuv; + + yuv.x = texture2D(inputImageTexture, textureCoordinate).r - (16.0/255.0); + yuv.yz = texture2D(inputImageTexture2, textureCoordinate).ra - vec2(0.5, 0.5); + lowp vec3 rgb = colorConversionMatrix * yuv; + + gl_FragColor = vec4(rgb, 1.0); +} +""" +public let ZoomBlurFragmentShader = """ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; + +uniform highp vec2 blurCenter; +uniform highp float blurSize; + +void main() +{ + // TODO: Do a more intelligent scaling based on resolution here + highp vec2 samplingOffset = 1.0/100.0 * (blurCenter - textureCoordinate) * blurSize; + + lowp vec4 fragmentColor = texture2D(inputImageTexture, textureCoordinate) * 0.18; + fragmentColor += texture2D(inputImageTexture, textureCoordinate + samplingOffset) * 0.15; + fragmentColor += texture2D(inputImageTexture, textureCoordinate + (2.0 * samplingOffset)) * 0.12; + fragmentColor += texture2D(inputImageTexture, textureCoordinate + (3.0 * samplingOffset)) * 0.09; + fragmentColor += texture2D(inputImageTexture, textureCoordinate + (4.0 * samplingOffset)) * 0.05; + fragmentColor += texture2D(inputImageTexture, textureCoordinate - samplingOffset) * 0.15; + fragmentColor += texture2D(inputImageTexture, textureCoordinate - (2.0 * samplingOffset)) * 0.12; + fragmentColor += texture2D(inputImageTexture, textureCoordinate - (3.0 * samplingOffset)) * 0.09; + fragmentColor += texture2D(inputImageTexture, textureCoordinate - (4.0 * samplingOffset)) * 0.05; + + gl_FragColor = fragmentColor; +} +""" diff --git a/framework/Source/Operations/Shaders/ShaderConverter.sh b/framework/Source/Operations/Shaders/ShaderConverter.sh index 60e9e603..25afc514 100755 --- a/framework/Source/Operations/Shaders/ShaderConverter.sh +++ b/framework/Source/Operations/Shaders/ShaderConverter.sh @@ -46,12 +46,10 @@ for fileName in fileNames { shaderPlatform = .Both } - var accumulatedString = "public let \(convertedShaderName) = \"" + var accumulatedString = "public let \(convertedShaderName) = \"\"\"\n" let fileContents = try String(contentsOfFile:fileName, encoding:String.Encoding.ascii) - fileContents.enumerateLines {line, stop in - accumulatedString += "\(line.replacingOccurrences(of:"\"", with:"\\\""))\\n " - } - accumulatedString += "\"\n" + accumulatedString += fileContents + accumulatedString += "\n\"\"\"\n" switch (shaderPlatform) { case .OpenGL: allConvertedGLShaders += accumulatedString