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 // match with core/base color conversions
26
27 // No conversion and should be used as default
28 #define CORE_COLOR_CONVERSION_TYPE_NONE 0
29 // sRGB to linear conversion
30 #define CORE_COLOR_CONVERSION_TYPE_SRGB_TO_LINEAR 1
31 // Linear to sRGB conversion
32 #define CORE_COLOR_CONVERSION_TYPE_LINEAR_TO_SRGB 2
33
34 /**
35 * Calculate luma.
36 */
CalcLuma(const vec3 color)37 float CalcLuma(const vec3 color)
38 {
39 // Rec. 601 luma
40 return 0.299 * color.r + 0.587 * color.g + 0.114 * color.b; // 0.299: param 0.587: param 0.114: param
41 }
42
43 /**
44 * Calculate simplified luma.
45 */
CalcLumaFxaa(const vec3 color)46 float CalcLumaFxaa(const vec3 color)
47 {
48 // Rec. 601 luma based approximation
49 return color.g * (0.587 / 0.299) + color.r; // 0.587: param 0.299: param
50 }
51
52 /**
53 * Luma weight.
54 */
LumaWeight(const float luma)55 float LumaWeight(const float luma)
56 {
57 return (1.0 / (1.0 + luma));
58 }
59
60 /**
61 * Tonemap based on luma.
62 */
TonemapLuma(const vec3 color,const float luma,const float range)63 vec3 TonemapLuma(const vec3 color, const float luma, const float range)
64 {
65 return color / (1.0 + luma / range);
66 }
67
68 /**
69 * Inverse tonemap based on luma.
70 */
TonemapLumaInv(const vec3 color,const float luma,const float range)71 vec3 TonemapLumaInv(const vec3 color, const float luma, const float range)
72 {
73 return color / (1.0 - luma / range);
74 }
75
76 /**
77 * Convert sRGB to linear RGB.
78 * https://en.wikipedia.org/wiki/SRGB
79 */
SrgbToLinear(const vec3 srgb)80 vec3 SrgbToLinear(const vec3 srgb)
81 {
82 const float mlow = 1.0f / 12.92f;
83 const float mhigh = 1.0f / 1.055f;
84
85 const vec3 high = pow((srgb + 0.055f) * mhigh, vec3(2.4f));
86 const vec3 low = srgb * mlow;
87 const bvec3 cutoff = lessThan(srgb, vec3(0.04045f));
88 return mix(high, low, cutoff);
89 }
90
91 /**
92 * Convert linear RGB to sRGB.
93 * https://en.wikipedia.org/wiki/SRGB
94 */
LinearToSrgb(const vec3 linear)95 vec3 LinearToSrgb(const vec3 linear)
96 {
97 const float mlow = 12.92f;
98 const float mhigh = 1.055f;
99
100 const vec3 high = pow(linear, vec3(0.416f)) * mhigh - 0.055f;
101 const vec3 low = linear * mlow;
102 const bvec3 cutoff = lessThan(linear, vec3(0.0031308f));
103 return mix(high, low, cutoff);
104 }
105
106 /**
107 * Convert RGB to YCoCg.
108 * https://en.wikipedia.org/wiki/YCoCg
109 */
rgbToYCoCg(const vec3 rgb)110 vec3 rgbToYCoCg(const vec3 rgb)
111 {
112 const float y = dot(rgb, vec3(0.25, 0.5, 0.25));
113 const float co = dot(rgb, vec3(0.5, 0.0, -0.5));
114 const float cg = dot(rgb, vec3(-0.25, 0.5, -0.25));
115 return vec3(y, co, cg);
116 }
117
118 /**
119 * Convert YCoCg to RGB
120 * https://en.wikipedia.org/wiki/YCoCg
121 */
yCoCgToRgb(const vec3 ycocg)122 vec3 yCoCgToRgb(const vec3 ycocg)
123 {
124 const float y = ycocg.r;
125 const float co = ycocg.g;
126 const float cg = ycocg.b;
127 return vec3(y + co - cg, y + cg, y - co - cg);
128 }
129
130 #endif // API_RENDER_SHADERS_COMMON_CORE_COLOR_CONVERSION_COMMON_H
131