载入中...
搜索中...
未找到
DepthPyramid.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <string>
5#include <vector>
6
7#include "common/Exception.h"
9#include "graphics/Canvas.h"
10#include "graphics/Color.h"
11#include "graphics/Graphics.h"
12#include "graphics/Shader.h"
13#include "graphics/Texture.h"
15#include "graphics/shaders/depth_pyramid_downsample_frag_spv.inc"
16
17namespace eve::graphics {
18namespace {
19
20std::vector<uint32_t> copySpv(const uint32_t *data, size_t count) {
21 return std::vector<uint32_t>(data, data + count);
22}
23
24} // namespace
25
27 if (!gfx_) throw eve::Exception("DepthPyramid: null graphics");
28 downsample_ = gfx_->getBackendName() == "webgpu"
29 ? gfx_->newShaderFromWgsl(
30 {}, std::string(shaders::kPostCommon) +
32 : gfx_->newShaderFromSpv(
33 {}, copySpv(depth_pyramid_downsample_frag_spv,
34 depth_pyramid_downsample_frag_spv_count));
35 if (!downsample_ || !downsample_->gpuHandle)
36 throw eve::Exception("DepthPyramid: failed to create shader");
37 downsample_->declareFloat("texelW");
38 downsample_->declareFloat("texelH");
39 downsample_->declareFloat("firstLevel");
40}
41
42void DepthPyramid::ensureTargets(int width, int height, int maxLevels) {
43 width = std::max(width, 1);
44 height = std::max(height, 1);
45 maxLevels = std::clamp(maxLevels, 1, kMaxLevels);
46 int desiredLevels = 1;
47 int desiredWidth = width;
48 int desiredHeight = height;
49 while (desiredLevels < maxLevels && (desiredWidth > 1 || desiredHeight > 1)) {
50 desiredWidth = std::max(desiredWidth / 2, 1);
51 desiredHeight = std::max(desiredHeight / 2, 1);
52 ++desiredLevels;
53 }
54 if (atlas_ && sourceWidth_ == width && sourceHeight_ == height &&
55 levelCount_ == desiredLevels)
56 return;
57 sourceWidth_ = width;
58 sourceHeight_ = height;
59 levelCount_ = 0;
60 int levelWidth = width;
61 int levelHeight = height;
62 while (levelCount_ < desiredLevels) {
63 levels_[levelCount_] = gfx_->newHDRCanvas(levelWidth, levelHeight);
64 if (!levels_[levelCount_])
65 throw eve::Exception("DepthPyramid: failed to allocate level");
66 ++levelCount_;
67 if (levelWidth == 1 && levelHeight == 1) break;
68 levelWidth = std::max(levelWidth / 2, 1);
69 levelHeight = std::max(levelHeight / 2, 1);
70 }
71 atlas_ = gfx_->newHDRCanvas(width * 2, height);
72 if (!atlas_) throw eve::Exception("DepthPyramid: failed to allocate atlas");
73}
74
76 if (!depth) throw eve::Exception("DepthPyramid.build: null depth");
77 ensureTargets(depth->getWidth(), depth->getHeight(), maxLevels);
78 Canvas *previousCanvas = gfx_->getCanvas();
80 for (int level = 0; level < levelCount_; ++level) {
81 Canvas *target = levels_[level];
82 downsample_->sendFloat("texelW", 1.f / float(std::max(input->getWidth(), 1)));
83 downsample_->sendFloat("texelH", 1.f / float(std::max(input->getHeight(), 1)));
84 downsample_->sendFloat("firstLevel", level == 0 ? 1.f : 0.f);
85 target->clear(Color(1.f, 1.f, 0.f, 1.f), {}, {});
86 gfx_->setCanvas(target);
87 gfx_->drawTexturedRectShaderUV(input, downsample_, 0.f, 0.f, float(target->getWidth()),
88 float(target->getHeight()), 0.f, 0.f, 1.f, 1.f,
89 Color(1.f, 1.f, 1.f, 1.f), false, BlendMode::Opaque);
90 input = target->getTexture();
91 }
92
93 atlas_->clear(Color(1.f, 1.f, 0.f, 1.f), {}, {});
94 gfx_->setCanvas(atlas_);
95 float offsetX = 0.f;
96 for (int level = 0; level < levelCount_; ++level) {
97 Canvas *source = levels_[level];
99 source->getTexture(), nullptr, offsetX, 0.f, float(source->getWidth()),
100 float(source->getHeight()), 0.f, 0.f, 1.f, 1.f, Color(1.f, 1.f, 1.f, 1.f), false,
102 offsetX += float(source->getWidth());
103 }
104 gfx_->setCanvas(previousCanvas);
105 Texture *result = atlas_->getTexture();
106 if (!result) throw eve::Exception("DepthPyramid: atlas texture missing");
107 return result;
108}
109
110} // namespace eve::graphics
LogicalId target
EvpackChunkInput input
Definition Evpack.cpp:170
std::uint32_t height
std::uint32_t width
int level
std::uint32_t count
float offsetX
const UnitySourceAsset & source
std::uint32_t depth
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
Canvas public API.
Definition Canvas.h:17
virtual void clear(std::optional< Color > color, std::optional< int > stencil, std::optional< double > depth)=0
Clears .
virtual Texture * getTexture()=0
Sampleable color buffer; screen Canvas returns nullptr.
DepthPyramid(Graphics *gfx)
Create the depth reduction shader.
Texture * build(Texture *depth, int maxLevels=8)
Build the min/max hierarchy from a hardware depth texture.
virtual std::string getBackendName() const =0
Renderer backend id used by sibling modules (e.g. Gpgpu).
virtual Shader * newShaderFromWgsl(const std::string &vertWgsl, const std::string &fragWgsl)=0
Create a 2D custom shader from WGSL source (WebGPU backend). Empty vert → default textured vertex sha...
virtual void drawTexturedRectShaderUV(Texture *texture, Shader *shader, float x, float y, float w, float h, float u0, float v0, float u1, float v1, const Color &color, bool rotatedUV=false, BlendMode blend=BlendMode::Alpha)=0
UV draw with an explicit Shader (nullptr = default textured pipeline).
virtual Canvas * getCanvas() const =0
Returns the canvas.
virtual void setCanvas(Canvas *canvas)=0
nullptr or this → screen. Switching flushes pending draws to the previous target.
virtual Shader * newShaderFromSpv(const std::vector< uint32_t > &vertSpv, const std::vector< uint32_t > &fragSpv)=0
Create a custom 2D shader from SPIR-V words (vert + frag). Owned by Graphics. Vertex stage may be emp...
virtual Canvas * newHDRCanvas(int width, int height)=0
Create an engine-internal linear RGBA16F post-process target.
void sendFloat(const std::string &name, float x)
Definition Shader.cpp:95
int declareFloat(const std::string &name)
Reserve sequential float slots in the push-constant block. Returns start index.
Definition Shader.cpp:43
GPU texture created via Graphics::newTexture. Owns GPU resources through an opaque backend handle.
Definition Texture.h:18
constexpr const char * kPostCommon
constexpr const char * kDepthPyramidDownsample
卡牌游戏 UI 工具模块:工厂 + 脚本绑定入口。 功能参考 ycarowr/UiCard:扇形手牌布局、抽牌/洗牌、悬浮放大、拖拽到落牌区、 敌方手牌(背面/偷看)、费用不足置灰,以及可实时调节的布局...
Definition Animation.h:25
eve::Color Color
RGBA color used by every graphics draw call. Lives inside eve::graphics so including a graphics heade...
Definition Color.h:13