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 SHADERS__COMMON__3D_DM_INDIRECT_LIGHTING_COMMON_H
17 #define SHADERS__COMMON__3D_DM_INDIRECT_LIGHTING_COMMON_H
18
19 #include "3d/shaders/common/3d_dm_structures_common.h"
20 #include "render/shaders/common/render_compatibility_common.h"
21
22 #ifdef VULKAN
23
24 #define CORE3D_BRDF_PI 3.14159265359
25 // Avoid divisions by 0 on devices that do not support denormals (from Filament documentation)
26 #define CORE3D_BRDF_MIN_ROUGHNESS 0.089
27 #define CORE3D_HDR_FLOAT_CLAMP_MAX_VALUE 64512.0
28 #define CORE3D_PBR_LIGHTING_EPSILON 0.0001
29
30 /*
31 Unpack environment color.
32 */
33 // RGBD or just RGB -> ALPHA = 1.0
unpackEnvMap(vec4 envColorRgbd)34 vec3 unpackEnvMap(vec4 envColorRgbd)
35 {
36 return envColorRgbd.xyz * (1.0 / envColorRgbd.a);
37 }
38
39 // RGBD or just RGB -> ALPHA = 1.0
unpackIblRadiance(vec4 envColorRgbd)40 vec3 unpackIblRadiance(vec4 envColorRgbd)
41 {
42 return envColorRgbd.xyz * (1.0 / envColorRgbd.a);
43 }
44
45 // build-in (1.0 / PI)
unpackIblIrradianceSH(vec3 n,vec4 sh[CORE_DEFAULT_MATERIAL_MAX_SH_VEC3_VALUE_COUNT])46 vec3 unpackIblIrradianceSH(vec3 n, vec4 sh[CORE_DEFAULT_MATERIAL_MAX_SH_VEC3_VALUE_COUNT])
47 {
48 // use 3 bands spherical harmonics
49 return max(vec3(0.0), sh[0].xyz
50
51 + sh[1].xyz * n.y + sh[2].xyz * n.z + sh[3].xyz * n.x
52
53 + sh[4].xyz * (n.x * n.y) + sh[5].xyz * (n.z * n.y) +
54 sh[6].xyz * ((3.0 * n.z * n.z) - 1.0) + sh[7].xyz * (n.x * n.z) +
55 sh[8].xyz * (n.x * n.x - n.y * n.y));
56 }
57
58 // https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile
59 // alpha taken into account
EnvBRDFApprox(vec3 f0,float roughness,float NoV)60 vec3 EnvBRDFApprox(vec3 f0, float roughness, float NoV)
61 {
62 const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
63 const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);
64 vec4 r = roughness * c0 + c1;
65 float a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;
66 vec2 ab = vec2(-1.04, 1.04) * a004 + r.zw;
67 // f0 has baked transparency, ab.y needs to take alpha into account
68 // 2% f0, takes into account alpha
69 const float f90 = clamp(50.0 * max(f0.x, max(f0.y, f0.z)), 0.0, 1.0);
70 return f0 * ab.x + ab.y * f90;
71 }
72
73 // https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile
74 // Approximation of EnvBRDFApprox for non metallic (diaelectric) materials with reflectance value of 0.04
EnvBRDFApproxNonmetal(float Roughness,float NoV)75 float EnvBRDFApproxNonmetal(float Roughness, float NoV)
76 {
77 // Same as EnvBRDFApprox( 0.04, Roughness, NoV )
78 const vec2 c0 = { -1, -0.0275 };
79 const vec2 c1 = { 1, 0.0425 };
80 vec2 r = Roughness * c0 + c1;
81 return min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y; // 9.28 : param
82 }
83
84 #endif // VULKAN
85
86 #endif // SHADERS__COMMON__3D_DM_INDIRECT_LIGHTING_COMMON_H
87