/**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the Qt Graphical Effects module. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "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. ** * Neither the name of The Qt Company Ltd nor the names of its ** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** 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 ** OWNER 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." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ import QtQuick 2.0 Item { id: rootItem property variant source property variant maskSource property real blur: 0.0 property bool transparentBorder: false property bool cached: false SourceProxy { id: sourceProxy input: rootItem.source } SourceProxy { id: maskSourceProxy input: rootItem.maskSource } ShaderEffectSource { id: cacheItem anchors.fill: shaderItem visible: rootItem.cached sourceItem: shaderItem live: true hideSource: visible smooth: rootItem.blur > 0 } property string __internalBlurVertexShader: " attribute highp vec4 qt_Vertex; attribute highp vec2 qt_MultiTexCoord0; uniform highp mat4 qt_Matrix; uniform highp float yStep; uniform highp float xStep; varying highp vec2 qt_TexCoord0; varying highp vec2 qt_TexCoord1; varying highp vec2 qt_TexCoord2; varying highp vec2 qt_TexCoord3; void main() { qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36); qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep); qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep); qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36); gl_Position = qt_Matrix * qt_Vertex; } " property string __internalBlurFragmentShader: " uniform lowp sampler2D source; uniform lowp float qt_Opacity; varying highp vec2 qt_TexCoord0; varying highp vec2 qt_TexCoord1; varying highp vec2 qt_TexCoord2; varying highp vec2 qt_TexCoord3; void main() { highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) + texture2D(source, qt_TexCoord1) + texture2D(source, qt_TexCoord2) + texture2D(source, qt_TexCoord3)) * 0.25; gl_FragColor = sourceColor * qt_Opacity; } " ShaderEffect { id: mask0 property variant source: maskSourceProxy.output anchors.fill: parent visible: false smooth: true } ShaderEffectSource { id: masklevel1 width: Math.ceil(shaderItem.width / 32) * 32 height: Math.ceil(shaderItem.height / 32) * 32 sourceItem: mask0 hideSource: rootItem.visible sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0, 0, 0, 0) visible: false smooth: rootItem.blur > 0 } ShaderEffect { id: level0 property variant source: sourceProxy.output anchors.fill: parent visible: false smooth: true } ShaderEffectSource { id: level1 width: Math.ceil(shaderItem.width / 32) * 32 height: Math.ceil(shaderItem.height / 32) * 32 sourceItem: level0 hideSource: rootItem.visible sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0, 0, 0, 0) visible: false smooth: rootItem.blur > 0 } ShaderEffect { id: effect1 property variant source: level1 property real yStep: 1/height property real xStep: 1/width anchors.fill: level2 visible: false smooth: true vertexShader: __internalBlurVertexShader fragmentShader: __internalBlurFragmentShader } ShaderEffectSource { id: level2 width: level1.width / 2 height: level1.height / 2 sourceItem: effect1 hideSource: rootItem.visible visible: false smooth: true } ShaderEffect { id: effect2 property variant source: level2 property real yStep: 1/height property real xStep: 1/width anchors.fill: level3 visible: false smooth: true vertexShader: __internalBlurVertexShader fragmentShader: __internalBlurFragmentShader } ShaderEffectSource { id: level3 width: level2.width / 2 height: level2.height / 2 sourceItem: effect2 hideSource: rootItem.visible visible: false smooth: true } ShaderEffect { id: effect3 property variant source: level3 property real yStep: 1/height property real xStep: 1/width anchors.fill: level4 visible: false smooth: true vertexShader: __internalBlurVertexShader fragmentShader: __internalBlurFragmentShader } ShaderEffectSource { id: level4 width: level3.width / 2 height: level3.height / 2 sourceItem: effect3 hideSource: rootItem.visible visible: false smooth: true } ShaderEffect { id: effect4 property variant source: level4 property real yStep: 1/height property real xStep: 1/width anchors.fill: level5 visible: false smooth: true vertexShader: __internalBlurVertexShader fragmentShader: __internalBlurFragmentShader } ShaderEffectSource { id: level5 width: level4.width / 2 height: level4.height / 2 sourceItem: effect4 hideSource: rootItem.visible visible: false smooth: true } ShaderEffect { id: effect5 property variant source: level5 property real yStep: 1/height property real xStep: 1/width anchors.fill: level6 visible: false smooth: true vertexShader: __internalBlurVertexShader fragmentShader: __internalBlurFragmentShader } ShaderEffectSource { id: level6 width: level5.width / 2 height: level5.height / 2 sourceItem: effect5 hideSource: rootItem.visible visible: false smooth: true } ShaderEffect { id: shaderItem property variant mask: masklevel1 property variant source1: level1 property variant source2: level2 property variant source3: level3 property variant source4: level4 property variant source5: level5 property variant source6: level6 property real lod: Math.sqrt(rootItem.blur) * 1.2 - 0.2 property real weight1 property real weight2 property real weight3 property real weight4 property real weight5 property real weight6 x: transparentBorder ? -64 : 0 y: transparentBorder ? -64 : 0 width: transparentBorder ? parent.width + 128 : parent.width height: transparentBorder ? parent.height + 128 : parent.height fragmentShader: " uniform lowp sampler2D mask; uniform lowp sampler2D source1; uniform lowp sampler2D source2; uniform lowp sampler2D source3; uniform lowp sampler2D source4; uniform lowp sampler2D source5; uniform lowp sampler2D source6; uniform lowp float lod; uniform lowp float qt_Opacity; varying mediump vec2 qt_TexCoord0; mediump float weight(mediump float v) { if (v <= 0.0) return 1.0; if (v >= 0.5) return 0.0; return 1.0 - v * 2.0; } void main() { lowp vec4 maskColor = texture2D(mask, qt_TexCoord0); mediump float l = lod * maskColor.a; mediump float w1 = weight(abs(l - 0.100)); mediump float w2 = weight(abs(l - 0.300)); mediump float w3 = weight(abs(l - 0.500)); mediump float w4 = weight(abs(l - 0.700)); mediump float w5 = weight(abs(l - 0.900)); mediump float w6 = weight(abs(l - 1.100)); mediump float sum = w1 + w2 + w3 + w4 + w5 + w6; mediump float weight1 = w1 / sum; mediump float weight2 = w2 / sum; mediump float weight3 = w3 / sum; mediump float weight4 = w4 / sum; mediump float weight5 = w5 / sum; mediump float weight6 = w6 / sum; lowp vec4 sourceColor = texture2D(source1, qt_TexCoord0) * weight1; sourceColor += texture2D(source2, qt_TexCoord0) * weight2; sourceColor += texture2D(source3, qt_TexCoord0) * weight3; sourceColor += texture2D(source4, qt_TexCoord0) * weight4; sourceColor += texture2D(source5, qt_TexCoord0) * weight5; sourceColor += texture2D(source6, qt_TexCoord0) * weight6; gl_FragColor = sourceColor * qt_Opacity; } " } }