• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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_TONEMAP_COMMON_H
17 #define API_RENDER_SHADERS_COMMON_TONEMAP_COMMON_H
18 
19 #include "render_post_process_common.h"
20 
21 /*
22 Aces tonemapping.
23 https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
24 */
TonemapAces(vec3 x)25 vec3 TonemapAces(vec3 x)
26 {
27     const float a = 2.51f;
28     const float b = 0.03f;
29     const float c = 2.43f;
30     const float d = 0.59f;
31     const float e = 0.14f;
32     return (x * (a * x + b)) / (x * (c * x + d) + e);
33 }
34 
35 /*
36 Aces film rec 2020 tonemapping.
37 https://knarkowicz.wordpress.com/2016/08/31/hdr-display-first-steps/
38 */
TonemapAcesFilmRec2020(vec3 x)39 vec3 TonemapAcesFilmRec2020(vec3 x)
40 {
41     float a = 15.8f;
42     float b = 2.12f;
43     float c = 1.2f;
44     float d = 5.92f;
45     float e = 1.9f;
46     return (x * (a * x + b)) / (x * (c * x + d) + e);
47 }
48 
49 /*
50 Filmic tonemapping.
51 // http://filmicgames.com/archives/75
52 */
TonemapFilmic(float x)53 float TonemapFilmic(float x)
54 {
55     const float a = 0.15f;
56     const float b = 0.50f;
57     const float c = 0.10f;
58     const float d = 0.20f;
59     const float e = 0.02f;
60     const float f = 0.30f;
61     return ((x * (a * x + c * b) + d * e) / (x * (a * x + b) + d * f)) - e / f;
62 }
TonemapFilmic(vec3 x)63 vec3 TonemapFilmic(vec3 x)
64 {
65     const float a = 0.15f;
66     const float b = 0.50f;
67     const float c = 0.10f;
68     const float d = 0.20f;
69     const float e = 0.02f;
70     const float f = 0.30f;
71     const float w = 11.2f;
72     const vec3 curr = ((x * (a * x + c * b) + d * e) / (x * (a * x + b) + d * f)) - e / f;
73     const float whiteScale = 1.0 / TonemapFilmic(w);
74     return curr * vec3(whiteScale);
75 }
76 
77 /*
78 PBR Neutral tonemapping.
79 https://github.com/KhronosGroup/ToneMapping
80 Input color is non-negative and resides in the Linear Rec. 709 color space.
81 Output color is also Linear Rec. 709, but in the [0, 1] range.
82 */
TonemapPbrNeutral(vec3 color)83 vec3 TonemapPbrNeutral(vec3 color)
84 {
85     const float startCompression = 0.8 - 0.04;
86     const float desaturation = 0.15;
87 
88     float x = min(color.r, min(color.g, color.b));
89     float offset = x < 0.08 ? x - 6.25 * x * x : 0.04;
90     color -= offset;
91 
92     float peak = max(color.r, max(color.g, color.b));
93     if (peak < startCompression)
94         return color;
95 
96     const float d = 1. - startCompression;
97     float newPeak = 1. - d * d / (peak + d - startCompression);
98     color *= newPeak / peak;
99 
100     float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.);
101     return mix(color, vec3(newPeak), g);
102 }
103 
104 #endif // API_RENDER_SHADERS_COMMON_TONEMAP_COMMON_H
105