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_COLOR_CONVERSION_COMMON_H
17 #define API_RENDER_SHADERS_COMMON_CORE_COLOR_CONVERSION_COMMON_H
18 
19 #ifndef VULKAN
20 #error "This is inteded to be included in shaders. Not fully ported to C/C++."
21 #endif
22 
23 #include "render_compatibility_common.h"
24 
25 /**
26  * Calculate luma.
27  */
CalcLuma(const vec3 color)28 float CalcLuma(const vec3 color)
29 {
30     // Rec. 601 luma
31     return 0.299 * color.r + 0.587 * color.g + 0.114 * color.b;
32 }
33 
34 /**
35  * Calculate simplified luma.
36  */
CalcLumaFxaa(const vec3 color)37 float CalcLumaFxaa(const vec3 color)
38 {
39     // Rec. 601 luma based approximation
40     return color.g * (0.587 / 0.299) + color.r;
41 }
42 
43 /**
44  * Luma weight.
45  */
LumaWeight(const float luma)46 float LumaWeight(const float luma)
47 {
48     return (1.0 / (1.0 + luma));
49 }
50 
51 /**
52  * Tonemap based on luma.
53  */
TonemapLuma(const vec3 color,const float luma,const float range)54 vec3 TonemapLuma(const vec3 color, const float luma, const float range)
55 {
56     return color / (1.0 + luma / range);
57 }
58 
59 /**
60  * Inverse tonemap based on luma.
61  */
TonemapLumaInv(const vec3 color,const float luma,const float range)62 vec3 TonemapLumaInv(const vec3 color, const float luma, const float range)
63 {
64     return color / (1.0 - luma / range);
65 }
66 
67 /**
68  * Convert sRGB to linear RGB.
69  * https://en.wikipedia.org/wiki/SRGB
70  */
SrgbToLinear(const vec3 srgb)71 vec3 SrgbToLinear(const vec3 srgb)
72 {
73     const float mlow = 1.0f / 12.92f;
74     const float mhigh = 1.0f / 1.055f;
75 
76     const vec3 high = pow((srgb + 0.055f) * mhigh, vec3(2.4f));
77     const vec3 low = srgb * mlow;
78     const bvec3 cutoff = lessThan(srgb, vec3(0.04045f));
79     return mix(high, low, cutoff);
80 }
81 
82 /**
83  * Convert linear RGB to sRGB.
84  * https://en.wikipedia.org/wiki/SRGB
85  */
LinearToSrgb(const vec3 linear)86 vec3 LinearToSrgb(const vec3 linear)
87 {
88     const float mlow = 12.92f;
89     const float mhigh = 1.055f;
90 
91     const vec3 high = pow(linear, vec3(0.416f)) * mhigh - 0.055f;
92     const vec3 low = linear * mlow;
93     const bvec3 cutoff = lessThan(linear, vec3(0.0031308f));
94     return mix(high, low, cutoff);
95 }
96 
97 /**
98  * Convert RGB to YCoCg.
99  * https://en.wikipedia.org/wiki/YCoCg
100  */
rgbToYCoCg(const vec3 rgb)101 vec3 rgbToYCoCg(const vec3 rgb)
102 {
103     const float y = dot(rgb, vec3(0.25, 0.5, 0.25));
104     const float co = dot(rgb, vec3(0.5, 0.0, -0.5));
105     const float cg = dot(rgb, vec3(-0.25, 0.5, -0.25));
106     return vec3(y, co, cg);
107 }
108 
109 /**
110  * Convert YCoCg to RGB
111  * https://en.wikipedia.org/wiki/YCoCg
112  */
yCoCgToRgb(const vec3 ycocg)113 vec3 yCoCgToRgb(const vec3 ycocg)
114 {
115     const float y = ycocg.r;
116     const float co = ycocg.g;
117     const float cg = ycocg.b;
118     return vec3(y + co - cg, y + cg, y - co - cg);
119 }
120 
121 #endif // API_RENDER_SHADERS_COMMON_CORE_COLOR_CONVERSION_COMMON_H
122