载入中...
搜索中...
未找到
GlobalIllumination.cpp
浏览该文件的文档.
2
3#include "common/Exception.h"
4#include "graphics/Canvas.h"
6#include "graphics/Graphics.h"
7#include "graphics/Shader.h"
8#include "graphics/Texture.h"
9#include "graphics/shaders/gi_ssgi_frag_spv.inc"
10
11#include <algorithm>
12#include <cmath>
13#include <cstdint>
14#include <vector>
15
16#include <glm/glm.hpp>
17#include <glm/gtc/matrix_transform.hpp>
18
19namespace eve::graphics {
20namespace {
21
22Shader *createSsgiShader(Graphics *gfx) {
23 if (!gfx) throw eve::Exception("GlobalIllumination: null graphics");
24 std::vector<uint32_t> frag(gi_ssgi_frag_spv, gi_ssgi_frag_spv + gi_ssgi_frag_spv_count);
25 Shader *sh = gfx->newShaderFromSpv({}, frag);
26 if (!sh || !sh->gpuHandle) throw eve::Exception("GlobalIllumination: failed to create SSGI shader");
27 sh->declareMatrix("invViewProj");
28 sh->declareFloat("nearZ");
29 sh->declareFloat("farZ");
30 sh->declareFloat("radius");
31 sh->declareFloat("intensity");
32 sh->declareFloat("sampleCount");
33 sh->declareFloat("lightDirX");
34 sh->declareFloat("lightDirY");
35 sh->declareFloat("lightDirZ");
36 sh->declareFloat("lightR");
37 sh->declareFloat("lightG");
38 sh->declareFloat("lightB");
39 sh->declareFloat("texelW");
40 sh->declareFloat("texelH");
41 sh->declareFloat("useNdcDepth");
42 sh->sendMatrix("invViewProj", glm::mat4(1.f));
43 sh->sendFloat("nearZ", 0.1f);
44 sh->sendFloat("farZ", 100.f);
45 sh->sendFloat("radius", 1.25f);
46 sh->sendFloat("intensity", 0.45f);
47 sh->sendFloat("sampleCount", 12.f);
48 sh->sendFloat("lightDirX", 0.4f);
49 sh->sendFloat("lightDirY", 1.f);
50 sh->sendFloat("lightDirZ", 0.3f);
51 sh->sendFloat("lightR", 1.f);
52 sh->sendFloat("lightG", 1.f);
53 sh->sendFloat("lightB", 1.f);
54 sh->sendFloat("texelW", 1.f / 256.f);
55 sh->sendFloat("texelH", 1.f / 256.f);
56 sh->sendFloat("useNdcDepth", 0.f);
57 return sh;
58}
59
60} // namespace
61
63 ssgi_ = createSsgiShader(gfx);
64 applyQualityDefaults();
65}
66
68
69void GlobalIllumination::applyQualityDefaults() {
70 if (quality_ == "low") {
71 radius_ = 0.9f;
72 setFloat("sampleCount", 8.f);
73 } else if (quality_ == "high") {
74 radius_ = 1.6f;
75 setFloat("sampleCount", 24.f);
76 } else {
77 radius_ = 1.25f;
78 setFloat("sampleCount", 16.f);
79 }
80 setFloat("radius", radius_);
81 setFloat("intensity", intensity_);
82}
83
84void GlobalIllumination::setQuality(const std::string &quality) {
85 if (quality == "low" || quality == "medium" || quality == "high")
86 quality_ = quality;
87 else
88 quality_ = "medium";
89 applyQualityDefaults();
90}
91
92void GlobalIllumination::setInvViewProj(const glm::mat4 &invViewProj) {
93 invViewProj_ = invViewProj;
94 ssgi_->sendMatrix("invViewProj", invViewProj_);
95}
96
97void GlobalIllumination::setCamera(float eyeX, float eyeY, float eyeZ, float targetX, float targetY,
98 float targetZ, float upX, float upY, float upZ, float fovYDeg,
99 float aspect, float nearZ, float farZ) {
100 nearZ_ = nearZ > 1e-4f ? nearZ : 0.1f;
101 farZ_ = farZ > nearZ_ ? farZ : nearZ_ + 1.f;
102 const float aspectSafe = aspect > 1e-4f ? aspect : 1.f;
103 const float fovRad = fovYDeg * 0.017453292519943295f;
104 const glm::mat4 view =
105 glm::lookAtRH(glm::vec3(eyeX, eyeY, eyeZ), glm::vec3(targetX, targetY, targetZ),
106 glm::vec3(upX, upY, upZ));
107 const glm::mat4 proj = perspectiveVulkanRH_ZO(fovRad, aspectSafe, nearZ_, farZ_);
108 setInvViewProj(glm::inverse(proj * view));
109 ssgi_->sendFloat("nearZ", nearZ_);
110 ssgi_->sendFloat("farZ", farZ_);
111}
112
114 radius_ = radius > 1e-4f ? radius : 1e-4f;
115 setFloat("radius", radius_);
116}
117
118void GlobalIllumination::setIntensity(float intensity) {
119 intensity_ = std::max(intensity, 0.f);
120 setFloat("intensity", intensity_);
121}
122
123void GlobalIllumination::setLightDirection(float dx, float dy, float dz) {
124 glm::vec3 d(dx, dy, dz);
125 if (glm::length(d) < 1e-6f) d = glm::vec3(0.f, 1.f, 0.f);
126 else d = glm::normalize(d);
127 lightDir_ = d;
128 ssgi_->sendFloat("lightDirX", lightDir_.x);
129 ssgi_->sendFloat("lightDirY", lightDir_.y);
130 ssgi_->sendFloat("lightDirZ", lightDir_.z);
131}
132
133void GlobalIllumination::setLightColor(float r, float g, float b) {
134 lightColor_ = glm::vec3(std::max(r, 0.f), std::max(g, 0.f), std::max(b, 0.f));
135 ssgi_->sendFloat("lightR", lightColor_.x);
136 ssgi_->sendFloat("lightG", lightColor_.y);
137 ssgi_->sendFloat("lightB", lightColor_.z);
138}
139
140bool GlobalIllumination::hasParam(const std::string &name) const {
141 return ssgi_ && ssgi_->hasUniform(name);
142}
143
144void GlobalIllumination::setFloat(const std::string &name, float value) {
145 if (!ssgi_ || !ssgi_->hasUniform(name))
146 throw eve::Exception("GlobalIllumination.setFloat: missing param '%s'", name.c_str());
147 ssgi_->sendFloat(name, value);
148 if (name == "radius") radius_ = value;
149 if (name == "intensity") intensity_ = value;
150}
151
152float GlobalIllumination::getFloat(const std::string &name) const {
153 if (!ssgi_ || !ssgi_->hasUniform(name))
154 throw eve::Exception("GlobalIllumination.getFloat: missing param '%s'", name.c_str());
155 float v = 0.f;
156 if (ssgi_->getFromVar(name, &v, sizeof(v)) == int(sizeof(v))) return v;
157 throw eve::Exception("GlobalIllumination.getFloat: missing param '%s'", name.c_str());
158}
159
161 return int(std::lround(getFloat("sampleCount")));
162}
163
164void GlobalIllumination::uploadUniforms(int width, int height) {
165 if (width < 1) width = 1;
166 if (height < 1) height = 1;
167 ssgi_->sendMatrix("invViewProj", invViewProj_);
168 ssgi_->sendFloat("nearZ", nearZ_);
169 ssgi_->sendFloat("farZ", farZ_);
170 ssgi_->sendFloat("radius", radius_);
171 ssgi_->sendFloat("intensity", intensity_);
172 ssgi_->sendFloat("lightDirX", lightDir_.x);
173 ssgi_->sendFloat("lightDirY", lightDir_.y);
174 ssgi_->sendFloat("lightDirZ", lightDir_.z);
175 ssgi_->sendFloat("lightR", lightColor_.x);
176 ssgi_->sendFloat("lightG", lightColor_.y);
177 ssgi_->sendFloat("lightB", lightColor_.z);
178 ssgi_->sendFloat("texelW", 1.f / float(width));
179 ssgi_->sendFloat("texelH", 1.f / float(height));
180}
181
182void GlobalIllumination::drawFullscreen(Graphics *gfx, Texture *source, Shader *shader,
183 Texture *hwDepth) {
184 if (!gfx) throw eve::Exception("GlobalIllumination: null graphics");
185 if (!source) throw eve::Exception("GlobalIllumination: null source texture");
186 if (!shader) throw eve::Exception("GlobalIllumination: null shader");
187 const float dw = gfx->getCanvas() ? float(gfx->getCanvas()->getWidth()) : float(gfx->getWidth());
188 const float dh =
189 gfx->getCanvas() ? float(gfx->getCanvas()->getHeight()) : float(gfx->getHeight());
190 if (hwDepth)
191 gfx->drawTexturedRectShaderDepth(source, hwDepth, shader, 0.f, 0.f, dw, dh,
192 Color(1.f, 1.f, 1.f, 1.f));
193 else
194 gfx->drawTexturedRectShader(source, shader, 0.f, 0.f, dw, dh, Color(1.f, 1.f, 1.f, 1.f));
195}
196
198 if (!packedAlbedo) throw eve::Exception("GlobalIllumination.applyFromDepth: null packedAlbedo");
199 ssgi_->sendFloat("useNdcDepth", 0.f);
200 uploadUniforms(packedAlbedo->getWidth(), packedAlbedo->getHeight());
201 drawFullscreen(gfx, packedAlbedo, ssgi_, nullptr);
202}
203
205 if (!color) throw eve::Exception("GlobalIllumination.applyFromScene: null color");
206 if (!hwDepth) throw eve::Exception("GlobalIllumination.applyFromScene: null hwDepth");
207 ssgi_->sendFloat("useNdcDepth", 1.f);
208 uploadUniforms(color->getWidth(), color->getHeight());
209 drawFullscreen(gfx, color, ssgi_, hwDepth);
210}
211
213 if (!gfx) throw eve::Exception("GlobalIllumination.applyFromDepthTo: null graphics");
214 if (!dest) throw eve::Exception("GlobalIllumination.applyFromDepthTo: null dest");
215 Canvas *prev = gfx->getCanvas();
216 gfx->setCanvas(dest);
217 applyFromDepth(gfx, packedAlbedo);
218 gfx->setCanvas(prev == gfx ? nullptr : prev);
219}
220
221} // namespace eve::graphics
std::string value
vk::ShaderModule frag
float height
Definition Grass.cpp:235
uint32_t b
int width
float fovRad
Shader * shader
glm::mat4 view
glm::mat4 proj
const char * name
Definition RockMesh.cpp:21
int d
int v
image::ImageData::Colorf color
void applyFromDepth(Graphics *gfx, Texture *packedAlbedo)
Overlay bounced light onto the currently bound canvas / screen. Packed path (tests): RGB=albedo/lit,...
void applyFromScene(Graphics *gfx, Texture *color, Texture *hwDepth)
bool hasParam(const std::string &name) const
void setLightDirection(float dx, float dy, float dz)
void setQuality(const std::string &quality)
"low" | "medium" | "high" (unknown → medium).
void setCamera(float eyeX, float eyeY, float eyeZ, float targetX, float targetY, float targetZ, float upX, float upY, float upZ, float fovYDeg, float aspect, float nearZ, float farZ)
Camera for depth reconstruction (RH + ZO). Builds inv(viewProj) and near/far used by applyFromDepth.
void setFloat(const std::string &name, float value)
void setInvViewProj(const glm::mat4 &invViewProj)
void setLightColor(float r, float g, float b)
void applyFromDepthTo(Graphics *gfx, Texture *packedAlbedo, Canvas *dest)
float getFloat(const std::string &name) const
virtual Canvas * getCanvas() const =0
virtual void setCanvas(Canvas *canvas)=0
nullptr or this → screen. Switching flushes pending draws to the previous target.
bool hasUniform(const std::string &name) const
Definition Shader.cpp:46
void sendFloat(const std::string &name, float x)
Definition Shader.cpp:82
void sendMatrix(const std::string &name, const glm::mat4 &m)
Definition Shader.cpp:99
int getFromVar(const std::string &name, void *data, size_t size) const
Definition Shader.cpp:71
GPU texture created via Graphics::newTexture. Owns GPU resources through an opaque backend handle.
Definition Texture.h:17
int getWidth() const
Definition Texture.h:26
int getHeight() const
Definition Texture.h:27
卡牌游戏 UI 工具模块:工厂 + 脚本绑定入口。 功能参考 ycarowr/UiCard:扇形手牌布局、抽牌/洗牌、悬浮放大、拖拽到落牌区、 敌方手牌(背面/偷看)、费用不足置灰,以及可实时调节的布局...
Definition AnimTrail.h:6
glm::mat4 perspectiveVulkanRH_ZO(float fovyRad, float aspect, float zNear, float zFar)
Right-handed, zero-to-one depth perspective for Vulkan swapchains.
Definition ClipSpace.h:20
glm::vec4 Color
RGBA color used by every graphics draw call. Lives inside eve::graphics so including a graphics heade...
Definition Color.h:13