From e5e17f55abca52bf6b93592fb68da88f0ddb3305 Mon Sep 17 00:00:00 2001 From: Tomi Korpipaa <tomi.korpipaa@qt.io> Date: Fri, 28 Feb 2020 09:04:26 +0200 Subject: [PATCH] Add tilt shift effect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I74ec0be689b6e51fb289e2c99c8da66da70296f2 Reviewed-by: Antti Määttä <antti.maatta@qt.io> Reviewed-by: Christian Strømme <christian.stromme@qt.io> --- src/imports/effectlib/TiltShift.qml | 93 +++++++++++++++++++ src/imports/effectlib/plugin.pro | 3 +- src/imports/effectlib/qmldir | 1 + src/imports/effectlib/qteffectlibrary.qrc | 3 + .../shaders/downsampletiltshift.frag | 38 ++++++++ .../shaders/poissonblurtiltshift.frag | 50 ++++++++++ .../shaders/poissonblurtiltshift.vert | 6 ++ 7 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 src/imports/effectlib/TiltShift.qml create mode 100644 src/imports/effectlib/shaders/downsampletiltshift.frag create mode 100644 src/imports/effectlib/shaders/poissonblurtiltshift.frag create mode 100644 src/imports/effectlib/shaders/poissonblurtiltshift.vert diff --git a/src/imports/effectlib/TiltShift.qml b/src/imports/effectlib/TiltShift.qml new file mode 100644 index 000000000..1d3892ef1 --- /dev/null +++ b/src/imports/effectlib/TiltShift.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Quick 3D. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.15 +import QtQuick3D 1.15 +import QtQuick3D.Effects 1.15 + +Effect { + property TextureInput sourceSampler: TextureInput { + texture: Texture {} + } + property real focusPosition: 0.5 // 0 - 1 + property real focusWidth: 0.2 // 0 - 1 + property real blurAmount: 4 // 0 - 10 + property bool isVertical: false + property bool isInverted: false + + Shader { + id: downsampleVert + stage: Shader.Vertex + shader: "shaders/downsample.vert" + } + Shader { + id: downsampleFrag + stage: Shader.Fragment + shader: "shaders/downsampletiltshift.frag" + } + + Shader { + id: blurVert + stage: Shader.Vertex + shader: "shaders/poissonblurtiltshift.vert" + } + Shader { + id: blurFrag + stage: Shader.Fragment + shader: "shaders/poissonblurtiltshift.frag" + } + + Buffer { + id: downsampleBuffer + name: "downsampleBuffer" + format: Buffer.RGBA8 + textureFilterOperation: Buffer.Linear + textureCoordOperation: Buffer.ClampToEdge + bufferFlags: Buffer.None + sizeMultiplier: 0.5 + } + + passes: [ + Pass { + shaders: [ downsampleVert, downsampleFrag ] + output: downsampleBuffer + }, + Pass { + shaders: [ blurVert, blurFrag ] + commands: [ + BufferInput { + buffer: downsampleBuffer + }, + BufferInput { + param: "sourceSampler" + } + ] + } + ] +} diff --git a/src/imports/effectlib/plugin.pro b/src/imports/effectlib/plugin.pro index 60673008a..a981fb1e7 100644 --- a/src/imports/effectlib/plugin.pro +++ b/src/imports/effectlib/plugin.pro @@ -4,8 +4,9 @@ TARGETPATH = QtQuick3D/Effects QT += quick qml quick3d-private IMPORT_VERSION = 1.$$QT_MINOR_VERSION QML_FILES = \ - SCurveTonemap.qml \ Vignette.qml \ + TiltShift.qml \ + SCurveTonemap.qml \ Scatter.qml \ MotionBlur.qml \ HDRBloomTonemap.qml \ diff --git a/src/imports/effectlib/qmldir b/src/imports/effectlib/qmldir index a4e96acee..1af833901 100644 --- a/src/imports/effectlib/qmldir +++ b/src/imports/effectlib/qmldir @@ -20,6 +20,7 @@ HDRBloomTonemap 1.0 HDRBloomTonemap.qml MotionBlur 1.0 MotionBlur.qml Scatter 1.0 Scatter.qml SCurveTonemap 1.0 SCurveTonemap.qml +TiltShift 1.0 TiltShift.qml Vignette 1.0 Vignette.qml designersupported depends QtQuick3D 1.15 diff --git a/src/imports/effectlib/qteffectlibrary.qrc b/src/imports/effectlib/qteffectlibrary.qrc index d24e8053e..b9eb9ba7e 100644 --- a/src/imports/effectlib/qteffectlibrary.qrc +++ b/src/imports/effectlib/qteffectlibrary.qrc @@ -38,5 +38,8 @@ <file>shaders/motionblurhorizontal.frag</file> <file>shaders/motionblurvertical.frag</file> <file>shaders/blend.frag</file> + <file>shaders/downsampletiltshift.frag</file> + <file>shaders/poissonblurtiltshift.vert</file> + <file>shaders/poissonblurtiltshift.frag</file> </qresource> </RCC> diff --git a/src/imports/effectlib/shaders/downsampletiltshift.frag b/src/imports/effectlib/shaders/downsampletiltshift.frag new file mode 100644 index 000000000..da81e5076 --- /dev/null +++ b/src/imports/effectlib/shaders/downsampletiltshift.frag @@ -0,0 +1,38 @@ +#include "blur.glsllib" + +float AdvancedGetTiltShiftMultiplier(vec2 inTexCoord, float inFocusBarHeight, float inFocusWidth, + bool inVertical, bool inInvert) +{ + float texPos = inVertical ? inTexCoord.x : inTexCoord.y; + float focusDiff = max(0.0, abs(texPos - inFocusBarHeight) - (inFocusWidth / 2.0)) + / inFocusWidth; + float retval = clamp(focusDiff, 0.0, 1.0); + return inInvert ? 1.0 - retval : retval; +} + +vec4 AdvancedBoxTiltShiftBlur(sampler2D inBlurSampler, float inBlurSamplerAlphaFlag, + float inFocusBarHeight, float inFocusWidth, + bool inVertical, bool inInvert) +{ + float mult0 = .25 * AdvancedGetTiltShiftMultiplier(TexCoord0, inFocusBarHeight, inFocusWidth, + inVertical, inInvert); + float mult1 = .25 * AdvancedGetTiltShiftMultiplier(TexCoord1, inFocusBarHeight, inFocusWidth, + inVertical, inInvert); + float mult2 = .25 * AdvancedGetTiltShiftMultiplier(TexCoord2, inFocusBarHeight, inFocusWidth, + inVertical, inInvert); + float mult3 = .25 * AdvancedGetTiltShiftMultiplier(TexCoord3, inFocusBarHeight, inFocusWidth, + inVertical, inInvert); + float multTotal = mult0 + mult1 + mult2 + mult3; + float totalDivisor = multTotal != 0.0 ? 1.0 / multTotal : 0.0; + vec4 outCol = GetTextureValuePreMult(inBlurSampler, TexCoord0) * mult0; + outCol += GetTextureValuePreMult(inBlurSampler, TexCoord1) * mult1; + outCol += GetTextureValuePreMult(inBlurSampler, TexCoord2) * mult2; + outCol += GetTextureValuePreMult(inBlurSampler, TexCoord3) * mult3; + return outCol * totalDivisor; +} + +void frag() +{ + gl_FragColor = AdvancedBoxTiltShiftBlur(Texture0, Texture0Info.z, focusPosition, focusWidth, + isVertical, isInverted); +} diff --git a/src/imports/effectlib/shaders/poissonblurtiltshift.frag b/src/imports/effectlib/shaders/poissonblurtiltshift.frag new file mode 100644 index 000000000..6c9bf82bf --- /dev/null +++ b/src/imports/effectlib/shaders/poissonblurtiltshift.frag @@ -0,0 +1,50 @@ +#include "blur.glsllib" + +float AdvancedGetTiltShiftMultiplier(vec2 inTexCoord, float inFocusBarHeight, float inFocusWidth, + bool inVertical, bool inInvert) +{ + float texPos = inVertical ? inTexCoord.x : inTexCoord.y; + float focusDiff = max(0.0, abs(texPos - inFocusBarHeight) - (inFocusWidth / 2.0)) + / inFocusWidth; + float retval = clamp(focusDiff, 0.0, 1.0); + return inInvert ? 1.0 - retval : retval; +} + +vec4 AdvancedPoissonTiltShiftBlur(sampler2D inSampler, float inAlphaFlag, float inBarHeight, + float inFocusWidth, bool inVertical, bool inInvert) +{ + float mult0 = (1.0 - poisson0.z) * AdvancedGetTiltShiftMultiplier(TexCoord0, inBarHeight, + inFocusWidth, inVertical, + inInvert); + float mult1 = (1.0 - poisson1.z) * AdvancedGetTiltShiftMultiplier(TexCoord1, inBarHeight, + inFocusWidth, inVertical, + inInvert); + float mult2 = (1.0 - poisson2.z) * AdvancedGetTiltShiftMultiplier(TexCoord2, inBarHeight, + inFocusWidth, inVertical, + inInvert); + float mult3 = (1.0 - poisson3.z) * AdvancedGetTiltShiftMultiplier(TexCoord3, inBarHeight, + inFocusWidth, inVertical, + inInvert); + float mult4 = (1.0 - poisson4.z) * AdvancedGetTiltShiftMultiplier(TexCoord4, inBarHeight, + inFocusWidth, inVertical, + inInvert); + + float multTotal = mult0 + mult1 + mult2 + mult3 + mult4; + float multMultiplier = multTotal > 0.0 ? 1.0 / multTotal : 0.0; + + vec4 outColor = GetTextureValuePreMult(inSampler, TexCoord0) * (mult0 * multMultiplier); + outColor += GetTextureValuePreMult(inSampler, TexCoord1) * (mult1 * multMultiplier); + outColor += GetTextureValuePreMult(inSampler, TexCoord2) * (mult2 * multMultiplier); + outColor += GetTextureValuePreMult(inSampler, TexCoord3) * (mult3 * multMultiplier); + outColor += GetTextureValuePreMult(inSampler, TexCoord4) * (mult4 * multMultiplier); + return outColor; +} + +void frag() +{ + float centerMultiplier = AdvancedGetTiltShiftMultiplier(TexCoord, focusPosition, focusWidth, + isVertical, isInverted); + vec4 blurColor = AdvancedPoissonTiltShiftBlur(Texture0, Texture0Info.z, focusPosition, + focusWidth, isVertical, isInverted); + gl_FragColor = mix(texture2D_sourceSampler(TexCoord), blurColor, centerMultiplier); +} diff --git a/src/imports/effectlib/shaders/poissonblurtiltshift.vert b/src/imports/effectlib/shaders/poissonblurtiltshift.vert new file mode 100644 index 000000000..43f45d7a4 --- /dev/null +++ b/src/imports/effectlib/shaders/poissonblurtiltshift.vert @@ -0,0 +1,6 @@ +#include "blur.glsllib" + +void vert() +{ + SetupPoissonBlurCoords(blurAmount, DestSize.xy); +} -- GitLab