• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef SHADERS__COMMON__BLOOM_COMMON_H
17 #define SHADERS__COMMON__BLOOM_COMMON_H
18 
19 #include "render/shaders/common/render_color_conversion_common.h"
20 #include "render/shaders/common/render_compatibility_common.h"
21 #include "render/shaders/common/render_post_process_structs_common.h"
22 
23 #define CORE_BLOOM_CLAMP_MAX_VALUE 64512.0
24 
25 #define CORE_BLOOM_QUALITY_LOW 1
26 #define CORE_BLOOM_QUALITY_NORMAL 2
27 #define CORE_BLOOM_QUALITY_HIGH 4
28 
29 #define CORE_BLOOM_TYPE_NORMAL 0.0f
30 #define CORE_BLOOM_TYPE_HORIZONTAL 1.0f
31 #define CORE_BLOOM_TYPE_VERTICAL 2.0f
32 
33 /*
34 Combines bloom color with the given base color.
35 */
BloomCombine(vec3 baseColor,vec3 bloomColor,vec4 bloomParameters)36 vec3 BloomCombine(vec3 baseColor, vec3 bloomColor, vec4 bloomParameters)
37 {
38     return baseColor + bloomColor * bloomParameters.z;
39 }
40 
41 #define CORE_ENABLE_HEAVY_SAMPLES 1
42 
43 /*
44  * Downscales samples.
45  * "Firefly" filter with weighting.
46  */
BloomDownscaleWeighted9(vec2 uv,vec2 invTexSize,texture2D tex,sampler sampl)47 vec3 BloomDownscaleWeighted9(vec2 uv, vec2 invTexSize, texture2D tex, sampler sampl)
48 {
49     vec3 colSample = textureLod(sampler2D(tex, sampl), uv + vec2(-0.96875, 0.96875) * invTexSize, 0).xyz;
50     float weight = 1.0 / (1.0 + CalcLuma(colSample));
51     vec3 color = colSample * (8.0 / 128.0) * weight;
52     float fullWeight = weight;
53 
54     colSample = textureLod(sampler2D(tex, sampl), uv + vec2(0.00000, 0.93750) * invTexSize, 0).xyz;
55     weight = 1.0 / (1.0 + CalcLuma(colSample));
56     color += colSample * (16.0 / 128.0) * weight;
57     fullWeight += weight;
58 
59     colSample = textureLod(sampler2D(tex, sampl), uv + vec2(0.96875, 0.96875) * invTexSize, 0).xyz;
60     weight = 1.0 / (1.0 + CalcLuma(colSample));
61     color += colSample * (8.0 / 128.0) * weight;
62     fullWeight += weight;
63 
64     colSample = textureLod(sampler2D(tex, sampl), uv + vec2(-0.93750, 0.00000) * invTexSize, 0).xyz;
65     weight = 1.0 / (1.0 + CalcLuma(colSample));
66     color += colSample * (16.0 / 128.0) * weight;
67     fullWeight += weight;
68 
69     colSample = textureLod(sampler2D(tex, sampl), uv, 0).xyz;
70     weight = 1.0 / (1.0 + CalcLuma(colSample));
71     color += colSample * (32.0 / 128.0) * weight;
72     fullWeight += weight;
73 
74     colSample = textureLod(sampler2D(tex, sampl), uv + vec2(0.93750, 0.00000) * invTexSize, 0).xyz;
75     weight = 1.0 / (1.0 + CalcLuma(colSample));
76     color += colSample * (16.0 / 128.0) * weight;
77     fullWeight += weight;
78 
79     colSample = textureLod(sampler2D(tex, sampl), uv + vec2(-0.96875, -0.96875) * invTexSize, 0).xyz;
80     weight = 1.0 / (1.0 + CalcLuma(colSample));
81     color += colSample * (8.0 / 128.0) * weight;
82     fullWeight += weight;
83 
84     colSample = textureLod(sampler2D(tex, sampl), uv + vec2(0.00000, -0.93750) * invTexSize, 0).xyz;
85     weight = 1.0 / (1.0 + CalcLuma(colSample));
86     color += colSample * (16.0 / 128.0) * weight;
87     fullWeight += weight;
88 
89     colSample = textureLod(sampler2D(tex, sampl), uv + vec2(0.96875, -0.96875) * invTexSize, 0).xyz;
90     weight = 1.0 / (1.0 + CalcLuma(colSample));
91     color += colSample * (8.0 / 128.0) * weight;
92     fullWeight += weight;
93 
94     // NOTE: the original bloom has weights
95     // 4 x 0.125
96     // 4 x 025
97     // 5 x 0.5
98     // which results to 4.0 coefficient
99     // here is an approximation coefficient to get a similar bloom value
100     color *= 10.5 / (fullWeight);
101 
102     return color;
103 }
104 
BloomDownscale9(vec2 uv,vec2 invTexSize,texture2D tex,sampler sampl)105 vec3 BloomDownscale9(vec2 uv, vec2 invTexSize, texture2D tex, sampler sampl)
106 {
107     vec3 color = textureLod(sampler2D(tex, sampl), uv + vec2(-invTexSize.x, invTexSize.y), 0).rgb * (8.0 / 128.0);
108     color += textureLod(sampler2D(tex, sampl), uv + vec2(0.0, invTexSize.y), 0).rgb * (16.0 / 128.0);
109     color += textureLod(sampler2D(tex, sampl), uv + invTexSize, 0).rgb * (8.0 / 128.0);
110     color += textureLod(sampler2D(tex, sampl), uv + vec2(-invTexSize.x, 0.0), 0).rgb * (16.0 / 128.0);
111     color += textureLod(sampler2D(tex, sampl), uv, 0).rgb * (32.0 / 128.0);
112     color += textureLod(sampler2D(tex, sampl), uv + vec2(invTexSize.x, 0.0), 0).rgb * (16.0 / 128.0);
113     color += textureLod(sampler2D(tex, sampl), uv - invTexSize, 0).rgb * (8.0 / 128.0);
114     color += textureLod(sampler2D(tex, sampl), uv + vec2(0.0, -invTexSize.y), 0).rgb * (16.0 / 128.0);
115     color += textureLod(sampler2D(tex, sampl), uv + vec2(invTexSize.x, -invTexSize.y), 0).rgb * (8.0 / 128.0);
116     return color;
117 }
118 
BloomDownScaleHorizontal(vec2 uv,vec2 invTexSize,texture2D tex,sampler sampl)119 vec3 BloomDownScaleHorizontal(vec2 uv, vec2 invTexSize, texture2D tex, sampler sampl)
120 {
121     vec3 color = textureLod(sampler2D(tex, sampl), uv + vec2(-invTexSize.x * 3, 0.0), 0).rgb * 0.05;
122     color += textureLod(sampler2D(tex, sampl), uv + vec2(-invTexSize.x * 2, 0.0), 0).rgb * 0.10;
123     color += textureLod(sampler2D(tex, sampl), uv + vec2(-invTexSize.x, 0.0), 0).rgb * 0.15;
124     color += textureLod(sampler2D(tex, sampl), uv + vec2(0.0, -invTexSize.y), 0).rgb * 0.05;
125     color += textureLod(sampler2D(tex, sampl), uv, 0).rgb * 0.30;
126     color += textureLod(sampler2D(tex, sampl), uv + vec2(0.0, invTexSize.y), 0).rgb * 0.05;
127     color += textureLod(sampler2D(tex, sampl), uv + vec2(invTexSize.x, 0.0), 0).rgb * 0.15;
128     color += textureLod(sampler2D(tex, sampl), uv + vec2(invTexSize.x * 2, 0.0), 0).rgb * 0.10;
129     color += textureLod(sampler2D(tex, sampl), uv + vec2(invTexSize.x * 3, 0.0), 0).rgb * 0.05;
130     /*
131     //                               0.05
132     // Kernel:        0.05 0.10 0.15 0.30 0.15 0.10 0.05
133     //                               0.05
134     */
135     return color;
136 }
137 
BloomDownScaleVertical(vec2 uv,vec2 invTexSize,texture2D tex,sampler sampl)138 vec3 BloomDownScaleVertical(vec2 uv, vec2 invTexSize, texture2D tex, sampler sampl)
139 {
140     vec3 color = textureLod(sampler2D(tex, sampl), uv + vec2(0, -invTexSize.y * 3), 0).rgb * 0.05;
141     color += textureLod(sampler2D(tex, sampl), uv + vec2(0, -invTexSize.y * 2), 0).rgb * 0.10;
142     color += textureLod(sampler2D(tex, sampl), uv + vec2(0, -invTexSize.y), 0).rgb * 0.15;
143     color += textureLod(sampler2D(tex, sampl), uv + vec2(-invTexSize.x, 0.0), 0).rgb * 0.05;
144     color += textureLod(sampler2D(tex, sampl), uv, 0).rgb * 0.30;
145     color += textureLod(sampler2D(tex, sampl), uv + vec2(invTexSize.x, 0.0), 0).rgb * 0.05;
146     color += textureLod(sampler2D(tex, sampl), uv + vec2(0, invTexSize.y), 0).rgb * 0.15;
147     color += textureLod(sampler2D(tex, sampl), uv + vec2(0, invTexSize.y * 2), 0).rgb * 0.10;
148     color += textureLod(sampler2D(tex, sampl), uv + vec2(0, invTexSize.y * 3), 0).rgb * 0.05;
149     /*
150      *                               0.05
151      *                               0.10
152      *                               0.15
153      * Kernel:                0.05   0.30   0.05
154      *                               0.15
155      *                               0.10
156      *                               0.05
157      */
158     return color;
159 }
160 
BloomSampleAndAdd(in vec2 uv,in float coeff,in texture2D tex,in sampler sampl,inout float fullWeight,inout vec3 fullColor)161 void BloomSampleAndAdd(
162     in vec2 uv, in float coeff, in texture2D tex, in sampler sampl, inout float fullWeight, inout vec3 fullColor)
163 {
164     vec3 colSample = textureLod(sampler2D(tex, sampl), uv, 0).xyz;
165     float weight = 1.0 / (1 + CalcLuma(colSample));
166     fullColor += colSample * coeff * weight;
167     fullWeight += weight;
168 }
169 
BloomDownscaleWeighted(vec2 uv,vec2 invTexSize,texture2D tex,sampler sampl)170 vec3 BloomDownscaleWeighted(vec2 uv, vec2 invTexSize, texture2D tex, sampler sampl)
171 {
172     // first, 9 samples (calculate coefficients)
173     const float diagCoeff = (1.0f / 32.0f);
174     const float stepCoeff = (2.0f / 32.0f);
175     const float centerCoeff = (4.0f / 32.0f);
176 
177     const vec2 ts = invTexSize;
178 
179     float fullWeight = 0.00001;
180     vec3 color = vec3(0.0);
181     //
182     BloomSampleAndAdd(vec2(uv.x - ts.x, uv.y - ts.y), diagCoeff, tex, sampl, fullWeight, color);
183     BloomSampleAndAdd(vec2(uv.x, uv.y - ts.y), stepCoeff, tex, sampl, fullWeight, color);
184     BloomSampleAndAdd(vec2(uv.x + ts.x, uv.y - ts.y), diagCoeff, tex, sampl, fullWeight, color);
185 
186     //
187     BloomSampleAndAdd(vec2(uv.x - ts.x, uv.y), stepCoeff, tex, sampl, fullWeight, color);
188     BloomSampleAndAdd(vec2(uv.x, uv.y), centerCoeff, tex, sampl, fullWeight, color);
189     BloomSampleAndAdd(vec2(uv.x + ts.x, uv.y), stepCoeff, tex, sampl, fullWeight, color);
190 
191     //
192     BloomSampleAndAdd(vec2(uv.x - ts.x, uv.y + ts.y), diagCoeff, tex, sampl, fullWeight, color);
193     BloomSampleAndAdd(vec2(uv.x, uv.y + ts.y), centerCoeff, tex, sampl, fullWeight, color);
194     BloomSampleAndAdd(vec2(uv.x + ts.x, uv.y + ts.y), diagCoeff, tex, sampl, fullWeight, color);
195 
196     // then center square
197     const vec2 ths = ts * 0.5;
198 
199     BloomSampleAndAdd(vec2(uv.x - ths.x, uv.y - ths.y), centerCoeff, tex, sampl, fullWeight, color);
200     BloomSampleAndAdd(vec2(uv.x + ths.x, uv.y - ths.y), centerCoeff, tex, sampl, fullWeight, color);
201     BloomSampleAndAdd(vec2(uv.x - ths.x, uv.y + ths.y), centerCoeff, tex, sampl, fullWeight, color);
202     BloomSampleAndAdd(vec2(uv.x + ths.x, uv.y + ths.y), centerCoeff, tex, sampl, fullWeight, color);
203 
204     // NOTE: the original bloom has weights
205     // 4 x 0.125
206     // 4 x 025
207     // 5 x 0.5
208     // which results to 4.0 coefficient
209 
210     color *= (13.0 / fullWeight);
211 
212     return color;
213 }
214 
BloomDownscale(vec2 uv,vec2 invTexSize,texture2D tex,sampler sampl)215 vec3 BloomDownscale(vec2 uv, vec2 invTexSize, texture2D tex, sampler sampl)
216 {
217 #if (CORE_ENABLE_HEAVY_SAMPLES == 1)
218     // first, 9 samples (calculate coefficients)
219     const float diagCoeff = (1.0f / 32.0f);
220     const float stepCoeff = (2.0f / 32.0f);
221     const float centerCoeff = (4.0f / 32.0f);
222 
223     const vec2 ts = invTexSize;
224 
225     vec3 color = textureLod(sampler2D(tex, sampl), vec2(uv.x - ts.x, uv.y - ts.y), 0).xyz * diagCoeff;
226     color += textureLod(sampler2D(tex, sampl), vec2(uv.x, uv.y - ts.y), 0).xyz * stepCoeff;
227     color += textureLod(sampler2D(tex, sampl), vec2(uv.x + ts.x, uv.y - ts.y), 0).xyz * diagCoeff;
228 
229     color += textureLod(sampler2D(tex, sampl), vec2(uv.x - ts.x, uv.y), 0).xyz * stepCoeff;
230     color += textureLod(sampler2D(tex, sampl), vec2(uv.x, uv.y), 0).xyz * centerCoeff;
231     color += textureLod(sampler2D(tex, sampl), vec2(uv.x + ts.x, uv.y), 0).xyz * stepCoeff;
232 
233     color += textureLod(sampler2D(tex, sampl), vec2(uv.x - ts.x, uv.y + ts.y), 0).xyz * diagCoeff;
234     color += textureLod(sampler2D(tex, sampl), vec2(uv.x, uv.y + ts.y), 0).xyz * centerCoeff;
235     color += textureLod(sampler2D(tex, sampl), vec2(uv.x + ts.x, uv.y + ts.y), 0).xyz * diagCoeff;
236 
237     // then center square
238     const vec2 ths = ts * 0.5;
239 
240     color += textureLod(sampler2D(tex, sampl), vec2(uv.x - ths.x, uv.y - ths.y), 0).xyz * centerCoeff;
241     color += textureLod(sampler2D(tex, sampl), vec2(uv.x + ths.x, uv.y - ths.y), 0).xyz * centerCoeff;
242     color += textureLod(sampler2D(tex, sampl), vec2(uv.x - ths.x, uv.y + ths.y), 0).xyz * centerCoeff;
243     color += textureLod(sampler2D(tex, sampl), vec2(uv.x + ths.x, uv.y + ths.y), 0).xyz * centerCoeff;
244 
245 #else
246 
247     const vec2 ths = invTexSize * 0.5;
248 
249     // center
250     vec3 color = textureLod(sampler2D(tex, sampl), uv, 0).xyz * 0.5;
251     // corners
252     // 1.0 / 8.0 = 0.125
253     color = textureLod(sampler2D(tex, sampl), uv - ths, 0).xyz * 0.125 + color;
254     color = textureLod(sampler2D(tex, sampl), vec2(uv.x + ths.x, uv.y - ths.y), 0).xyz * 0.125 + color;
255     color = textureLod(sampler2D(tex, sampl), vec2(uv.x - ths.x, uv.y + ths.y), 0).xyz * 0.125 + color;
256     color = textureLod(sampler2D(tex, sampl), uv + ths, 0).xyz * 0.125 + color;
257 
258 #endif
259 
260     return color;
261 }
262 
263 /*
264 Upscale samples.
265 */
BloomUpscale(vec2 uv,vec2 invTexSize,texture2D tex,sampler sampl)266 vec3 BloomUpscale(vec2 uv, vec2 invTexSize, texture2D tex, sampler sampl)
267 {
268     const vec2 ts = invTexSize * 2.0;
269 
270     // center
271     vec3 color = textureLod(sampler2D(tex, sampl), uv, 0).xyz * (1.0 / 2.0);
272     // corners
273     color = textureLod(sampler2D(tex, sampl), uv - ts, 0).xyz * (1.0 / 8.0) + color;
274     color = textureLod(sampler2D(tex, sampl), uv + vec2(ts.x, -ts.y), 0).xyz * (1.0 / 8.0) + color;
275     color = textureLod(sampler2D(tex, sampl), uv + vec2(-ts.x, ts.y), 0).xyz * (1.0 / 8.0) + color;
276     color = textureLod(sampler2D(tex, sampl), uv + ts, 0).xyz * (1.0 / 8.0) + color;
277 
278     return color;
279 }
280 
281 /*
282 Upscale horizontally for horizontal bloom
283 */
BloomUpscaleHorizontal(vec2 uv,vec2 invTexSize,texture2D tex,sampler sampl)284 vec3 BloomUpscaleHorizontal(vec2 uv, vec2 invTexSize, texture2D tex, sampler sampl)
285 {
286     const vec2 ts = invTexSize * 2.0;
287 
288     vec3 color = textureLod(sampler2D(tex, sampl), uv + vec2(-ts.x * 3, 0.0), 0).xyz * 0.05;
289     color += textureLod(sampler2D(tex, sampl), uv + vec2(-ts.x * 2, 0.0), 0).xyz * 0.10;
290     color += textureLod(sampler2D(tex, sampl), uv + vec2(-ts.x, 0.0), 0).xyz * 0.15;
291     color += textureLod(sampler2D(tex, sampl), uv + vec2(0.0, -ts.y), 0).xyz * 0.05;
292     color += textureLod(sampler2D(tex, sampl), uv, 0).xyz * 0.30;
293     color += textureLod(sampler2D(tex, sampl), uv + vec2(0.0, ts.y), 0).xyz * 0.05;
294     color += textureLod(sampler2D(tex, sampl), uv + vec2(ts.x, 0.0), 0).xyz * 0.15;
295     color += textureLod(sampler2D(tex, sampl), uv + vec2(ts.x * 2, 0.0), 0).xyz * 0.10;
296     color += textureLod(sampler2D(tex, sampl), uv + vec2(ts.x * 3, 0.0), 0).xyz * 0.05;
297 
298     return color;
299 }
300 
301 /*
302 Upscale vertically for vertical bloom
303 */
BloomUpscaleVertical(vec2 uv,vec2 invTexSize,texture2D tex,sampler sampl)304 vec3 BloomUpscaleVertical(vec2 uv, vec2 invTexSize, texture2D tex, sampler sampl)
305 {
306     const vec2 ts = invTexSize * 2.0;
307 
308     vec3 color = textureLod(sampler2D(tex, sampl), uv + vec2(0, -ts.y * 3), 0).rgb * 0.05;
309     color += textureLod(sampler2D(tex, sampl), uv + vec2(0, -ts.y * 2), 0).rgb * 0.10;
310     color += textureLod(sampler2D(tex, sampl), uv + vec2(0, -ts.y), 0).rgb * 0.15;
311     color += textureLod(sampler2D(tex, sampl), uv + vec2(-ts.x, 0.0), 0).rgb * 0.05;
312     color += textureLod(sampler2D(tex, sampl), uv, 0).rgb * 0.30;
313     color += textureLod(sampler2D(tex, sampl), uv + vec2(ts.x, 0.0), 0).rgb * 0.05;
314     color += textureLod(sampler2D(tex, sampl), uv + vec2(0, ts.y), 0).rgb * 0.15;
315     color += textureLod(sampler2D(tex, sampl), uv + vec2(0, ts.y * 2), 0).rgb * 0.10;
316     color += textureLod(sampler2D(tex, sampl), uv + vec2(0, ts.y * 3), 0).rgb * 0.05;
317 
318     return color;
319 }
320 
321 #endif // SHADERS__COMMON__BLOOM_COMMON_H
322