载入中...
搜索中...
未找到
AmbientOcclusion.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/ao_ssao_frag_spv.inc"
10#include "graphics/shaders/ao_hbao_frag_spv.inc"
11#include "graphics/shaders/ao_gtao_frag_spv.inc"
12#include "graphics/shaders/ao_blur_frag_spv.inc"
13#include "graphics/shaders/ao_overlay_frag_spv.inc"
14#include "graphics/shaders/ao_from_depth_frag_spv.inc"
16
17#include <algorithm>
18#include <cmath>
19#include <cstdint>
20#include <vector>
21
22#include <glm/gtc/matrix_transform.hpp>
23
24namespace eve::graphics {
25namespace {
26
27Shader *newAoShader(Graphics *gfx, const std::vector<uint32_t> &frag, const char *wgsl) {
28 if (gfx->getBackendName() == "webgpu")
29 return gfx->newShaderFromWgsl({}, std::string(shaders::kAoCommon) + wgsl);
30 return gfx->newShaderFromSpv({}, frag);
31}
32
33void declareComputeCommon(Shader *sh, bool horizonStyle) {
34 sh->declareMatrix("invViewProj");
35 sh->declareFloat("nearZ");
36 sh->declareFloat("farZ");
37 sh->declareFloat("radius");
38 sh->declareFloat("bias");
39 sh->declareFloat("intensity");
40 sh->declareFloat("power");
41 if (horizonStyle) {
42 sh->declareFloat("dirCount");
43 sh->declareFloat("stepCount");
44 } else {
45 sh->declareFloat("sampleCount");
46 }
47 sh->declareFloat("texelW");
48 sh->declareFloat("texelH");
49}
50
51Shader *createSsaoShader(Graphics *gfx) {
52 if (!gfx) throw eve::Exception("AmbientOcclusion: null graphics");
53 std::vector<uint32_t> frag(ao_ssao_frag_spv, ao_ssao_frag_spv + ao_ssao_frag_spv_count);
54 Shader *sh = newAoShader(gfx, frag, shaders::kSsao);
55 declareComputeCommon(sh, false);
56 sh->sendMatrix("invViewProj", glm::mat4(1.f));
57 sh->sendFloat("nearZ", 0.1f);
58 sh->sendFloat("farZ", 100.f);
59 sh->sendFloat("radius", 0.75f);
60 sh->sendFloat("bias", 0.025f);
61 sh->sendFloat("intensity", 1.f);
62 sh->sendFloat("power", 1.5f);
63 sh->sendFloat("sampleCount", 16.f);
64 sh->sendFloat("texelW", 1.f / 256.f);
65 sh->sendFloat("texelH", 1.f / 256.f);
66 return sh;
67}
68
69Shader *createHbaoShader(Graphics *gfx) {
70 if (!gfx) throw eve::Exception("AmbientOcclusion: null graphics");
71 std::vector<uint32_t> frag(ao_hbao_frag_spv, ao_hbao_frag_spv + ao_hbao_frag_spv_count);
72 Shader *sh = newAoShader(gfx, frag, shaders::kHbao);
73 declareComputeCommon(sh, true);
74 sh->sendMatrix("invViewProj", glm::mat4(1.f));
75 sh->sendFloat("nearZ", 0.1f);
76 sh->sendFloat("farZ", 100.f);
77 sh->sendFloat("radius", 0.75f);
78 sh->sendFloat("bias", 0.025f);
79 sh->sendFloat("intensity", 1.f);
80 sh->sendFloat("power", 1.5f);
81 sh->sendFloat("dirCount", 6.f);
82 sh->sendFloat("stepCount", 6.f);
83 sh->sendFloat("texelW", 1.f / 256.f);
84 sh->sendFloat("texelH", 1.f / 256.f);
85 return sh;
86}
87
88Shader *createGtaoShader(Graphics *gfx) {
89 if (!gfx) throw eve::Exception("AmbientOcclusion: null graphics");
90 std::vector<uint32_t> frag(ao_gtao_frag_spv, ao_gtao_frag_spv + ao_gtao_frag_spv_count);
91 Shader *sh = newAoShader(gfx, frag, shaders::kGtao);
92 declareComputeCommon(sh, true);
93 sh->declareFloat("thickness");
94 sh->sendMatrix("invViewProj", glm::mat4(1.f));
95 sh->sendFloat("nearZ", 0.1f);
96 sh->sendFloat("farZ", 100.f);
97 sh->sendFloat("radius", 0.75f);
98 sh->sendFloat("bias", 0.025f);
99 sh->sendFloat("intensity", 1.f);
100 sh->sendFloat("power", 1.5f);
101 sh->sendFloat("dirCount", 6.f);
102 sh->sendFloat("stepCount", 6.f);
103 sh->sendFloat("texelW", 1.f / 256.f);
104 sh->sendFloat("texelH", 1.f / 256.f);
105 sh->sendFloat("thickness", 0.5f);
106 return sh;
107}
108
109Shader *createBlurShader(Graphics *gfx) {
110 if (!gfx) throw eve::Exception("AmbientOcclusion: null graphics");
111 std::vector<uint32_t> frag(ao_blur_frag_spv, ao_blur_frag_spv + ao_blur_frag_spv_count);
112 Shader *sh = newAoShader(gfx, frag, shaders::kBlur);
113 sh->declareFloat("texelW");
114 sh->declareFloat("texelH");
115 sh->declareFloat("depthSigma");
116 sh->declareFloat("spatialKernel");
117 sh->sendFloat("texelW", 1.f / 256.f);
118 sh->sendFloat("texelH", 1.f / 256.f);
119 sh->sendFloat("depthSigma", 0.05f);
120 sh->sendFloat("spatialKernel", 2.f);
121 return sh;
122}
123
124Shader *createOverlayShader(Graphics *gfx) {
125 if (!gfx) throw eve::Exception("AmbientOcclusion: null graphics");
126 std::vector<uint32_t> frag(ao_overlay_frag_spv, ao_overlay_frag_spv + ao_overlay_frag_spv_count);
127 Shader *sh = newAoShader(gfx, frag, shaders::kOverlay);
128 sh->declareFloat("intensity");
129 sh->declareFloat("power");
130 sh->sendFloat("intensity", 1.f);
131 sh->sendFloat("power", 1.f);
132 return sh;
133}
134
135Shader *createFromDepthShader(Graphics *gfx) {
136 if (!gfx) throw eve::Exception("AmbientOcclusion: null graphics");
137 std::vector<uint32_t> frag(ao_from_depth_frag_spv,
138 ao_from_depth_frag_spv + ao_from_depth_frag_spv_count);
139 Shader *sh = newAoShader(gfx, frag, shaders::kFromDepth);
140 if (!sh || !sh->gpuHandle)
141 throw eve::Exception("AmbientOcclusion: failed to create from-depth shader");
142 declareComputeCommon(sh, false);
143 sh->sendMatrix("invViewProj", glm::mat4(1.f));
144 sh->sendFloat("nearZ", 0.1f);
145 sh->sendFloat("farZ", 100.f);
146 sh->sendFloat("radius", 0.75f);
147 sh->sendFloat("bias", 0.025f);
148 sh->sendFloat("intensity", 0.55f);
149 sh->sendFloat("power", 1.35f);
150 sh->sendFloat("sampleCount", 16.f);
151 sh->sendFloat("texelW", 1.f / 256.f);
152 sh->sendFloat("texelH", 1.f / 256.f);
153 sh->declareFloat("hasNormal");
154 sh->sendFloat("hasNormal", 0.f);
155 return sh;
156}
157
158} // namespace
159
161 ssaoShader_ = createSsaoShader(gfx);
162 hbaoShader_ = createHbaoShader(gfx);
163 gtaoShader_ = createGtaoShader(gfx);
164 blurShader_ = createBlurShader(gfx);
165 overlayShader_ = createOverlayShader(gfx);
166 fromDepthShader_ = createFromDepthShader(gfx);
167 applyQualityDefaults();
168}
169
171
172Shader *AmbientOcclusion::activeComputeShader() const {
173 if (mode_ == "hbao") return hbaoShader_;
174 if (mode_ == "gtao") return gtaoShader_;
175 return ssaoShader_;
176}
177
178Shader *AmbientOcclusion::getShader() const { return activeComputeShader(); }
179
180void AmbientOcclusion::applyQualityDefaults() {
181 if (quality_ == "low") {
182 downscale_ = 4.f;
183 radius_ = 0.55f;
184 if (mode_ == "hbao" || mode_ == "gtao") {
185 setFloat("dirCount", 4.f);
186 setFloat("stepCount", 4.f);
187 } else {
188 setFloat("sampleCount", 8.f);
189 }
190 } else if (quality_ == "high") {
191 downscale_ = 1.f;
192 radius_ = 1.f;
193 if (mode_ == "hbao" || mode_ == "gtao") {
194 setFloat("dirCount", 8.f);
195 setFloat("stepCount", 8.f);
196 } else {
197 setFloat("sampleCount", 24.f);
198 }
199 } else {
200 quality_ = "medium";
201 downscale_ = 2.f;
202 radius_ = 0.75f;
203 if (mode_ == "hbao" || mode_ == "gtao") {
204 setFloat("dirCount", 6.f);
205 setFloat("stepCount", 6.f);
206 } else {
207 setFloat("sampleCount", 16.f);
208 }
209 }
210 setRadius(radius_);
211 setBias(bias_);
212 setIntensity(intensity_);
213 setPower(power_);
214 setThickness(thickness_);
215}
216
217void AmbientOcclusion::setQuality(const std::string &quality) {
218 quality_ = quality;
219 applyQualityDefaults();
220}
221
222void AmbientOcclusion::setMode(const std::string &mode) {
223 if (mode == "hbao")
224 mode_ = "hbao";
225 else if (mode == "gtao")
226 mode_ = "gtao";
227 else
228 mode_ = "ssao";
229 applyQualityDefaults();
230}
231
233 invViewProj_ = invViewProj;
234 ssaoShader_->sendMatrix("invViewProj", invViewProj_);
235 hbaoShader_->sendMatrix("invViewProj", invViewProj_);
236 gtaoShader_->sendMatrix("invViewProj", invViewProj_);
237 if (fromDepthShader_) fromDepthShader_->sendMatrix("invViewProj", invViewProj_);
238}
239
240void AmbientOcclusion::setCamera(float eyeX, float eyeY, float eyeZ, float targetX, float targetY,
241 float targetZ, float upX, float upY, float upZ, float fovYDeg,
242 float aspect, float nearZ, float farZ) {
243 nearZ_ = nearZ > 1e-4f ? nearZ : 0.1f;
244 farZ_ = farZ > nearZ_ ? farZ : nearZ_ + 1.f;
245 const float aspectSafe = aspect > 1e-4f ? aspect : 1.f;
246 const float fovRad = fovYDeg * 0.017453292519943295f;
247 const glm::mat4 view =
248 glm::lookAtRH(glm::vec3(eyeX, eyeY, eyeZ), glm::vec3(targetX, targetY, targetZ),
249 glm::vec3(upX, upY, upZ));
250 const glm::mat4 proj = perspectiveVulkanRH_ZO(fovRad, aspectSafe, nearZ_, farZ_);
251 setInvViewProj(glm::inverse(proj * view));
252 ssaoShader_->sendFloat("nearZ", nearZ_);
253 ssaoShader_->sendFloat("farZ", farZ_);
254 hbaoShader_->sendFloat("nearZ", nearZ_);
255 hbaoShader_->sendFloat("farZ", farZ_);
256 gtaoShader_->sendFloat("nearZ", nearZ_);
257 gtaoShader_->sendFloat("farZ", farZ_);
258 if (fromDepthShader_) {
259 fromDepthShader_->sendFloat("nearZ", nearZ_);
260 fromDepthShader_->sendFloat("farZ", farZ_);
261 }
262}
263
265 radius_ = radius > 1e-4f ? radius : 1e-4f;
266 setFloat("radius", radius_);
267}
268
270 bias_ = bias < 0.f ? 0.f : bias;
271 setFloat("bias", bias_);
272}
273
274void AmbientOcclusion::setIntensity(float intensity) {
275 intensity_ = intensity < 0.f ? 0.f : intensity;
276 setFloat("intensity", intensity_);
277 if (overlayShader_) overlayShader_->sendFloat("intensity", intensity_);
278}
279
281 power_ = power < 0.01f ? 0.01f : power;
282 setFloat("power", power_);
283}
284
286 thickness_ = thickness < 0.f ? 0.f : thickness;
287 if (gtaoShader_ && gtaoShader_->hasUniform("thickness"))
288 gtaoShader_->sendFloat("thickness", thickness_);
289}
290
291float AmbientOcclusion::getRadius() const { return radius_; }
292float AmbientOcclusion::getBias() const { return bias_; }
293float AmbientOcclusion::getIntensity() const { return intensity_; }
294float AmbientOcclusion::getPower() const { return power_; }
295
296bool AmbientOcclusion::hasParam(const std::string &name) const {
297 return (ssaoShader_ && ssaoShader_->hasUniform(name)) ||
298 (hbaoShader_ && hbaoShader_->hasUniform(name)) ||
299 (gtaoShader_ && gtaoShader_->hasUniform(name)) ||
300 (blurShader_ && blurShader_->hasUniform(name)) ||
301 (overlayShader_ && overlayShader_->hasUniform(name));
302}
303
304void AmbientOcclusion::setFloat(const std::string &name, float value) {
305 if (ssaoShader_ && ssaoShader_->hasUniform(name)) ssaoShader_->sendFloat(name, value);
306 if (hbaoShader_ && hbaoShader_->hasUniform(name)) hbaoShader_->sendFloat(name, value);
307 if (gtaoShader_ && gtaoShader_->hasUniform(name)) gtaoShader_->sendFloat(name, value);
308 if (blurShader_ && blurShader_->hasUniform(name)) blurShader_->sendFloat(name, value);
309 if (overlayShader_ && overlayShader_->hasUniform(name)) overlayShader_->sendFloat(name, value);
310 if (fromDepthShader_ && fromDepthShader_->hasUniform(name)) fromDepthShader_->sendFloat(name, value);
311}
312
313float AmbientOcclusion::getFloat(const std::string &name) const {
314 Shader *active = activeComputeShader();
315 if (active && active->hasUniform(name)) {
316 float v = 0.f;
317 if (active->getFromVar(name, &v, sizeof(v)) == int(sizeof(v))) return v;
318 }
319 if (blurShader_ && blurShader_->hasUniform(name)) {
320 float v = 0.f;
321 if (blurShader_->getFromVar(name, &v, sizeof(v)) == int(sizeof(v))) return v;
322 }
323 if (overlayShader_ && overlayShader_->hasUniform(name)) {
324 float v = 0.f;
325 if (overlayShader_->getFromVar(name, &v, sizeof(v)) == int(sizeof(v))) return v;
326 }
327 // Fall back across compute shaders.
328 for (Shader *sh : {ssaoShader_, hbaoShader_, gtaoShader_}) {
329 if (sh && sh->hasUniform(name)) {
330 float v = 0.f;
331 if (sh->getFromVar(name, &v, sizeof(v)) == int(sizeof(v))) return v;
332 }
333 }
334 throw eve::Exception("AmbientOcclusion.getFloat: missing param '%s'", name.c_str());
335}
336
338 if (mode_ == "hbao" || mode_ == "gtao") {
339 const int dirs = int(std::lround(getFloat("dirCount")));
340 const int steps = int(std::lround(getFloat("stepCount")));
341 return dirs * steps;
342 }
343 return int(std::lround(getFloat("sampleCount")));
344}
345
346int AmbientOcclusion::resolutionFor(int fullSize) const {
347 if (fullSize < 1) return 1;
348 const float ds = std::max(downscale_, 1.f);
349 return std::max(1, int(std::floor(float(fullSize) / ds)));
350}
351
352void AmbientOcclusion::uploadComputeCommon(Shader *shader, int width, int height) {
353 if (!shader) throw eve::Exception("AmbientOcclusion: null compute shader");
354 if (width < 1) width = 1;
355 if (height < 1) height = 1;
356 shader->sendMatrix("invViewProj", invViewProj_);
357 shader->sendFloat("nearZ", nearZ_);
358 shader->sendFloat("farZ", farZ_);
359 shader->sendFloat("radius", radius_);
360 shader->sendFloat("bias", bias_);
361 shader->sendFloat("intensity", intensity_);
362 shader->sendFloat("power", power_);
363 shader->sendFloat("texelW", 1.f / float(width));
364 shader->sendFloat("texelH", 1.f / float(height));
365 if (shader->hasUniform("thickness")) shader->sendFloat("thickness", thickness_);
366}
367
368void AmbientOcclusion::drawFullscreen(Graphics *gfx, Texture *source, Shader *shader) {
369 if (!gfx) throw eve::Exception("AmbientOcclusion: null graphics");
370 if (!source) throw eve::Exception("AmbientOcclusion: null source texture");
371 if (!shader) throw eve::Exception("AmbientOcclusion: null shader");
372 const float dw = gfx->getCanvas() ? float(gfx->getCanvas()->getWidth()) : float(gfx->getWidth());
373 const float dh =
374 gfx->getCanvas() ? float(gfx->getCanvas()->getHeight()) : float(gfx->getHeight());
375 gfx->drawTexturedRectShader(source, shader, 0.f, 0.f, dw, dh, Color(1.f, 1.f, 1.f, 1.f));
376}
377
379 if (!linearDepth) throw eve::Exception("AmbientOcclusion.compute: null depth");
380 Shader *sh = activeComputeShader();
381 uploadComputeCommon(sh, linearDepth->getWidth(), linearDepth->getHeight());
382 drawFullscreen(gfx, linearDepth, sh);
383}
384
385void AmbientOcclusion::computeTo(Graphics *gfx, Texture *linearDepth, Canvas *dest) {
386 if (!gfx) throw eve::Exception("AmbientOcclusion.computeTo: null graphics");
387 if (!dest) throw eve::Exception("AmbientOcclusion.computeTo: null dest");
388 Canvas *prev = gfx->getCanvas();
389 gfx->setCanvas(dest);
390 compute(gfx, linearDepth);
391 gfx->setCanvas(prev);
392}
393
395 if (!aoMap) throw eve::Exception("AmbientOcclusion.blur: null aoMap");
396 blurShader_->sendFloat("texelW", 1.f / float(std::max(aoMap->getWidth(), 1)));
397 blurShader_->sendFloat("texelH", 1.f / float(std::max(aoMap->getHeight(), 1)));
398 drawFullscreen(gfx, aoMap, blurShader_);
399}
400
402 if (!gfx) throw eve::Exception("AmbientOcclusion.blurTo: null graphics");
403 if (!dest) throw eve::Exception("AmbientOcclusion.blurTo: null dest");
404 Canvas *prev = gfx->getCanvas();
405 gfx->setCanvas(dest);
406 blur(gfx, aoMap);
407 gfx->setCanvas(prev);
408}
409
411 if (!aoMap) throw eve::Exception("AmbientOcclusion.applyOverlay: null aoMap");
412 overlayShader_->sendFloat("intensity", intensity_);
413 // Overlay uses power=1 by default so compute-pass power is not double-applied.
414 if (!overlayShader_->hasUniform("power")) {
415 // unreachable — declared at create
416 }
417 overlayShader_->sendFloat("power", 1.f);
418 drawFullscreen(gfx, aoMap, overlayShader_);
419}
420
422 if (!gfx) throw eve::Exception("AmbientOcclusion.applyOverlayTo: null graphics");
423 if (!dest) throw eve::Exception("AmbientOcclusion.applyOverlayTo: null dest");
424 Canvas *prev = gfx->getCanvas();
425 gfx->setCanvas(dest);
426 applyOverlay(gfx, aoMap);
427 gfx->setCanvas(prev);
428}
429
431 applyFromGBuffer(gfx, hwDepth, nullptr);
432}
433
434void AmbientOcclusion::applyFromGBuffer(Graphics *gfx, Texture *hwDepth, Texture *worldNormal) {
435 if (!gfx) throw eve::Exception("AmbientOcclusion.applyFromGBuffer: null graphics");
436 if (!hwDepth) throw eve::Exception("AmbientOcclusion.applyFromGBuffer: null hwDepth");
437 if (!fromDepthShader_) throw eve::Exception("AmbientOcclusion.applyFromGBuffer: missing shader");
438 fromDepthShader_->sendFloat("hasNormal", worldNormal ? 1.f : 0.f);
439 uploadComputeCommon(fromDepthShader_, hwDepth->getWidth(), hwDepth->getHeight());
440 if (worldNormal) {
441 const float dw =
442 gfx->getCanvas() ? float(gfx->getCanvas()->getWidth()) : float(gfx->getWidth());
443 const float dh =
444 gfx->getCanvas() ? float(gfx->getCanvas()->getHeight()) : float(gfx->getHeight());
445 gfx->drawTexturedRectShaderDepth(hwDepth, worldNormal, fromDepthShader_, 0.f, 0.f, dw, dh,
446 Color(1.f, 1.f, 1.f, 1.f));
447 } else {
448 drawFullscreen(gfx, hwDepth, fromDepthShader_);
449 }
450}
451
453 if (!gfx) throw eve::Exception("AmbientOcclusion.applyFromDepthTo: null graphics");
454 if (!dest) throw eve::Exception("AmbientOcclusion.applyFromDepthTo: null dest");
455 Canvas *prev = gfx->getCanvas();
456 gfx->setCanvas(dest);
457 applyFromDepth(gfx, linearDepth);
458 gfx->setCanvas(prev);
459}
460
462 float (*depth01)(int x, int y, void *userdata),
463 void *userdata) {
464 if (!gfx) throw eve::Exception("AmbientOcclusion.newLinearDepthTexture: null graphics");
465 if (width < 1 || height < 1)
466 throw eve::Exception("AmbientOcclusion.newLinearDepthTexture: invalid size");
467 if (!depth01) throw eve::Exception("AmbientOcclusion.newLinearDepthTexture: null depth fn");
468 std::vector<uint8_t> rgba(size_t(width) * size_t(height) * 4);
469 for (int y = 0; y < height; ++y) {
470 for (int x = 0; x < width; ++x) {
471 float d = depth01(x, y, userdata);
472 if (d < 0.f) d = 0.f;
473 if (d > 1.f) d = 1.f;
474 const uint8_t b = uint8_t(std::lround(d * 255.f));
475 const size_t i = size_t(y * width + x) * 4;
476 rgba[i + 0] = b;
477 rgba[i + 1] = b;
478 rgba[i + 2] = b;
479 rgba[i + 3] = 255;
480 }
481 }
482 return gfx->newTexture(width, height, rgba.data());
483}
484
485} // namespace eve::graphics
double value
bool & active
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float thickness
Definition CaveMesh.cpp:83
vk::ShaderModule frag
float v
std::uint32_t height
std::uint32_t width
std::string name
MeleePoint3 b
Definition MeleeHit.cpp:41
OnnxCompute * compute
float radius
float d
int steps
float fovRad
Shader * shader
glm::mat4 view
glm::mat4 proj
float power
Definition RockMesh.cpp:23
float bias
float targetX
const UnitySourceAsset & source
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
void setBias(float bias)
Sets the bias.
void applyFromDepthTo(Graphics *gfx, Texture *linearDepth, Canvas *dest)
Applies from depth to.
void applyFromDepth(Graphics *gfx, Texture *hwDepth)
One-pass SSAO overlay for the 3D swapchain path. Samples hardware D32 (Vulkan NDC z in ....
int resolutionFor(int fullSize) const
Downscale helper: returns floor(dim / downscale), at least 1. Callers create AO canvases at this size...
void setIntensity(float intensity)
Sets the intensity.
void setFloat(const std::string &name, float value)
Sets the float.
void computeTo(Graphics *gfx, Texture *linearDepth, Canvas *dest)
Computes to.
AmbientOcclusion(Graphics *gfx)
Ambient occlusion.
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 compute*.
void setMode(const std::string &mode)
"ssao" | "hbao" | "gtao".
float getPower() const
Returns the power.
void blurTo(Graphics *gfx, Texture *aoMap, Canvas *dest)
Blur to.
void setInvViewProj(const glm::mat4 &invViewProj)
Sets the inv view proj.
bool hasParam(const std::string &name) const
True when param.
void setPower(float power)
Sets the power.
void applyFromGBuffer(Graphics *gfx, Texture *hwDepth, Texture *worldNormal)
Applies from g buffer.
void setThickness(float thickness)
Sets the thickness.
Shader * getShader() const
Returns the shader.
float getBias() const
Returns the bias.
Texture * newLinearDepthTexture(Graphics *gfx, int width, int height, float(*depth01)(int x, int y, void *userdata), void *userdata)
Build an RGBA8 texture with linear depth in R (G=B=R, A=255). Owned by Graphics (same convention as V...
~AmbientOcclusion()
Ambient occlusion.
float getFloat(const std::string &name) const
Returns the float.
float getRadius() const
Returns the radius.
void setQuality(const std::string &quality)
"low" | "medium" | "high" (unknown → medium).
float getIntensity() const
Returns the intensity.
int getSampleCount() const
Returns the sample count.
void compute(Graphics *gfx, Texture *linearDepth)
Compute AO into the currently bound canvas / screen. Output RGB = AO (1=open), A = depth01.
void blur(Graphics *gfx, Texture *aoMap)
Bilateral blur of an AO map (RGB=AO, A=depth).
void applyOverlayTo(Graphics *gfx, Texture *aoMap, Canvas *dest)
Applies overlay to.
void applyOverlay(Graphics *gfx, Texture *aoMap)
Darken the current target with AO: black + alpha=(1-ao)*intensity. Draw over an already-rendered scen...
void setRadius(float radius)
Sets the radius.
Canvas public API.
Definition Canvas.h:17
virtual int getWidth() const =0
Returns the width.
virtual int getHeight() const =0
Returns the height.
int getWidth() const
Returns the width.
Definition Graphics.h:502
virtual Canvas * getCanvas() const =0
Returns the canvas.
virtual Texture * newTexture(int width, int height, const uint8_t *rgba, bool repeatU=false, bool repeatV=false)=0
Creates a texture. @ownership Caller deletes unless documented otherwise.
virtual void setCanvas(Canvas *canvas)=0
nullptr or this → screen. Switching flushes pending draws to the previous target.
int getHeight() const
Returns the height.
Definition Graphics.h:504
virtual void drawTexturedRectShaderDepth(Texture *color, Texture *depth, Shader *shader, float x, float y, float w, float h, const Color &tint)=0
Fullscreen/post draw sampling color at binding 0 and depth at binding 1 (hardware D32,...
Custom GPU program.
Definition Shader.h:39
bool hasUniform(const std::string &name) const
Definition Shader.cpp:59
void sendFloat(const std::string &name, float x)
Definition Shader.cpp:95
void sendMatrix(const std::string &name, const glm::mat4 &m)
Definition Shader.cpp:112
int getFromVar(const std::string &name, void *data, size_t size) const
Definition Shader.cpp:84
GPU texture created via Graphics::newTexture. Owns GPU resources through an opaque backend handle.
Definition Texture.h:18
int getWidth() const
Returns the width.
Definition Texture.cpp:28
int getHeight() const
Returns the height.
Definition Texture.cpp:33
constexpr const char * kSsao
constexpr const char * kOverlay
constexpr const char * kBlur
constexpr const char * kGtao
constexpr const char * kAoCommon
constexpr const char * kHbao
constexpr const char * kFromDepth
卡牌游戏 UI 工具模块:工厂 + 脚本绑定入口。 功能参考 ycarowr/UiCard:扇形手牌布局、抽牌/洗牌、悬浮放大、拖拽到落牌区、 敌方手牌(背面/偷看)、费用不足置灰,以及可实时调节的布局...
Definition Animation.h:25
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:22
eve::Color Color
RGBA color used by every graphics draw call. Lives inside eve::graphics so including a graphics heade...
Definition Color.h:13
glm::mat4 invViewProj