载入中...
搜索中...
未找到
ClusteredLight.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <cmath>
5#include <vector>
6
7namespace eve::graphics {
8
9ClusteredLightingUpload buildClusteredLighting(const std::vector<ClusteredLightGpu> &points,
10 const std::vector<ClusteredLightGpu> &dirs,
11 const glm::mat4 &view, float nearZ, float farZ,
12 int screenW, int screenH, float fovYRad,
13 const glm::vec4 &ambient) {
15 out.ambient = ambient;
16 out.view = view;
17 out.clipInfo = glm::vec4(nearZ, farZ, float(std::max(screenW, 1)), float(std::max(screenH, 1)));
18 out.gridInfo = glm::vec4(float(ClusteredLightConfig::kTilesX), float(ClusteredLightConfig::kTilesY),
20
21 if (!dirs.empty()) {
22 glm::vec3 d(dirs[0].posRadius);
23 if (glm::length(d) < 1e-6f) d = glm::vec3(0.f, 1.f, 0.f);
24 else d = glm::normalize(d);
25 out.primaryDir = glm::vec4(d, 1.f);
26 out.primaryColor = dirs[0].color;
27 } else {
28 out.primaryDir = glm::vec4(0.f, 1.f, 0.f, 0.f);
29 out.primaryColor = glm::vec4(0.f);
30 }
31
32 const int maxPts = std::min(int(points.size()), ClusteredLightConfig::kMaxLights);
33 out.lights.assign(points.begin(), points.begin() + maxPts);
34 out.gridInfo.w = float(out.lights.size());
35
37 out.clusterTable.assign(size_t(C), ClusterTableEntry{});
38 auto perCluster = std::vector<std::vector<uint32_t>>(size_t(C));
39 for (auto &v : perCluster) v.reserve(4);
40
41 const float nx = nearZ;
42 const float fx = std::max(farZ, nearZ + 1e-3f);
43 const float tanHalfFov = std::tan(std::max(fovYRad, 1e-3f) * 0.5f);
44 const float aspect = out.clipInfo.z / std::max(out.clipInfo.w, 1.f);
45
46 for (uint32_t li = 0; li < uint32_t(out.lights.size()); ++li) {
47 const auto &L = out.lights[li];
48 const glm::vec3 worldPos(L.posRadius);
49 const float radius = std::max(L.posRadius.w, 0.01f);
50 const glm::vec4 vp = view * glm::vec4(worldPos, 1.f);
51 const glm::vec3 viewPos(vp);
52 const float zCenter = -viewPos.z; // positive depth in front of camera (RH)
53 const float z0 = zCenter - radius;
54 const float z1 = zCenter + radius;
55 if (z1 < nx || z0 > fx) continue;
56
57 const float zMin = std::max(z0, nx);
58 const float zMax = std::min(z1, fx);
59 const int slice0 = std::clamp(
60 int(std::floor((zMin - nx) / (fx - nx) * float(ClusteredLightConfig::kSlices))), 0,
62 const int slice1 = std::clamp(
63 int(std::floor((zMax - nx) / (fx - nx) * float(ClusteredLightConfig::kSlices))), 0,
65
66 const float depth = std::max(zCenter, nx);
67 const float halfH = depth * tanHalfFov;
68 const float halfW = halfH * aspect;
69
70 auto toTileX = [&](float x) {
71 float u = (x + halfW) / std::max(2.f * halfW, 1e-3f);
72 return std::clamp(int(std::floor(u * float(ClusteredLightConfig::kTilesX))), 0,
74 };
75 auto toTileY = [&](float y) {
76 float v = 1.f - (y + halfH) / std::max(2.f * halfH, 1e-3f);
77 return std::clamp(int(std::floor(v * float(ClusteredLightConfig::kTilesY))), 0,
79 };
80
81 const int tx0 = toTileX(viewPos.x - radius);
82 const int tx1 = toTileX(viewPos.x + radius);
83 const int tyA = toTileY(viewPos.y - radius);
84 const int tyB = toTileY(viewPos.y + radius);
85 const int ty0 = std::min(tyA, tyB);
86 const int ty1 = std::max(tyA, tyB);
87
88 for (int sz = slice0; sz <= slice1; ++sz) {
89 for (int ty = ty0; ty <= ty1; ++ty) {
90 for (int tx = tx0; tx <= tx1; ++tx) {
91 const int cid =
93 perCluster[size_t(cid)].push_back(li);
94 }
95 }
96 }
97 }
98
99 out.lightIndices.clear();
100 out.lightIndices.reserve(size_t(C) * 4);
101 for (int ci = 0; ci < C; ++ci) {
102 auto &list = perCluster[size_t(ci)];
103 if (list.size() > size_t(ClusteredLightConfig::kMaxLightsPerCluster)) {
104 std::stable_sort(list.begin(), list.end(), [&](uint32_t a, uint32_t b) {
105 const float ia = glm::length(glm::vec3(out.lights[a].color));
106 const float ib = glm::length(glm::vec3(out.lights[b].color));
107 return ia > ib;
108 });
110 }
111 out.clusterTable[size_t(ci)].offset = uint32_t(out.lightIndices.size());
112 out.clusterTable[size_t(ci)].count = uint32_t(list.size());
113 out.lightIndices.insert(out.lightIndices.end(), list.begin(), list.end());
114 }
115 if (out.lightIndices.empty()) out.lightIndices.push_back(0);
116 out.active = true;
117 return out;
118}
119
120} // namespace eve::graphics
int y
Definition Grass.cpp:135
float u
Definition Grass.cpp:234
int x
Definition Grass.cpp:135
float depth
uint32_t a
uint32_t b
glm::mat4 view
int d
int v
std::vector< V3 > points
Definition TreeMesh.cpp:126
卡牌游戏 UI 工具模块:工厂 + 脚本绑定入口。 功能参考 ycarowr/UiCard:扇形手牌布局、抽牌/洗牌、悬浮放大、拖拽到落牌区、 敌方手牌(背面/偷看)、费用不足置灰,以及可实时调节的布局...
Definition AnimTrail.h:6
ClusteredLightingUpload buildClusteredLighting(const std::vector< ClusteredLightGpu > &points, const std::vector< ClusteredLightGpu > &dirs, const glm::mat4 &view, float nearZ, float farZ, int screenW, int screenH, float fovYRad, const glm::vec4 &ambient)
Build clustered tables for point lights in view space.
static constexpr int kMaxLightsPerCluster
CPU-built clustered lighting upload for one frame/camera. Point lights are clustered; directional lig...