FastBlur.qml 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2017 The Qt Company Ltd.
  4. ** Contact: https://www.qt.io/licensing/
  5. **
  6. ** This file is part of the Qt Graphical Effects module.
  7. **
  8. ** $QT_BEGIN_LICENSE:LGPL$
  9. ** Commercial License Usage
  10. ** Licensees holding valid commercial Qt licenses may use this file in
  11. ** accordance with the commercial license agreement provided with the
  12. ** Software or, alternatively, in accordance with the terms contained in
  13. ** a written agreement between you and The Qt Company. For licensing terms
  14. ** and conditions see https://www.qt.io/terms-conditions. For further
  15. ** information use the contact form at https://www.qt.io/contact-us.
  16. **
  17. ** GNU Lesser General Public License Usage
  18. ** Alternatively, this file may be used under the terms of the GNU Lesser
  19. ** General Public License version 3 as published by the Free Software
  20. ** Foundation and appearing in the file LICENSE.LGPL3 included in the
  21. ** packaging of this file. Please review the following information to
  22. ** ensure the GNU Lesser General Public License version 3 requirements
  23. ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
  24. **
  25. ** GNU General Public License Usage
  26. ** Alternatively, this file may be used under the terms of the GNU
  27. ** General Public License version 2.0 or (at your option) the GNU General
  28. ** Public license version 3 or any later version approved by the KDE Free
  29. ** Qt Foundation. The licenses are as published by the Free Software
  30. ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
  31. ** included in the packaging of this file. Please review the following
  32. ** information to ensure the GNU General Public License requirements will
  33. ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
  34. ** https://www.gnu.org/licenses/gpl-3.0.html.
  35. **
  36. ** $QT_END_LICENSE$
  37. **
  38. ****************************************************************************/
  39. import QtQuick 2.12
  40. import QtGraphicalEffects.private 1.12
  41. /*!
  42. \qmltype FastBlur
  43. \inqmlmodule QtGraphicalEffects
  44. \since QtGraphicalEffects 1.0
  45. \inherits QtQuick2::Item
  46. \ingroup qtgraphicaleffects-blur
  47. \brief Applies a fast blur effect to one or more source items.
  48. FastBlur offers lower blur quality than
  49. \l{QtGraphicalEffects::GaussianBlur}{GaussianBlur}, but it is faster to
  50. render. The FastBlur effect softens the source content by blurring it with
  51. algorithm which uses the source content downscaling and bilinear filtering.
  52. Use this effect in situations where the source content is rapidly changing
  53. and the highest possible blur quality is not
  54. needed.
  55. \table
  56. \header
  57. \li Source
  58. \li Effect applied
  59. \row
  60. \li \image Original_bug.png
  61. \li \image FastBlur_bug.png
  62. \endtable
  63. \note This effect is available when running with OpenGL.
  64. s
  65. \section1 Example
  66. The following example shows how to apply the effect.
  67. \snippet FastBlur-example.qml example
  68. */
  69. Item {
  70. id: rootItem
  71. /*!
  72. This property defines the source item that is going to be blurred.
  73. \note It is not supported to let the effect include itself, for
  74. instance by setting source to the effect's parent.
  75. */
  76. property variant source
  77. /*!
  78. This property defines the distance of the neighboring pixels which affect
  79. the blurring of an individual pixel. A larger radius increases the blur
  80. effect. FastBlur algorithm may internally reduce the accuracy of the radius in order to
  81. provide good rendering performance.
  82. The value ranges from 0.0 (no blur) to inf. Visual quality of the blur is reduced when
  83. radius exceeds value 64. By default, the property is set to \c 0.0 (no blur).
  84. \table
  85. \header
  86. \li Output examples with different blur values
  87. \li
  88. \li
  89. \row
  90. \li \image FastBlur_radius1.png
  91. \li \image FastBlur_radius2.png
  92. \li \image FastBlur_radius3.png
  93. \row
  94. \li \b { radius: 0 }
  95. \li \b { radius: 32 }
  96. \li \b { radius: 64 }
  97. \endtable
  98. */
  99. property real radius: 0.0
  100. /*!
  101. This property defines the blur behavior near the edges of the item,
  102. where the pixel blurring is affected by the pixels outside the source
  103. edges.
  104. If the property is set to \c true, the pixels outside the source are
  105. interpreted to be transparent, which is similar to OpenGL
  106. clamp-to-border extension. The blur is expanded slightly outside the
  107. effect item area.
  108. If the property is set to \c false, the pixels outside the source are
  109. interpreted to contain the same color as the pixels at the edge of the
  110. item, which is similar to OpenGL clamp-to-edge behavior. The blur does
  111. not expand outside the effect item area.
  112. By default, the property is set to \c false.
  113. \table
  114. \header
  115. \li Output examples with different transparentBorder values
  116. \li
  117. \li
  118. \row
  119. \li \image FastBlur_transparentBorder1.png
  120. \li \image FastBlur_transparentBorder2.png
  121. \row
  122. \li \b { transparentBorder: false }
  123. \li \b { transparentBorder: true }
  124. \row
  125. \li \l radius: 64
  126. \li \l radius: 64
  127. \endtable
  128. */
  129. property bool transparentBorder: false
  130. /*!
  131. This property allows the effect output pixels to be cached in order to
  132. improve the rendering performance.
  133. Every time the source or effect properties are changed, the pixels in
  134. the cache must be updated. Memory consumption is increased, because an
  135. extra buffer of memory is required for storing the effect output.
  136. It is recommended to disable the cache when the source or the effect
  137. properties are animated.
  138. By default, the property is set to \c false.
  139. */
  140. property bool cached: false
  141. SourceProxy {
  142. id: sourceProxy
  143. input: rootItem.source
  144. }
  145. ShaderEffectSource {
  146. id: cacheItem
  147. anchors.fill: shaderItem
  148. visible: rootItem.cached
  149. sourceItem: shaderItem
  150. live: true
  151. hideSource: visible
  152. smooth: rootItem.radius > 0
  153. }
  154. /*! \internal */
  155. property string __internalBlurVertexShader: "qrc:/qt-project.org/imports/QtGraphicalEffects/shaders/fastblur_internal.vert"
  156. /*! \internal */
  157. property string __internalBlurFragmentShader: "qrc:/qt-project.org/imports/QtGraphicalEffects/shaders/fastblur_internal.frag"
  158. ShaderEffect {
  159. id: level0
  160. property variant source: sourceProxy.output
  161. anchors.fill: parent
  162. visible: false
  163. smooth: true
  164. }
  165. ShaderEffectSource {
  166. id: level1
  167. width: Math.ceil(shaderItem.width / 32) * 32
  168. height: Math.ceil(shaderItem.height / 32) * 32
  169. sourceItem: level0
  170. hideSource: rootItem.visible
  171. sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0, 0, 0, 0)
  172. visible: false
  173. smooth: rootItem.radius > 0
  174. }
  175. ShaderEffect {
  176. id: effect1
  177. property variant source: level1
  178. property real yStep: 1/height
  179. property real xStep: 1/width
  180. anchors.fill: level2
  181. visible: false
  182. smooth: true
  183. vertexShader: __internalBlurVertexShader
  184. fragmentShader: __internalBlurFragmentShader
  185. }
  186. ShaderEffectSource {
  187. id: level2
  188. width: level1.width / 2
  189. height: level1.height / 2
  190. sourceItem: effect1
  191. hideSource: rootItem.visible
  192. visible: false
  193. smooth: true
  194. }
  195. ShaderEffect {
  196. id: effect2
  197. property variant source: level2
  198. property real yStep: 1/height
  199. property real xStep: 1/width
  200. anchors.fill: level3
  201. visible: false
  202. smooth: true
  203. vertexShader: __internalBlurVertexShader
  204. fragmentShader: __internalBlurFragmentShader
  205. }
  206. ShaderEffectSource {
  207. id: level3
  208. width: level2.width / 2
  209. height: level2.height / 2
  210. sourceItem: effect2
  211. hideSource: rootItem.visible
  212. visible: false
  213. smooth: true
  214. }
  215. ShaderEffect {
  216. id: effect3
  217. property variant source: level3
  218. property real yStep: 1/height
  219. property real xStep: 1/width
  220. anchors.fill: level4
  221. visible: false
  222. smooth: true
  223. vertexShader: __internalBlurVertexShader
  224. fragmentShader: __internalBlurFragmentShader
  225. }
  226. ShaderEffectSource {
  227. id: level4
  228. width: level3.width / 2
  229. height: level3.height / 2
  230. sourceItem: effect3
  231. hideSource: rootItem.visible
  232. visible: false
  233. smooth: true
  234. }
  235. ShaderEffect {
  236. id: effect4
  237. property variant source: level4
  238. property real yStep: 1/height
  239. property real xStep: 1/width
  240. anchors.fill: level5
  241. visible: false
  242. smooth: true
  243. vertexShader: __internalBlurVertexShader
  244. fragmentShader: __internalBlurFragmentShader
  245. }
  246. ShaderEffectSource {
  247. id: level5
  248. width: level4.width / 2
  249. height: level4.height / 2
  250. sourceItem: effect4
  251. hideSource: rootItem.visible
  252. visible: false
  253. smooth: true
  254. }
  255. ShaderEffect {
  256. id: effect5
  257. property variant source: level5
  258. property real yStep: 1/height
  259. property real xStep: 1/width
  260. anchors.fill: level6
  261. visible: false
  262. smooth: true
  263. vertexShader: __internalBlurVertexShader
  264. fragmentShader: __internalBlurFragmentShader
  265. }
  266. ShaderEffectSource {
  267. id: level6
  268. width: level5.width / 2
  269. height: level5.height / 2
  270. sourceItem: effect5
  271. hideSource: rootItem.visible
  272. visible: false
  273. smooth: true
  274. }
  275. Item {
  276. id: dummysource
  277. width: 1
  278. height: 1
  279. visible: false
  280. }
  281. ShaderEffectSource {
  282. id: dummy
  283. width: 1
  284. height: 1
  285. sourceItem: dummysource
  286. visible: false
  287. smooth: false
  288. live: false
  289. }
  290. ShaderEffect {
  291. id: shaderItem
  292. property variant source1: level1
  293. property variant source2: level2
  294. property variant source3: level3
  295. property variant source4: level4
  296. property variant source5: level5
  297. property variant source6: level6
  298. property real lod: Math.sqrt(rootItem.radius / 64.0) * 1.2 - 0.2
  299. property real weight1
  300. property real weight2
  301. property real weight3
  302. property real weight4
  303. property real weight5
  304. property real weight6
  305. x: transparentBorder ? -64 : 0
  306. y: transparentBorder ? -64 : 0
  307. width: transparentBorder ? parent.width + 128 : parent.width
  308. height: transparentBorder ? parent.height + 128 : parent.height
  309. function weight(v) {
  310. if (v <= 0.0)
  311. return 1.0
  312. if (v >= 0.5)
  313. return 0.0
  314. return 1.0 - v * 2.0
  315. }
  316. function calculateWeights() {
  317. var w1 = weight(Math.abs(lod - 0.100))
  318. var w2 = weight(Math.abs(lod - 0.300))
  319. var w3 = weight(Math.abs(lod - 0.500))
  320. var w4 = weight(Math.abs(lod - 0.700))
  321. var w5 = weight(Math.abs(lod - 0.900))
  322. var w6 = weight(Math.abs(lod - 1.100))
  323. var sum = w1 + w2 + w3 + w4 + w5 + w6;
  324. weight1 = w1 / sum;
  325. weight2 = w2 / sum;
  326. weight3 = w3 / sum;
  327. weight4 = w4 / sum;
  328. weight5 = w5 / sum;
  329. weight6 = w6 / sum;
  330. upateSources()
  331. }
  332. function upateSources() {
  333. var sources = new Array();
  334. var weights = new Array();
  335. if (weight1 > 0) {
  336. sources.push(level1)
  337. weights.push(weight1)
  338. }
  339. if (weight2 > 0) {
  340. sources.push(level2)
  341. weights.push(weight2)
  342. }
  343. if (weight3 > 0) {
  344. sources.push(level3)
  345. weights.push(weight3)
  346. }
  347. if (weight4 > 0) {
  348. sources.push(level4)
  349. weights.push(weight4)
  350. }
  351. if (weight5 > 0) {
  352. sources.push(level5)
  353. weights.push(weight5)
  354. }
  355. if (weight6 > 0) {
  356. sources.push(level6)
  357. weights.push(weight6)
  358. }
  359. for (var j = sources.length; j < 6; j++) {
  360. sources.push(dummy)
  361. weights.push(0.0)
  362. }
  363. source1 = sources[0]
  364. source2 = sources[1]
  365. source3 = sources[2]
  366. source4 = sources[3]
  367. source5 = sources[4]
  368. source6 = sources[5]
  369. weight1 = weights[0]
  370. weight2 = weights[1]
  371. weight3 = weights[2]
  372. weight4 = weights[3]
  373. weight5 = weights[4]
  374. weight6 = weights[5]
  375. }
  376. Component.onCompleted: calculateWeights()
  377. onLodChanged: calculateWeights()
  378. fragmentShader: "qrc:/qt-project.org/imports/QtGraphicalEffects/shaders/fastblur.frag"
  379. }
  380. }