• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 /*
30 Combines bloom color with the given base color.
31 */
bloomCombine(vec3 baseColor,vec3 bloomColor,vec4 bloomParameters)32 vec3 bloomCombine(vec3 baseColor, vec3 bloomColor, vec4 bloomParameters)
33 {
34     return baseColor + bloomColor * bloomParameters.z;
35 }
36 
37 #define CORE_ENABLE_HEAVY_SAMPLES 1
38 
39 /*
40  * Downscales samples.
41  * "Firefly" filter with weighting.
42  */
bloomDownscaleWeighted9(vec2 uv,vec2 invTexSize,texture2D tex,sampler sampl)43 vec3 bloomDownscaleWeighted9(vec2 uv, vec2 invTexSize, texture2D tex, sampler sampl)
44 {
45     vec3 colSample = textureLod(sampler2D(tex, sampl), uv + vec2(-0.96875, 0.96875) * invTexSize, 0).xyz; // 0.96875:pa
46     float weight = 1.0 / (1.0 + CalcLuma(colSample));
47     vec3 color = colSample * (8.0 / 128.0) * weight; // 8.0, 128 : param
48     float fullWeight = weight;
49 
50     colSample =
51         textureLod(sampler2D(tex, sampl), uv + vec2(0.00000, 0.93750) * invTexSize, 0).xyz; // 0.00000,0.93750:param
52     weight = 1.0 / (1.0 + CalcLuma(colSample));
53     color += colSample * (16.0 / 128.0) * weight; // 16.0, 128.0:param
54     fullWeight += weight;
55 
56     colSample = textureLod(sampler2D(tex, sampl), uv + vec2(0.96875, 0.96875) * invTexSize, 0).xyz; // 0.96875:param
57     weight = 1.0 / (1.0 + CalcLuma(colSample));
58     color += colSample * (8.0 / 128.0) * weight; // 8.0,128.0: param
59     fullWeight += weight;
60 
61     colSample =
62         textureLod(sampler2D(tex, sampl), uv + vec2(-0.93750, 0.00000) * invTexSize, 0).xyz; // 0.00000,0.93750:param
63     weight = 1.0 / (1.0 + CalcLuma(colSample));
64     color += colSample * (16.0 / 128.0) * weight; // 16.0,128.0:param
65     fullWeight += weight;
66 
67     colSample = textureLod(sampler2D(tex, sampl), uv, 0).xyz;
68     weight = 1.0 / (1.0 + CalcLuma(colSample));
69     color += colSample * (32.0 / 128.0) * weight; // 32.0,128.0:param
70     fullWeight += weight;
71 
72     colSample =
73     textureLod(sampler2D(tex, sampl), uv + vec2(0.93750, 0.00000) * invTexSize, 0).xyz; // 0.00000,0.93750: param
74     weight = 1.0 / (1.0 + CalcLuma(colSample));
75     color += colSample * (16.0 / 128.0) * weight; // 16.0,128.0:param
76     fullWeight += weight;
77 
78     colSample = textureLod(sampler2D(tex, sampl), uv + vec2(-0.96875, -0.96875) * invTexSize, 0).xyz; // 0.96875:param
79     weight = 1.0 / (1.0 + CalcLuma(colSample));
80     color += colSample * (8.0 / 128.0) * weight; // 8.0,128.0:param
81     fullWeight += weight;
82 
83     colSample =
84         textureLod(sampler2D(tex, sampl), uv + vec2(0.00000, -0.93750) * invTexSize, 0).xyz; // 0.00000,0.93750: param
85     weight = 1.0 / (1.0 + CalcLuma(colSample));
86     color += colSample * (16.0 / 128.0) * weight; // 16.0,128.0:param
87     fullWeight += weight;
88 
89     colSample = textureLod(sampler2D(tex, sampl), uv + vec2(0.96875, -0.96875) * invTexSize, 0).xyz; // 0.96875:param
90     weight = 1.0 / (1.0 + CalcLuma(colSample));
91     color += colSample * (8.0 / 128.0) * weight; // 8.0,128.0:param
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); // 10.5:param
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 *
108         (8.0 / 128.0); // 8.0,128.0:param
109     color += textureLod(sampler2D(tex, sampl), uv + vec2(0.0, invTexSize.y), 0).rgb *
110         (16.0 / 128.0); // 16.0,128.0:param
111     color += textureLod(sampler2D(tex, sampl), uv + invTexSize, 0).rgb * (8.0 / 128.0); // 8.0,128.0:param
112     color += textureLod(sampler2D(tex, sampl), uv + vec2(-invTexSize.x, 0.0), 0).rgb *
113         (16.0 / 128.0); // 16.0,128.0:param
114     color += textureLod(sampler2D(tex, sampl), uv, 0).rgb * (32.0 / 128.0); // 32.0,128.0:param
115     color += textureLod(sampler2D(tex, sampl), uv + vec2(invTexSize.x, 0.0), 0).rgb *
116         (16.0 / 128.0); // 16.0,128.0:param
117     color += textureLod(sampler2D(tex, sampl), uv - invTexSize, 0).rgb * (8.0 / 128.0); // 8.0,128.0: param
118     color += textureLod(sampler2D(tex, sampl), uv + vec2(0.0, -invTexSize.y), 0).rgb *
119         (16.0 / 128.0); // 16.0, 128.0:param
120     color += textureLod(sampler2D(tex, sampl), uv + vec2(invTexSize.x, -invTexSize.y), 0).rgb *
121        (8.0 / 128.0); // 8.0, 128.0:param
122     return color;
123 }
124 
BloomSampleAndAdd(in vec2 uv,in float coeff,in texture2D tex,in sampler sampl,inout float fullWeight,inout vec3 fullColor)125 void BloomSampleAndAdd(
126     in vec2 uv, in float coeff, in texture2D tex, in sampler sampl, inout float fullWeight, inout vec3 fullColor)
127 {
128     vec3 colSample = textureLod(sampler2D(tex, sampl), uv, 0).xyz;
129     float weight = 1.0 / (1 + CalcLuma(colSample));
130     fullColor += colSample * coeff * weight;
131     fullWeight += weight;
132 }
133 
bloomDownscaleWeighted(vec2 uv,vec2 invTexSize,texture2D tex,sampler sampl)134 vec3 bloomDownscaleWeighted(vec2 uv, vec2 invTexSize, texture2D tex, sampler sampl)
135 {
136     // first, 9 samples (calculate coefficients)
137     const float diagCoeff = (1.0f / 32.0f); // 32.0 : param
138     const float stepCoeff = (2.0f / 32.0f); // 2.0, 32.0 : param
139     const float centerCoeff = (4.0f / 32.0f); // 4.0,32.0 : param
140 
141     const vec2 ts = invTexSize;
142 
143     float fullWeight = 0.00001; // 0.00001 : param
144     vec3 color = vec3(0.0);
145     //
146     BloomSampleAndAdd(vec2(uv.x - ts.x, uv.y - ts.y), diagCoeff, tex, sampl, fullWeight, color);
147     BloomSampleAndAdd(vec2(uv.x, uv.y - ts.y), stepCoeff, tex, sampl, fullWeight, color);
148     BloomSampleAndAdd(vec2(uv.x + ts.x, uv.y - ts.y), diagCoeff, tex, sampl, fullWeight, color);
149 
150     //
151     BloomSampleAndAdd(vec2(uv.x - ts.x, uv.y), stepCoeff, tex, sampl, fullWeight, color);
152     BloomSampleAndAdd(vec2(uv.x, uv.y), centerCoeff, tex, sampl, fullWeight, color);
153     BloomSampleAndAdd(vec2(uv.x + ts.x, uv.y), stepCoeff, tex, sampl, fullWeight, color);
154 
155     //
156     BloomSampleAndAdd(vec2(uv.x - ts.x, uv.y + ts.y), diagCoeff, tex, sampl, fullWeight, color);
157     BloomSampleAndAdd(vec2(uv.x, uv.y + ts.y), centerCoeff, tex, sampl, fullWeight, color);
158     BloomSampleAndAdd(vec2(uv.x + ts.x, uv.y + ts.y), diagCoeff, tex, sampl, fullWeight, color);
159 
160     // then center square
161     const vec2 ths = ts * 0.5; // 0.5 : half
162 
163     BloomSampleAndAdd(vec2(uv.x - ths.x, uv.y - ths.y), centerCoeff, tex, sampl, fullWeight, color);
164     BloomSampleAndAdd(vec2(uv.x + ths.x, uv.y - ths.y), centerCoeff, tex, sampl, fullWeight, color);
165     BloomSampleAndAdd(vec2(uv.x - ths.x, uv.y + ths.y), centerCoeff, tex, sampl, fullWeight, color);
166     BloomSampleAndAdd(vec2(uv.x + ths.x, uv.y + ths.y), centerCoeff, tex, sampl, fullWeight, color);
167 
168     // NOTE: the original bloom has weights
169     // 4 x 0.125
170     // 4 x 025
171     // 5 x 0.5
172     // which results to 4.0 coefficient
173 
174     color *= (13.0 / fullWeight); // 13.0 : param
175 
176     return color;
177 }
178 
bloomDownscale(vec2 uv,vec2 invTexSize,texture2D tex,sampler sampl)179 vec3 bloomDownscale(vec2 uv, vec2 invTexSize, texture2D tex, sampler sampl)
180 {
181 #if (CORE_ENABLE_HEAVY_SAMPLES == 1)
182     // first, 9 samples (calculate coefficients)
183     const float diagCoeff = (1.0f / 32.0f); // 32.0 : param
184     const float stepCoeff = (2.0f / 32.0f); // 2.0,32.0 : param
185     const float centerCoeff = (4.0f / 32.0f); // 4.0, 32.0 : param
186 
187     const vec2 ts = invTexSize;
188 
189     vec3 color = textureLod(sampler2D(tex, sampl), vec2(uv.x - ts.x, uv.y - ts.y), 0).xyz * diagCoeff;
190     color += textureLod(sampler2D(tex, sampl), vec2(uv.x, uv.y - ts.y), 0).xyz * stepCoeff;
191     color += textureLod(sampler2D(tex, sampl), vec2(uv.x + ts.x, uv.y - ts.y), 0).xyz * diagCoeff;
192 
193     color += textureLod(sampler2D(tex, sampl), vec2(uv.x - ts.x, uv.y), 0).xyz * stepCoeff;
194     color += textureLod(sampler2D(tex, sampl), vec2(uv.x, uv.y), 0).xyz * centerCoeff;
195     color += textureLod(sampler2D(tex, sampl), vec2(uv.x + ts.x, uv.y), 0).xyz * stepCoeff;
196 
197     color += textureLod(sampler2D(tex, sampl), vec2(uv.x - ts.x, uv.y + ts.y), 0).xyz * diagCoeff;
198     color += textureLod(sampler2D(tex, sampl), vec2(uv.x, uv.y + ts.y), 0).xyz * centerCoeff;
199     color += textureLod(sampler2D(tex, sampl), vec2(uv.x + ts.x, uv.y + ts.y), 0).xyz * diagCoeff;
200 
201     // then center square
202     const vec2 ths = ts * 0.5; // 0.5 : half
203 
204     color += textureLod(sampler2D(tex, sampl), vec2(uv.x - ths.x, uv.y - ths.y), 0).xyz * centerCoeff;
205     color += textureLod(sampler2D(tex, sampl), vec2(uv.x + ths.x, uv.y - ths.y), 0).xyz * centerCoeff;
206     color += textureLod(sampler2D(tex, sampl), vec2(uv.x - ths.x, uv.y + ths.y), 0).xyz * centerCoeff;
207     color += textureLod(sampler2D(tex, sampl), vec2(uv.x + ths.x, uv.y + ths.y), 0).xyz * centerCoeff;
208 
209 #else
210 
211     const vec2 ths = invTexSize * 0.5; // 0.5 : half
212 
213     // center
214     vec3 color = textureLod(sampler2D(tex, sampl), uv, 0).xyz * 0.5; // 0.5 : half
215     // corners
216     // 1.0 / 8.0 = 0.125
217     color = textureLod(sampler2D(tex, sampl), uv - ths, 0).xyz * 0.125 + color; // 0.125 : param
218     color = textureLod(sampler2D(tex, sampl), vec2(uv.x + ths.x, uv.y - ths.y), 0).xyz * 0.125 + color; // 0.125 : para
219     color = textureLod(sampler2D(tex, sampl), vec2(uv.x - ths.x, uv.y + ths.y), 0).xyz * 0.125 + color; // 0.125 : para
220     color = textureLod(sampler2D(tex, sampl), uv + ths, 0).xyz * 0.125 + color; // 0.125 : param
221 
222 #endif
223 
224     return color;
225 }
226 
227 /*
228 Upscale samples.
229 */
bloomUpscale(vec2 uv,vec2 invTexSize,texture2D tex,sampler sampl)230 vec3 bloomUpscale(vec2 uv, vec2 invTexSize, texture2D tex, sampler sampl)
231 {
232     const vec2 ts = invTexSize * 2.0; // 2.0 : size
233 
234     // center
235     vec3 color = textureLod(sampler2D(tex, sampl), uv, 0).xyz * (1.0 / 2.0); // 2.0 ;param
236     // corners
237     color = textureLod(sampler2D(tex, sampl), uv - ts, 0).xyz * (1.0 / 8.0) + color; // 8.0 : param
238     color = textureLod(sampler2D(tex, sampl), uv + vec2(ts.x, -ts.y), 0).xyz * (1.0 / 8.0) + color; // 8.0 : param
239     color = textureLod(sampler2D(tex, sampl), uv + vec2(-ts.x, ts.y), 0).xyz * (1.0 / 8.0) + color; // 8.0 : param
240     color = textureLod(sampler2D(tex, sampl), uv + ts, 0).xyz * (1.0 / 8.0) + color; // 8.0 : param
241 
242     return color;
243 }
244 
245 #endif // SHADERS__COMMON__BLOOM_COMMON_H
246