• 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 CORE3D_RENDER__NODE__RENDER_LIGHT_HELPER_H
17 #define CORE3D_RENDER__NODE__RENDER_LIGHT_HELPER_H
18 
19 // NOTE: do not include this helper file in header
20 
21 #include <algorithm>
22 
23 #include <3d/namespace.h>
24 #include <3d/render/intf_render_data_store_default_light.h>
25 
CORE3D_BEGIN_NAMESPACE()26 CORE3D_BEGIN_NAMESPACE()
27 class RenderLightHelper final {
28 public:
29     RenderLightHelper() = default;
30     ~RenderLightHelper() = default;
31 
32     // offset to DefaultMaterialSingleLightStruct
33     static constexpr uint32_t LIGHT_LIST_OFFSET { 16u * 6u };
34 
35     static constexpr bool ENABLE_CLUSTERED_LIGHTING { false };
36 
37     struct LightCounts {
38         uint32_t directionalLightCount { 0u };
39         uint32_t pointLightCount { 0u };
40         uint32_t spotLightCount { 0u };
41     };
42 
43     static BASE_NS::Math::Vec4 GetShadowAtlasSizeInvSize(const IRenderDataStoreDefaultLight& dsLight)
44     {
45         const BASE_NS::Math::UVec2 shadowQualityRes = dsLight.GetShadowQualityResolution();
46         const uint32_t shadowCount = dsLight.GetLightCounts().shadowCount;
47         BASE_NS::Math::Vec2 size = { float(shadowQualityRes.x * shadowCount), float(shadowQualityRes.y) };
48         size.x = BASE_NS::Math::max(1.0f, size.x);
49         size.y = BASE_NS::Math::max(1.0f, size.y);
50         return { size.x, size.y, 1.0f / size.x, 1.0f / size.y };
51     }
52 
53     struct SortData {
54         RenderLight::LightUsageFlags lightUsageFlags { 0u };
55         uint32_t index { 0u };
56     };
57 
58     static BASE_NS::vector<SortData> SortLights(
59         const BASE_NS::array_view<const RenderLight> lights, const uint32_t lightCount, const uint32_t sceneId)
60     {
61         BASE_NS::vector<SortData> sortedFlags(lightCount);
62         uint32_t outIdx = 0U;
63         for (uint32_t inIdx = 0U; inIdx < lightCount; ++inIdx) {
64             if (lights[inIdx].sceneId != sceneId) {
65                 continue;
66             }
67             sortedFlags[outIdx].lightUsageFlags = lights[inIdx].lightUsageFlags;
68             sortedFlags[outIdx].index = inIdx;
69             ++outIdx;
70         }
71         sortedFlags.resize(outIdx);
72         std::sort(sortedFlags.begin(), sortedFlags.end(), [](const auto& lhs, const auto& rhs) {
73             return ((lhs.lightUsageFlags & 0x7u) < (rhs.lightUsageFlags & 0x7u));
74         });
75         return sortedFlags;
76     }
77 
78     static void CopySingleLight(
79         const RenderLight& currLight, const uint32_t shadowCount, DefaultMaterialSingleLightStruct* memLight)
80     {
81         const float shadowStepSize = 1.0f / BASE_NS::Math::max(1.0f, static_cast<float>(shadowCount));
82         const BASE_NS::Math::Vec4 pos = currLight.pos;
83         const BASE_NS::Math::Vec4 dir = currLight.dir;
84         memLight->pos = pos;
85         memLight->dir = dir;
86         constexpr float epsilonForMinDivisor { 0.0001f };
87         memLight->dir.w = BASE_NS::Math::max(epsilonForMinDivisor, currLight.range);
88         memLight->color =
89             BASE_NS::Math::Vec4(BASE_NS::Math::Vec3(currLight.color) * currLight.color.w, currLight.color.w);
90         memLight->spotLightParams = currLight.spotLightParams;
91         memLight->shadowFactors = { currLight.shadowFactors.x, currLight.shadowFactors.y, currLight.shadowFactors.z,
92             shadowStepSize };
93         memLight->flags = { currLight.lightUsageFlags, currLight.shadowCameraIndex, currLight.shadowIndex,
94             shadowCount };
95         memLight->indices = { static_cast<uint32_t>(currLight.id >> 32U),
96             static_cast<uint32_t>(currLight.id & 0xFFFFffff), static_cast<uint32_t>(currLight.layerMask >> 32U),
97             static_cast<uint32_t>(currLight.layerMask & 0xFFFFffff) };
98     }
99 };
100 CORE3D_END_NAMESPACE()
101 
102 #endif // CORE3D_RENDER__NODE__RENDER_LIGHT_HELPER_H
103