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_POST_PROCESS_BLOCKS_H
17 #define API_RENDER_SHADERS_COMMON_POST_PROCESS_BLOCKS_H
18
19 #include "render_color_conversion_common.h"
20 #include "render_post_process_structs_common.h"
21 #include "render_tonemap_common.h"
22
23 #define CORE_CLAMP_MAX_VALUE 64512.0
24
25 /**
26 * returns tonemapped color
27 */
PostProcessTonemapBlock(in uint postProcessFlags,in vec4 tonemapFactor,in vec3 inCol,out vec3 outCol)28 void PostProcessTonemapBlock(in uint postProcessFlags, in vec4 tonemapFactor, in vec3 inCol, out vec3 outCol)
29 {
30 outCol = inCol;
31 if ((postProcessFlags & POST_PROCESS_SPECIALIZATION_TONEMAP_BIT) == POST_PROCESS_SPECIALIZATION_TONEMAP_BIT) {
32 const float exposure = tonemapFactor.x;
33 const vec3 x = outCol * exposure;
34 const uint tonemapType = uint(tonemapFactor.w);
35 if (tonemapType == CORE_POST_PROCESS_TONEMAP_ACES) {
36 outCol = TonemapAces(x);
37 } else if (tonemapType == CORE_POST_PROCESS_TONEMAP_ACES_2020) {
38 outCol = TonemapAcesFilmRec2020(x);
39 } else if (tonemapType == CORE_POST_PROCESS_TONEMAP_FILMIC) {
40 const float exposureEstimate = 6.0f;
41 outCol = TonemapFilmic(x * exposureEstimate);
42 }
43 }
44 }
45
46 /**
47 * returns vignette applied color with vignette values in the range 0-1
48 */
PostProcessVignetteBlock(in uint postProcessFlags,in vec4 vignetteFactor,in vec2 uv,in vec3 inCol,out vec3 outCol)49 void PostProcessVignetteBlock(
50 in uint postProcessFlags, in vec4 vignetteFactor, in vec2 uv, in vec3 inCol, out vec3 outCol)
51 {
52 outCol = inCol;
53 if ((postProcessFlags & POST_PROCESS_SPECIALIZATION_VIGNETTE_BIT) == POST_PROCESS_SPECIALIZATION_VIGNETTE_BIT) {
54 const vec2 uvVal = uv.xy * (vec2(1.0) - uv.yx);
55 CORE_RELAXEDP float vignette = uvVal.x * uvVal.y * vignetteFactor.x * 40.0;
56 vignette = clamp(pow(vignette, vignetteFactor.y), 0.0, 1.0);
57 outCol.rgb *= vignette;
58 }
59 }
60
61 /**
62 * returns chroma applied color with two additional samples, coefficient in the range 0-1
63 */
PostProcessColorFringeBlock(in uint postProcessFlags,in vec4 chromaFactor,in vec2 uv,in vec2 uvSize,in sampler2D imgSampler,in vec3 inCol,out vec3 outCol)64 void PostProcessColorFringeBlock(in uint postProcessFlags, in vec4 chromaFactor, in vec2 uv, in vec2 uvSize,
65 in sampler2D imgSampler, in vec3 inCol, out vec3 outCol)
66 {
67 outCol = inCol;
68 if ((postProcessFlags & POST_PROCESS_SPECIALIZATION_COLOR_FRINGE_BIT) ==
69 POST_PROCESS_SPECIALIZATION_COLOR_FRINGE_BIT) {
70 // this is cheap chroma
71 const vec2 distUv = (uv - 0.5) * 2.0;
72 const CORE_RELAXEDP float chroma = dot(distUv, distUv) * chromaFactor.y * chromaFactor.x;
73
74 const vec2 uvDistToImageCenter = chroma * uvSize;
75 const CORE_RELAXEDP float chromaRed =
76 textureLod(imgSampler, uv - vec2(uvDistToImageCenter.x, uvDistToImageCenter.y), 0).x;
77 const CORE_RELAXEDP float chromaBlue =
78 textureLod(imgSampler, uv + vec2(uvDistToImageCenter.x, uvDistToImageCenter.y), 0).z;
79
80 outCol.r = chromaRed;
81 outCol.b = chromaBlue;
82 }
83 }
84
85 /**
86 * returns dithered color
87 */
PostProcessDitherBlock(in uint postProcessFlags,in vec4 ditherFactor,in vec2 uv,in vec3 inCol,out vec3 outCol)88 void PostProcessDitherBlock(in uint postProcessFlags, in vec4 ditherFactor, in vec2 uv, in vec3 inCol, out vec3 outCol)
89 {
90 outCol = inCol;
91 if ((postProcessFlags & POST_PROCESS_SPECIALIZATION_DITHER_BIT) == POST_PROCESS_SPECIALIZATION_DITHER_BIT) {
92 const vec2 random01Range = vec2(uv.x * ditherFactor.y, uv.y * ditherFactor.z);
93 outCol += fract(sin(dot(random01Range.xy, vec2(12.9898, 78.233))) * 43758.5453) * ditherFactor.x;
94 }
95 }
96
97 /**
98 * returns additional color conversion
99 */
PostProcessColorConversionBlock(in uint postProcessFlags,in vec4 colorConversionFactor,in vec3 inCol,out vec3 outCol)100 void PostProcessColorConversionBlock(
101 in uint postProcessFlags, in vec4 colorConversionFactor, in vec3 inCol, out vec3 outCol)
102 {
103 outCol = inCol;
104 if ((postProcessFlags & POST_PROCESS_SPECIALIZATION_COLOR_CONVERSION_BIT) ==
105 POST_PROCESS_SPECIALIZATION_COLOR_CONVERSION_BIT) {
106 const uint conversionType = uint(colorConversionFactor.w);
107 if (conversionType == CORE_POST_PROCESS_COLOR_CONVERSION_SRGB) {
108 outCol.rgb = LinearToSrgb(outCol.rgb);
109 }
110 }
111 }
112
113 /**
114 * returns bloom combine
115 */
PostProcessBloomCombineBlock(in uint postProcessFlags,in vec4 bloomFactor,in vec2 uv,in sampler2D imgSampler,in sampler2D dirtImgSampler,in vec3 inCol,out vec3 outCol)116 void PostProcessBloomCombineBlock(in uint postProcessFlags, in vec4 bloomFactor, in vec2 uv, in sampler2D imgSampler,
117 in sampler2D dirtImgSampler, in vec3 inCol, out vec3 outCol)
118 {
119 outCol = inCol;
120 if ((postProcessFlags & POST_PROCESS_SPECIALIZATION_BLOOM_BIT) == POST_PROCESS_SPECIALIZATION_BLOOM_BIT) {
121 // NOTE: lower resolution, more samples might be needed
122 const vec3 bloomColor = textureLod(imgSampler, uv, 0).rgb * bloomFactor.z;
123 const vec3 dirtColor = textureLod(dirtImgSampler, uv, 0).rgb * bloomFactor.w;
124 const vec3 bloomCombine = outCol + bloomColor + dirtColor * max(bloomColor.x, max(bloomColor.y, bloomColor.z));
125 outCol.rgb = min(bloomCombine, CORE_CLAMP_MAX_VALUE);
126 }
127 }
128
129 #endif // API_RENDER_SHADERS_COMMON_POST_PROCESS_BLOCKS_H
130