1/****************************************************************************
2**
3** Copyright (C) 2014 NVIDIA Corporation.
4** Copyright (C) 2019 The Qt Company Ltd.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of Qt 3D Studio.
8**
9** $QT_BEGIN_LICENSE:GPL$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU
20** General Public License version 3 or (at your option) any later version
21** approved by the KDE Free Qt Foundation. The licenses are as published by
22** the Free Software Foundation and appearing in the file LICENSE.GPL3
23** included in the packaging of this file. Please review the following
24** information to ensure the GNU General Public License requirements will
25** be met: https://www.gnu.org/licenses/gpl-3.0.html.
26**
27** $QT_END_LICENSE$
28**
29****************************************************************************/
30
31#ifndef BLUR_GLSLLIB
32#define BLUR_GLSLLIB 1
33#include "depthpass.glsllib"
34varying float xIncrement;
35varying float yIncrement;
36varying vec2 TexCoord0;
37varying vec2 TexCoord1;
38varying vec2 TexCoord2;
39varying vec2 TexCoord3;
40varying vec2 TexCoord4;
41varying vec2 TexCoord5;
42varying vec2 TexCoord6;
43varying vec2 TexCoord7;
44
45
46const vec3 poisson0 = vec3( 0.000000, 0.000000, 0.000000 );
47const vec3 poisson1 = vec3( 0.527837, -0.085868, 0.534776 );
48const vec3 poisson2 = vec3( -0.040088, 0.537087, 0.538581 );
49const vec3 poisson3 = vec3( -0.670445, -0.017995, 0.670686 );
50const vec3 poisson4 = vec3( -0.419418, -0.616039, 0.745262 );
51const vec3 poisson5 = vec3( 0.440453, -0.639399, 0.776421 );
52const vec3 poisson6 = vec3( -0.757088, 0.349334, 0.833796 );
53const vec3 poisson7 = vec3( 0.574619, 0.685879, 0.894772 );
54
55//7 textel gaussian
56#define WT7_0 20.0
57#define WT7_1 15.0
58#define WT7_2 6.0
59#define WT7_3 1.0
60#define WT7_NORMALIZE (WT7_0+2.0*(WT7_1+WT7_2+WT7_3))
61
62//3 textel gaussian
63#define WT3_0 1.0
64#define WT3_1 0.6
65#define WT3_NORMALIZE (WT3_0+2.0*(WT3_1))
66
67uniform vec2 CameraClipRange;
68
69float GetDepthMultiplier(vec2 inTexCoord, sampler2D inDepthSampler, float inFocusDistance, float inFocusWidth, float inFocusPenumbra)
70{
71    float depthTap = getDepthValue( texture2D(inDepthSampler, inTexCoord), CameraClipRange );
72    float linearDepth = depthValueToLinearDistance( depthTap, CameraClipRange );
73    float depthDiff = max( 0.0, abs( linearDepth - inFocusDistance ) - (inFocusWidth/2.0) ) / inFocusPenumbra;
74    return clamp( depthDiff, 0.0, 1.0 );
75}
76
77float GetTiltShiftMultiplier(vec2 inTexCoord, float inFocusBarHeight, float inFocusWidth )
78{
79    //For now, you can't rotate the focus blur but in time you will be able to.
80    float texPos = inTexCoord.y;
81    float focusDiff = max( 0.0, abs( texPos - inFocusBarHeight ) - (inFocusWidth/2.0) ) / inFocusWidth;
82    return clamp( focusDiff, 0.0, 1.0 );
83}
84
85#ifdef VERTEX_SHADER
86
87void SetupBoxBlurCoords(vec2 inTexInfo)
88{
89    xIncrement = .5 / inTexInfo.x;
90    yIncrement = .5 / inTexInfo.y;
91    TexCoord0 = vec2( TexCoord.x + xIncrement, TexCoord.y + yIncrement );
92    TexCoord1 = vec2( TexCoord.x - xIncrement, TexCoord.y - yIncrement );
93    TexCoord2 = vec2( TexCoord.x - xIncrement, TexCoord.y + yIncrement );
94    TexCoord3 = vec2( TexCoord.x + xIncrement, TexCoord.y - yIncrement );
95}
96
97void SetupPoissonBlurCoords(float inBlurAmount, vec2 inTexInfo )
98{
99    float incX = inBlurAmount / inTexInfo.x;
100    float incY = inBlurAmount / inTexInfo.y;
101    TexCoord0 = vec2( TexCoord.x + poisson0.x * incX, TexCoord.y + poisson0.y * incY );
102    TexCoord1 = vec2( TexCoord.x + poisson1.x * incX, TexCoord.y + poisson1.y * incY );
103    TexCoord2 = vec2( TexCoord.x + poisson2.x * incX, TexCoord.y + poisson2.y * incY );
104    TexCoord3 = vec2( TexCoord.x + poisson3.x * incX, TexCoord.y + poisson3.y * incY );
105    TexCoord4 = vec2( TexCoord.x + poisson4.x * incX, TexCoord.y + poisson4.y * incY );
106    TexCoord5 = vec2( TexCoord.x + poisson5.x * incX, TexCoord.y + poisson5.y * incY );
107    TexCoord6 = vec2( TexCoord.x + poisson6.x * incX, TexCoord.y + poisson6.y * incY );
108    TexCoord7 = vec2( TexCoord.x + poisson7.x * incX, TexCoord.y + poisson7.y * incY );
109}
110
111void SetupHorizontalGaussianBlur( float inDestWidth, float inBlurAmount, vec2 inTexCoord )
112{
113    float increment = inBlurAmount/inDestWidth;
114    TexCoord0 = vec2(inTexCoord.x + increment            , inTexCoord.y );
115    TexCoord1 = vec2(inTexCoord.x + increment * 2.0      , inTexCoord.y);
116    TexCoord2 = vec2(inTexCoord.x + increment * 3.0      , inTexCoord.y);
117    TexCoord3 = vec2(inTexCoord.x                        , inTexCoord.y);
118    TexCoord4 = vec2(inTexCoord.x - increment            , inTexCoord.y);
119    TexCoord5 = vec2(inTexCoord.x - increment * 2.0      , inTexCoord.y);
120    TexCoord6 = vec2(inTexCoord.x - increment * 3.0      , inTexCoord.y);
121}
122
123void SetupVerticalGaussianBlur( float inDestHeight, float inBlurAmount, vec2 inTexCoord )
124{
125    float increment = inBlurAmount/inDestHeight;
126    TexCoord0 = vec2(inTexCoord.x, inTexCoord.y + increment );
127    TexCoord1 = vec2(inTexCoord.x, inTexCoord.y + increment * 2.0 );
128    TexCoord2 = vec2(inTexCoord.x, inTexCoord.y + increment * 3.0);
129    TexCoord3 = vec2(inTexCoord.x, inTexCoord.y);
130    TexCoord4 = vec2(inTexCoord.x, inTexCoord.y - increment);
131    TexCoord5 = vec2(inTexCoord.x, inTexCoord.y - increment * 2.0);
132    TexCoord6 = vec2(inTexCoord.x, inTexCoord.y - increment * 3.0);
133}
134
135void SetupHorizontalGaussianBlur3Tap( float inDestWidth, float inBlurAmount, vec2 inTexCoord )
136{
137    float increment = inBlurAmount/inDestWidth;
138    TexCoord0 = vec2(inTexCoord.x + increment            , inTexCoord.y );
139    TexCoord1 = vec2(inTexCoord.x                        , inTexCoord.y);
140    TexCoord2 = vec2(inTexCoord.x - increment            , inTexCoord.y);
141}
142
143void SetupVerticalGaussianBlur3Tap( float inDestHeight, float inBlurAmount, vec2 inTexCoord )
144{
145    float increment = inBlurAmount/inDestHeight;
146    TexCoord0 = vec2(inTexCoord.x, inTexCoord.y + increment );
147    TexCoord1 = vec2(inTexCoord.x, inTexCoord.y);
148    TexCoord2 = vec2(inTexCoord.x, inTexCoord.y - increment);
149}
150
151#endif
152
153#ifdef FRAGMENT_SHADER
154
155vec4 BoxDepthBlur(sampler2D inDepthSampler, sampler2D inBlurSampler, float inBlurSamplerAlphaFlag
156                            , float inFocusDistance, float inFocusWidth, float inFocusPenumbra )
157{
158    float mult0 = .25 * GetDepthMultiplier( TexCoord0, inDepthSampler, inFocusDistance, inFocusWidth, inFocusPenumbra );
159    float mult1 = .25 * GetDepthMultiplier( TexCoord1, inDepthSampler, inFocusDistance, inFocusWidth, inFocusPenumbra );
160    float mult2 = .25 * GetDepthMultiplier( TexCoord2, inDepthSampler, inFocusDistance, inFocusWidth, inFocusPenumbra );
161    float mult3 = .25 * GetDepthMultiplier( TexCoord3, inDepthSampler, inFocusDistance, inFocusWidth, inFocusPenumbra );
162    float multTotal = mult0 + mult1 + mult2 + mult3;
163    float totalDivisor = multTotal != 0.0 ? 1.0 / multTotal : 0.0;
164    vec4 OutCol = GetTextureValue(inBlurSampler, TexCoord0, inBlurSamplerAlphaFlag) * mult0;
165    OutCol += GetTextureValue(inBlurSampler, TexCoord1, inBlurSamplerAlphaFlag) * mult1;
166    OutCol += GetTextureValue(inBlurSampler, TexCoord2, inBlurSamplerAlphaFlag) * mult2;
167    OutCol += GetTextureValue(inBlurSampler, TexCoord3, inBlurSamplerAlphaFlag) * mult3;
168    return OutCol * totalDivisor;
169}
170
171vec4 BoxTiltShiftBlur( sampler2D inBlurSampler, float inBlurSamplerAlphaFlag
172                            , float inFocusBarHeight, float inFocusWidth )
173{
174    float mult0 = .25 * GetTiltShiftMultiplier( TexCoord0, inFocusBarHeight, inFocusWidth );
175    float mult1 = .25 * GetTiltShiftMultiplier( TexCoord1, inFocusBarHeight, inFocusWidth );
176    float mult2 = .25 * GetTiltShiftMultiplier( TexCoord2, inFocusBarHeight, inFocusWidth );
177    float mult3 = .25 * GetTiltShiftMultiplier( TexCoord3, inFocusBarHeight, inFocusWidth );
178    float multTotal = mult0 + mult1 + mult2 + mult3;
179    float totalDivisor = multTotal != 0.0 ? 1.0 / multTotal : 0.0;
180    vec4 OutCol = GetTextureValuePreMult(inBlurSampler, TexCoord0) * mult0;
181    OutCol += GetTextureValuePreMult(inBlurSampler, TexCoord1) * mult1;
182    OutCol += GetTextureValuePreMult(inBlurSampler, TexCoord2) * mult2;
183    OutCol += GetTextureValuePreMult(inBlurSampler, TexCoord3) * mult3;
184    return OutCol * totalDivisor;
185}
186
187vec4 PoissonDepthBlur(sampler2D inSampler, float inAlphaFlag, sampler2D inDepthSampler
188                        , float inFocusDistance, float inFocusWidth, float inFocusPenumbra )
189{
190    float mult0 = (1.0 - poisson0.z) * GetDepthMultiplier(TexCoord0,inDepthSampler, inFocusDistance, inFocusWidth, inFocusPenumbra);
191    float mult1 = (1.0 - poisson1.z) * GetDepthMultiplier(TexCoord1,inDepthSampler, inFocusDistance, inFocusWidth, inFocusPenumbra);
192    float mult2 = (1.0 - poisson2.z) * GetDepthMultiplier(TexCoord2,inDepthSampler, inFocusDistance, inFocusWidth, inFocusPenumbra);
193
194    float multTotal = mult0 + mult1 + mult2;
195    float multMultiplier = multTotal > 0.0 ? 1.0 / multTotal : 0.0;
196
197    vec4 outColor = GetTextureValue( inSampler, TexCoord0, inAlphaFlag ) * (mult0 * multMultiplier);
198    outColor += GetTextureValue( inSampler, TexCoord1, inAlphaFlag ) * (mult1 * multMultiplier);
199    outColor += GetTextureValue( inSampler, TexCoord2, inAlphaFlag ) * (mult2 * multMultiplier);
200    return outColor;
201}
202
203vec4 PoissonTiltShiftBlur(sampler2D inSampler, float inAlphaFlag, float inBarHeight, float inFocusWidth )
204{
205    float mult0 = (1.0 - poisson0.z) * GetTiltShiftMultiplier(TexCoord0, inBarHeight, inFocusWidth );
206    float mult1 = (1.0 - poisson1.z) * GetTiltShiftMultiplier(TexCoord1, inBarHeight, inFocusWidth );
207    float mult2 = (1.0 - poisson2.z) * GetTiltShiftMultiplier(TexCoord2, inBarHeight, inFocusWidth );
208    float mult3 = (1.0 - poisson3.z) * GetTiltShiftMultiplier(TexCoord3, inBarHeight, inFocusWidth );
209    float mult4 = (1.0 - poisson4.z) * GetTiltShiftMultiplier(TexCoord4, inBarHeight, inFocusWidth );
210
211    float multTotal = mult0 + mult1 + mult2 + mult3 + mult4;
212    float multMultiplier = multTotal > 0.0 ? 1.0 / multTotal : 0.0;
213
214    vec4 outColor = GetTextureValuePreMult( inSampler, TexCoord0 ) * (mult0 * multMultiplier);
215    outColor += GetTextureValuePreMult( inSampler, TexCoord1 ) * (mult1 * multMultiplier);
216    outColor += GetTextureValuePreMult( inSampler, TexCoord2 ) * (mult2 * multMultiplier);
217    outColor += GetTextureValuePreMult( inSampler, TexCoord3 ) * (mult3 * multMultiplier);
218    outColor += GetTextureValuePreMult( inSampler, TexCoord4 ) * (mult4 * multMultiplier);
219    return outColor;
220}
221
222float GaussianAlphaBlur( sampler2D inSampler, float inAlphaFlag )
223{
224    float OutCol = 0.0;
225    OutCol += GetTextureValue(inSampler, TexCoord0, inAlphaFlag).a * ( WT7_1/WT7_NORMALIZE );
226    OutCol += GetTextureValue(inSampler, TexCoord1, inAlphaFlag).a * ( WT7_2/WT7_NORMALIZE );
227    OutCol += GetTextureValue(inSampler, TexCoord2, inAlphaFlag).a * ( WT7_3/WT7_NORMALIZE );
228    OutCol += GetTextureValue(inSampler, TexCoord3, inAlphaFlag).a * ( WT7_0/WT7_NORMALIZE );
229    OutCol += GetTextureValue(inSampler, TexCoord4, inAlphaFlag).a * ( WT7_1/WT7_NORMALIZE );
230    OutCol += GetTextureValue(inSampler, TexCoord5, inAlphaFlag).a * ( WT7_2/WT7_NORMALIZE );
231    OutCol += GetTextureValue(inSampler, TexCoord6, inAlphaFlag).a * ( WT7_3/WT7_NORMALIZE );
232    return OutCol;
233}
234
235vec4 GaussianBlur( sampler2D inSampler, float inAlphaFlag )
236{
237    vec4 OutCol = vec4(0.0);
238    OutCol += GetTextureValue(inSampler, TexCoord0, inAlphaFlag) * ( WT7_1/WT7_NORMALIZE );
239    OutCol += GetTextureValue(inSampler, TexCoord1, inAlphaFlag) * ( WT7_2/WT7_NORMALIZE );
240    OutCol += GetTextureValue(inSampler, TexCoord2, inAlphaFlag) * ( WT7_3/WT7_NORMALIZE );
241    OutCol += GetTextureValue(inSampler, TexCoord3, inAlphaFlag) * ( WT7_0/WT7_NORMALIZE );
242    OutCol += GetTextureValue(inSampler, TexCoord4, inAlphaFlag) * ( WT7_1/WT7_NORMALIZE );
243    OutCol += GetTextureValue(inSampler, TexCoord5, inAlphaFlag) * ( WT7_2/WT7_NORMALIZE );
244    OutCol += GetTextureValue(inSampler, TexCoord6, inAlphaFlag) * ( WT7_3/WT7_NORMALIZE );
245    return OutCol;
246}
247
248vec4 GaussianBlur3Tap( sampler2D inSampler, float inAlphaFlag )
249{
250    vec4 OutCol = vec4(0.0);
251    OutCol += GetTextureValue(inSampler, TexCoord0, inAlphaFlag) * ( WT3_1/WT3_NORMALIZE );
252    OutCol += GetTextureValue(inSampler, TexCoord1, inAlphaFlag) * ( WT3_0/WT3_NORMALIZE );
253    OutCol += GetTextureValue(inSampler, TexCoord2, inAlphaFlag) * ( WT3_1/WT3_NORMALIZE );
254    return OutCol;
255}
256
257//Get texture data for a texture we know is premultiplied.
258vec4 GaussianBlur3TapPremultiplied( sampler2D inSampler )
259{
260    vec4 OutCol = vec4(0.0);
261    OutCol += texture2D(inSampler, TexCoord0) * ( WT3_1/WT3_NORMALIZE );
262    OutCol += texture2D(inSampler, TexCoord1) * ( WT3_0/WT3_NORMALIZE );
263    OutCol += texture2D(inSampler, TexCoord2) * ( WT3_1/WT3_NORMALIZE );
264    return OutCol;
265}
266
267vec4 GaussianDepthBlur( sampler2D inSampler, float inTextureAlphaInfo, sampler2D inDepthSampler
268                            , float inFocusDistance, float inFocusWidth, float inFocusPenumbra )
269{
270    //We modulate each sample weight by the depth value so that we minimize bleeding of the focused
271    //area into the non-focused area.
272    float mult0 = GetDepthMultiplier(TexCoord0, inDepthSampler, inFocusDistance, inFocusWidth, inFocusPenumbra) * WT7_1;
273    float mult1 = GetDepthMultiplier(TexCoord1, inDepthSampler, inFocusDistance, inFocusWidth, inFocusPenumbra) * WT7_2;
274    float mult2 = GetDepthMultiplier(TexCoord2, inDepthSampler, inFocusDistance, inFocusWidth, inFocusPenumbra) * WT7_3;
275    float mult3 = GetDepthMultiplier(TexCoord3, inDepthSampler, inFocusDistance, inFocusWidth, inFocusPenumbra) * WT7_0;
276    float mult4 = GetDepthMultiplier(TexCoord4, inDepthSampler, inFocusDistance, inFocusWidth, inFocusPenumbra) * WT7_1;
277    float mult5 = GetDepthMultiplier(TexCoord5, inDepthSampler, inFocusDistance, inFocusWidth, inFocusPenumbra) * WT7_2;
278    float mult6 = GetDepthMultiplier(TexCoord6, inDepthSampler, inFocusDistance, inFocusWidth, inFocusPenumbra) * WT7_3;
279    float multTotal = mult0 + mult1 + mult2 + mult3 + mult4 + mult5 + mult6;
280    float multMultiplier = multTotal > 0.0 ? 1.0 / multTotal : 0.0;
281    vec4 OutCol = vec4(0.0);
282    OutCol += GetTextureValue(inSampler, TexCoord0, inTextureAlphaInfo) * (mult0 * multMultiplier);
283    OutCol += GetTextureValue(inSampler, TexCoord1, inTextureAlphaInfo) * (mult1 * multMultiplier);
284    OutCol += GetTextureValue(inSampler, TexCoord2, inTextureAlphaInfo) * (mult2 * multMultiplier);
285    OutCol += GetTextureValue(inSampler, TexCoord3, inTextureAlphaInfo) * (mult3 * multMultiplier);
286    OutCol += GetTextureValue(inSampler, TexCoord4, inTextureAlphaInfo) * (mult4 * multMultiplier);
287    OutCol += GetTextureValue(inSampler, TexCoord5, inTextureAlphaInfo) * (mult5 * multMultiplier);
288    OutCol += GetTextureValue(inSampler, TexCoord6, inTextureAlphaInfo) * (mult6 * multMultiplier);
289    return OutCol;
290}
291
292#endif
293
294
295#endif // BLUR_GLSLLIB
296