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