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 API_RENDER_SHADERS_COMMON_CORE_BLUR_COMMON_H
17 #define API_RENDER_SHADERS_COMMON_CORE_BLUR_COMMON_H
18
19 // includes
20 #include "render_compatibility_common.h"
21
22 // specialization for CORE_BLUR_COLOR_TYPE.
23 // These are defines instead of contants to avoid extra code generation in shaders.
24 #define CORE_BLUR_TYPE_RGBA 0
25 #define CORE_BLUR_TYPE_R 1
26 #define CORE_BLUR_TYPE_RG 2
27 #define CORE_BLUR_TYPE_RGB 3
28 #define CORE_BLUR_TYPE_A 4
29 #define CORE_BLUR_TYPE_SOFT_DOWNSCALE_RGB 5
30 #define CORE_BLUR_TYPE_DOWNSCALE_RGBA 6
31 #define CORE_BLUR_TYPE_DOWNSCALE_RGBA_DOF 7
32 #define CORE_BLUR_TYPE_RGBA_DOF 8
33 #define CORE_BLUR_FILTER_SIZE 3
34
35 #ifndef VULKAN
36 #include <render/namespace.h>
37 RENDER_BEGIN_NAMESPACE()
38 #endif
39
40 #ifndef VULKAN
41 RENDER_END_NAMESPACE()
42 #endif
43
44 #ifdef VULKAN
45 /**
46 http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
47 */
48
49 const float CORE_BLUR_OFFSETS[CORE_BLUR_FILTER_SIZE] = { 0.0, 1.3846153846, 3.2307692308 };
50 const float CORE_BLUR_WEIGHTS[CORE_BLUR_FILTER_SIZE] = { 0.2270270270, 0.3162162162, 0.0702702703 };
51
GaussianBlurRGBA(texture2D tex,sampler sampl,const vec2 fragCoord,const vec2 uv,const vec2 dir,const vec2 invTexSize)52 vec4 GaussianBlurRGBA(
53 texture2D tex, sampler sampl, const vec2 fragCoord, const vec2 uv, const vec2 dir, const vec2 invTexSize)
54 {
55 vec4 color = textureLod(sampler2D(tex, sampl), uv, 0) * CORE_BLUR_WEIGHTS[0];
56
57 for (int idx = 1; idx < CORE_BLUR_FILTER_SIZE; ++idx) {
58 vec2 currOffset = vec2(CORE_BLUR_OFFSETS[idx]) * dir.xy;
59
60 color +=
61 textureLod(sampler2D(tex, sampl), (vec2(fragCoord) + currOffset) * invTexSize, 0) * CORE_BLUR_WEIGHTS[idx];
62 color +=
63 textureLod(sampler2D(tex, sampl), (vec2(fragCoord) - currOffset) * invTexSize, 0) * CORE_BLUR_WEIGHTS[idx];
64 }
65
66 return color;
67 }
68
GaussianBlurRGB(texture2D tex,sampler sampl,const vec2 fragCoord,const vec2 uv,const vec2 dir,const vec2 invTexSize)69 vec3 GaussianBlurRGB(
70 texture2D tex, sampler sampl, const vec2 fragCoord, const vec2 uv, const vec2 dir, const vec2 invTexSize)
71 {
72 vec3 color = textureLod(sampler2D(tex, sampl), uv, 0).xyz * CORE_BLUR_WEIGHTS[0];
73
74 for (int idx = 1; idx < CORE_BLUR_FILTER_SIZE; ++idx) {
75 vec2 currOffset = vec2(CORE_BLUR_OFFSETS[idx]) * dir.xy;
76
77 color += textureLod(sampler2D(tex, sampl), (vec2(fragCoord) + currOffset) * invTexSize, 0).xyz *
78 CORE_BLUR_WEIGHTS[idx];
79 color += textureLod(sampler2D(tex, sampl), (vec2(fragCoord) - currOffset) * invTexSize, 0).xyz *
80 CORE_BLUR_WEIGHTS[idx];
81 }
82
83 return color;
84 }
85
GaussianBlurRG(texture2D tex,sampler sampl,const vec2 fragCoord,const vec2 uv,const vec2 dir,const vec2 invTexSize)86 vec2 GaussianBlurRG(
87 texture2D tex, sampler sampl, const vec2 fragCoord, const vec2 uv, const vec2 dir, const vec2 invTexSize)
88 {
89 vec2 color = textureLod(sampler2D(tex, sampl), uv, 0).xy * CORE_BLUR_WEIGHTS[0];
90
91 for (int idx = 1; idx < CORE_BLUR_FILTER_SIZE; ++idx) {
92 vec2 currOffset = vec2(CORE_BLUR_OFFSETS[idx]) * dir.xy;
93
94 color += textureLod(sampler2D(tex, sampl), (vec2(fragCoord) + currOffset) * invTexSize, 0).xy *
95 CORE_BLUR_WEIGHTS[idx];
96 color += textureLod(sampler2D(tex, sampl), (vec2(fragCoord) - currOffset) * invTexSize, 0).xy *
97 CORE_BLUR_WEIGHTS[idx];
98 }
99
100 return color;
101 }
102
GaussianBlurR(texture2D tex,sampler sampl,const vec2 fragCoord,const vec2 uv,const vec2 dir,const vec2 invTexSize)103 float GaussianBlurR(
104 texture2D tex, sampler sampl, const vec2 fragCoord, const vec2 uv, const vec2 dir, const vec2 invTexSize)
105 {
106 float color = textureLod(sampler2D(tex, sampl), uv, 0).x * CORE_BLUR_WEIGHTS[0];
107
108 for (int idx = 1; idx < CORE_BLUR_FILTER_SIZE; ++idx) {
109 vec2 currOffset = vec2(CORE_BLUR_OFFSETS[idx]) * dir.xy;
110
111 color += textureLod(sampler2D(tex, sampl), (vec2(fragCoord) + currOffset) * invTexSize, 0).x *
112 CORE_BLUR_WEIGHTS[idx];
113 color += textureLod(sampler2D(tex, sampl), (vec2(fragCoord) - currOffset) * invTexSize, 0).x *
114 CORE_BLUR_WEIGHTS[idx];
115 }
116
117 return color;
118 }
119
GaussianBlurA(texture2D tex,sampler sampl,const vec2 fragCoord,const vec2 uv,const vec2 dir,const vec2 invTexSize)120 float GaussianBlurA(
121 texture2D tex, sampler sampl, const vec2 fragCoord, const vec2 uv, const vec2 dir, const vec2 invTexSize)
122 {
123 float alpha = textureLod(sampler2D(tex, sampl), uv, 0).a * CORE_BLUR_WEIGHTS[0];
124
125 for (int idx = 1; idx < CORE_BLUR_FILTER_SIZE; ++idx) {
126 vec2 currOffset = vec2(CORE_BLUR_OFFSETS[idx]) * dir.xy;
127
128 alpha += textureLod(sampler2D(tex, sampl), (vec2(fragCoord) + currOffset, 0) * invTexSize, 0).a *
129 CORE_BLUR_WEIGHTS[idx];
130 alpha += textureLod(sampler2D(tex, sampl), (vec2(fragCoord) - currOffset, 0) * invTexSize, 0).a *
131 CORE_BLUR_WEIGHTS[idx];
132 }
133
134 return alpha;
135 }
136
GaussianBlurRGBALayer(texture2DArray tex,sampler sampl,const vec2 fragCoord,const vec2 uv,const vec3 dirLayer,const vec2 invTexSize)137 vec4 GaussianBlurRGBALayer(
138 texture2DArray tex, sampler sampl, const vec2 fragCoord, const vec2 uv, const vec3 dirLayer, const vec2 invTexSize)
139 {
140 vec4 color = textureLod(sampler2DArray(tex, sampl), vec3(uv, dirLayer.z), 0) * CORE_BLUR_WEIGHTS[0];
141
142 for (int idx = 1; idx < CORE_BLUR_FILTER_SIZE; ++idx) {
143 vec2 currOffset = vec2(CORE_BLUR_OFFSETS[idx]) * dirLayer.xy;
144
145 color +=
146 textureLod(sampler2DArray(tex, sampl), vec3((vec2(fragCoord) + currOffset) * invTexSize, dirLayer.z), 0) *
147 CORE_BLUR_WEIGHTS[idx];
148 color +=
149 textureLod(sampler2DArray(tex, sampl), vec3((vec2(fragCoord) - currOffset) * invTexSize, dirLayer.z), 0) *
150 CORE_BLUR_WEIGHTS[idx];
151 }
152
153 return color;
154 }
155
GaussianBlurRGBLayer(texture2DArray tex,sampler sampl,const vec2 fragCoord,const vec2 uv,const vec3 dirLayer,const vec2 invTexSize)156 vec3 GaussianBlurRGBLayer(
157 texture2DArray tex, sampler sampl, const vec2 fragCoord, const vec2 uv, const vec3 dirLayer, const vec2 invTexSize)
158 {
159 vec3 color = textureLod(sampler2DArray(tex, sampl), vec3(uv, dirLayer.z), 0).xyz * CORE_BLUR_WEIGHTS[0];
160
161 for (int idx = 1; idx < CORE_BLUR_FILTER_SIZE; ++idx) {
162 vec2 currOffset = vec2(CORE_BLUR_OFFSETS[idx]) * dirLayer.xy;
163
164 color +=
165 textureLod(sampler2DArray(tex, sampl), vec3((vec2(fragCoord) + currOffset) * invTexSize, dirLayer.z), 0)
166 .xyz *
167 CORE_BLUR_WEIGHTS[idx];
168 color +=
169 textureLod(sampler2DArray(tex, sampl), vec3((vec2(fragCoord) - currOffset) * invTexSize, dirLayer.z), 0)
170 .xyz *
171 CORE_BLUR_WEIGHTS[idx];
172 }
173
174 return color;
175 }
176
GaussianBlurRGLayer(texture2DArray tex,sampler sampl,const vec2 fragCoord,const vec2 uv,const vec3 dirLayer,const vec2 invTexSize)177 vec2 GaussianBlurRGLayer(
178 texture2DArray tex, sampler sampl, const vec2 fragCoord, const vec2 uv, const vec3 dirLayer, const vec2 invTexSize)
179 {
180 vec2 color = textureLod(sampler2DArray(tex, sampl), vec3(uv, dirLayer.z), 0).xy * CORE_BLUR_WEIGHTS[0];
181
182 for (int idx = 1; idx < CORE_BLUR_FILTER_SIZE; ++idx) {
183 vec2 currOffset = vec2(CORE_BLUR_OFFSETS[idx]) * dirLayer.xy;
184
185 color +=
186 textureLod(sampler2DArray(tex, sampl), vec3((vec2(fragCoord) + currOffset) * invTexSize, dirLayer.z), 0)
187 .xy *
188 CORE_BLUR_WEIGHTS[idx];
189 color +=
190 textureLod(sampler2DArray(tex, sampl), vec3((vec2(fragCoord) - currOffset) * invTexSize, dirLayer.z), 0)
191 .xy *
192 CORE_BLUR_WEIGHTS[idx];
193 }
194
195 return color;
196 }
197
GaussianBlurRLayer(texture2DArray tex,sampler sampl,const vec2 fragCoord,const vec2 uv,const vec3 dirLayer,const vec2 invTexSize)198 float GaussianBlurRLayer(
199 texture2DArray tex, sampler sampl, const vec2 fragCoord, const vec2 uv, const vec3 dirLayer, const vec2 invTexSize)
200 {
201 float color = textureLod(sampler2DArray(tex, sampl), vec3(uv, dirLayer.z), 0).x * CORE_BLUR_WEIGHTS[0];
202
203 for (int idx = 1; idx < CORE_BLUR_FILTER_SIZE; ++idx) {
204 vec2 currOffset = vec2(CORE_BLUR_OFFSETS[idx]) * dirLayer.xy;
205
206 color +=
207 textureLod(sampler2DArray(tex, sampl), vec3((vec2(fragCoord) + currOffset) * invTexSize, dirLayer.z), 0).x *
208 CORE_BLUR_WEIGHTS[idx];
209 color +=
210 textureLod(sampler2DArray(tex, sampl), vec3((vec2(fragCoord) - currOffset) * invTexSize, dirLayer.z), 0).x *
211 CORE_BLUR_WEIGHTS[idx];
212 }
213
214 return color;
215 }
216
GaussianBlurALayer(texture2DArray tex,sampler sampl,const vec2 fragCoord,const vec2 uv,const vec3 dirLayer,const vec2 invTexSize)217 float GaussianBlurALayer(
218 texture2DArray tex, sampler sampl, const vec2 fragCoord, const vec2 uv, const vec3 dirLayer, const vec2 invTexSize)
219 {
220 float alpha = textureLod(sampler2DArray(tex, sampl), vec3(uv, dirLayer.z), 0).a * CORE_BLUR_WEIGHTS[0];
221
222 for (int idx = 1; idx < CORE_BLUR_FILTER_SIZE; ++idx) {
223 vec2 currOffset = vec2(CORE_BLUR_OFFSETS[idx]) * dirLayer.xy;
224
225 alpha +=
226 textureLod(sampler2DArray(tex, sampl), vec3((vec2(fragCoord) + currOffset, 0) * invTexSize, dirLayer.z), 0)
227 .a *
228 CORE_BLUR_WEIGHTS[idx];
229 alpha +=
230 textureLod(sampler2DArray(tex, sampl), vec3((vec2(fragCoord) - currOffset, 0) * invTexSize, dirLayer.z), 0)
231 .a *
232 CORE_BLUR_WEIGHTS[idx];
233 }
234
235 return alpha;
236 }
237
238 #define CORE_BLUR_SOFT_HEAVY_SAMPLES 0
239 // NOTE: dir not used
SoftDownscaleRGB(texture2D tex,sampler sampl,const vec2 fragCoord,const vec2 uv,const vec2 dir,const vec2 invTexSize)240 vec3 SoftDownscaleRGB(
241 texture2D tex, sampler sampl, const vec2 fragCoord, const vec2 uv, const vec2 dir, const vec2 invTexSize)
242 {
243 #if (CORE_BLUR_SOFT_HEAVY_SAMPLES == 1)
244
245 // first, 9 samples (calculate coefficients)
246 const float diagCoeff = (1.0f / 32.0f); // 32.0 : param
247 const float stepCoeff = (2.0f / 32.0f); // 2.0, 32.0 : param
248 const float centerCoeff = (4.0f / 32.0f); // 4.0, 32.0 : param
249
250 const vec2 ts = invTexSize;
251
252 vec3 color = textureLod(sampler2D(tex, sampl), vec2(uv.x - ts.x, uv.y - ts.y), 0).xyz * diagCoeff;
253 color += textureLod(sampler2D(tex, sampl), vec2(uv.x, uv.y - ts.y), 0).xyz * stepCoeff;
254 color += textureLod(sampler2D(tex, sampl), vec2(uv.x + ts.x, uv.y - ts.y), 0).xyz * diagCoeff;
255
256 color += textureLod(sampler2D(tex, sampl), vec2(uv.x - ts.x, uv.y), 0).xyz * stepCoeff;
257 color += textureLod(sampler2D(tex, sampl), vec2(uv.x, uv.y), 0).xyz * centerCoeff;
258 color += textureLod(sampler2D(tex, sampl), vec2(uv.x + ts.x, uv.y), 0).xyz * stepCoeff;
259
260 color += textureLod(sampler2D(tex, sampl), vec2(uv.x - ts.x, uv.y + ts.y), 0).xyz * diagCoeff;
261 color += textureLod(sampler2D(tex, sampl), vec2(uv.x, uv.y + ts.y), 0).xyz * centerCoeff;
262 color += textureLod(sampler2D(tex, sampl), vec2(uv.x + ts.x, uv.y + ts.y), 0).xyz * diagCoeff;
263
264 // then center square
265 const vec2 ths = ts * 0.5; // 0.5 half
266
267 color += textureLod(sampler2D(tex, sampl), vec2(uv.x - ths.x, uv.y - ths.y), 0).xyz * centerCoeff;
268 color += textureLod(sampler2D(tex, sampl), vec2(uv.x + ths.x, uv.y - ths.y), 0).xyz * centerCoeff;
269 color += textureLod(sampler2D(tex, sampl), vec2(uv.x - ths.x, uv.y + ths.y), 0).xyz * centerCoeff;
270 color += textureLod(sampler2D(tex, sampl), vec2(uv.x + ths.x, uv.y + ths.y), 0).xyz * centerCoeff;
271
272 #else
273
274 const vec2 ths = invTexSize * 0.5; // 0.5 : half
275
276 // center
277 vec3 color = textureLod(sampler2D(tex, sampl), uv + ths, 0).xyz * 0.5; // 0.5 : half
278 // corners
279 color = textureLod(sampler2D(tex, sampl), uv - ths, 0).xyz * 0.125 + color; // 0.125 : param
280 color = textureLod(sampler2D(tex, sampl), vec2(uv.x + ths.x, uv.y - ths.y), 0).xyz * 0.125 + color; // 0.125:param
281 color = textureLod(sampler2D(tex, sampl), vec2(uv.x - ths.x, uv.y + ths.y), 0).xyz * 0.125 + color; // 0.125:param
282 color = textureLod(sampler2D(tex, sampl), uv + ths, 0).xyz * 0.125 + color; // 0.125:pram
283
284 #endif
285
286 return color;
287 }
288
DownscaleRGBA(texture2D tex,sampler sampl,const vec2 fragCoord,const vec2 uv,const vec2 dir,const vec2 invTexSize)289 vec4 DownscaleRGBA(
290 texture2D tex, sampler sampl, const vec2 fragCoord, const vec2 uv, const vec2 dir, const vec2 invTexSize)
291 {
292 return textureLod(sampler2D(tex, sampl), uv, 0);
293 }
294
DownscaleRGBADof(texture2D tex,sampler sampl,const vec2 fragCoord,const vec2 uv,const vec2 dir,const vec2 invTexSize)295 vec4 DownscaleRGBADof(
296 texture2D tex, sampler sampl, const vec2 fragCoord, const vec2 uv, const vec2 dir, const vec2 invTexSize)
297 {
298 const vec2 ths = invTexSize * 0.5; // 0.5 : half
299
300 vec4 color = vec4(0);
301
302 // 1.0 / 8.0 = 0.125
303 float weights[5] = { 0.5, 0.125, 0.125, 0.125, 0.125 }; // 5 :size 0.125 : param
304 vec4 samples[5] = { // 5 : size
305 // center
306 textureLod(sampler2D(tex, sampl), uv, 0),
307 // corners
308 textureLod(sampler2D(tex, sampl), uv - ths, 0),
309 textureLod(sampler2D(tex, sampl), vec2(uv.x + ths.x, uv.y - ths.y), 0),
310 textureLod(sampler2D(tex, sampl), vec2(uv.x - ths.x, uv.y + ths.y), 0),
311 textureLod(sampler2D(tex, sampl), uv + ths, 0),
312 };
313 float weight = 0.0;
314 for (int i = 0; i < 5; ++i) { // 5 : size
315 weight += samples[i].a;
316 }
317 if (weight > 0.0) {
318 for (int i = 0; i < 5; ++i) { // 5 : size
319 color += samples[i] * weights[i];
320 }
321 } else {
322 color = samples[0];
323 }
324
325 return color;
326 }
327
BlurRGBADof(texture2D tex,sampler sampl,const vec2 fragCoord,const vec2 uv,const vec2 dir,const vec2 invTexSize)328 vec4 BlurRGBADof(
329 texture2D tex, sampler sampl, const vec2 fragCoord, const vec2 uv, const vec2 dir, const vec2 invTexSize)
330 {
331 const vec2 ths = invTexSize * 0.5; // 0.5 : half
332
333 CORE_RELAXEDP vec4 color = vec4(0);
334
335 CORE_RELAXEDP vec4 samples[1 + 2 * CORE_BLUR_FILTER_SIZE]; // 2 :param
336 samples[0] = textureLod(sampler2D(tex, sampl), uv, 0);
337 float weight = samples[0].a;
338 for (int idx = 1; idx < CORE_BLUR_FILTER_SIZE; ++idx) {
339 vec2 currOffset = vec2(CORE_BLUR_OFFSETS[idx]) * dir.xy;
340
341 samples[idx * 2 - 1] = // 2 : index
342 textureLod(sampler2D(tex, sampl), (vec2(fragCoord) + currOffset) * invTexSize, 0);
343 weight += samples[idx * 2 - 1].a; // 2 : index
344 samples[idx * 2] = textureLod(sampler2D(tex, sampl), (vec2(fragCoord) - currOffset) * invTexSize, 0); // 2: idx
345 weight += samples[idx * 2].a; // 2 : idx
346 }
347 if (weight > 0.0) {
348 weight = 1.0 / weight;
349 color = samples[0] * CORE_BLUR_WEIGHTS[0] * weight;
350 for (int idx = 1; idx < CORE_BLUR_FILTER_SIZE; ++idx) {
351 color += samples[idx * 2 - 1] * CORE_BLUR_WEIGHTS[idx] * weight; // 2 : idx
352 color += samples[idx * 2] * CORE_BLUR_WEIGHTS[idx] * weight; // 2 : idx
353 }
354 } else {
355 color = samples[0];
356 }
357
358 return color;
359 }
360
SoftDownscaleRGBLayer(texture2DArray tex,sampler sampl,const vec2 fragCoord,const vec2 uv,const vec3 dirLayer,const vec2 invTexSize)361 vec3 SoftDownscaleRGBLayer(
362 texture2DArray tex, sampler sampl, const vec2 fragCoord, const vec2 uv, const vec3 dirLayer, const vec2 invTexSize)
363 {
364 #if (CORE_BLUR_SOFT_HEAVY_SAMPLES == 1)
365
366 // first, 9 samples (calculate coefficients)
367 const float diagCoeff = (1.0f / 32.0f); // 32.0 : param
368 const float stepCoeff = (2.0f / 32.0f); // 2.0 , 32.0 : param
369 const float centerCoeff = (4.0f / 32.0f); // 4.0, 32.0 : param
370
371 const vec2 ts = invTexSize;
372
373 vec3 color = textureLod(sampler2DArray(tex, sampl), vec3(uv.x - ts.x, uv.y - ts.y, dirLayer.z), 0).xyz * diagCoeff;
374 color += textureLod(sampler2DArray(tex, sampl), vec3(uv.x, uv.y - ts.y, dirLayer.z), 0).xyz * stepCoeff;
375 color += textureLod(sampler2DArray(tex, sampl), vec3(uv.x + ts.x, uv.y - ts.y, dirLayer.z), 0).xyz * diagCoeff;
376
377 color += textureLod(sampler2DArray(tex, sampl), vec3(uv.x - ts.x, uv.y, dirLayer.z), 0).xyz * stepCoeff;
378 color += textureLod(sampler2DArray(tex, sampl), vec3(uv.x, uv.y, dirLayer.z), 0).xyz * centerCoeff;
379 color += textureLod(sampler2DArray(tex, sampl), vec3(uv.x + ts.x, uv.y, dirLayer.z), 0).xyz * stepCoeff;
380
381 color += textureLod(sampler2DArray(tex, sampl), vec3(uv.x - ts.x, uv.y + ts.y, dirLayer.z), 0).xyz * diagCoeff;
382 color += textureLod(sampler2DArray(tex, sampl), vec3(uv.x, uv.y + ts.y, dirLayer.z), 0).xyz * centerCoeff;
383 color += textureLod(sampler2DArray(tex, sampl), vec3(uv.x + ts.x, uv.y + ts.y, dirLayer.z), 0).xyz * diagCoeff;
384
385 // then center square
386 const vec2 ths = ts * 0.5; // half
387
388 color += textureLod(sampler2DArray(tex, sampl), vec3(uv.x - ths.x, uv.y - ths.y, dirLayer.z), 0).xyz * centerCoeff;
389 color += textureLod(sampler2DArray(tex, sampl), vec3(uv.x + ths.x, uv.y - ths.y, dirLayer.z), 0).xyz * centerCoeff;
390 color += textureLod(sampler2DArray(tex, sampl), vec3(uv.x - ths.x, uv.y + ths.y, dirLayer.z), 0).xyz * centerCoeff;
391 color += textureLod(sampler2DArray(tex, sampl), vec3(uv.x + ths.x, uv.y + ths.y, dirLayer.z), 0).xyz * centerCoeff;
392
393 #else
394
395 const vec2 ths = invTexSize * 0.5; // 0.5 : half
396
397 // center
398 vec3 color = textureLod(sampler2DArray(tex, sampl), vec3(uv + ths, dirLayer.z), 0).xyz * 0.5; // 0.5 : half
399 // corners
400 color = textureLod(sampler2DArray(tex, sampl), vec3(uv - ths, dirLayer.z), 0).xyz * 0.125 + color; // 0.125 : param
401 color = textureLod(sampler2DArray(tex, sampl), vec3(uv.x + ths.x, uv.y - ths.y, dirLayer.z), 0).xyz *
402 0.125 + color; // 0.125 : param
403 color = textureLod(sampler2DArray(tex, sampl), vec3(uv.x - ths.x, uv.y + ths.y, dirLayer.z), 0).xyz *
404 0.125 + color; // 0.125 : param
405 color = textureLod(sampler2DArray(tex, sampl), vec3(uv + ths, dirLayer.z), 0).xyz * 0.125 + color; // 0.125 : param
406
407 #endif
408
409 return color;
410 }
411
DownscaleRGBALayer(texture2DArray tex,sampler sampl,const vec2 fragCoord,const vec2 uv,const vec3 dirLayer,const vec2 invTexSize)412 vec4 DownscaleRGBALayer(
413 texture2DArray tex, sampler sampl, const vec2 fragCoord, const vec2 uv, const vec3 dirLayer, const vec2 invTexSize)
414 {
415 return textureLod(sampler2DArray(tex, sampl), vec3(uv, dirLayer.z), 0);
416 }
417 #endif
418
419 #endif // API_RENDER_SHADERS_COMMON_CORE_BLUR_COMMON_H
420