载入中...
搜索中...
未找到
Outline.cpp
浏览该文件的文档.
1#include "graphics/Outline.h"
2
3#include "common/Exception.h"
4#include "graphics/Canvas.h"
5#include "graphics/Graphics.h"
6#include "graphics/Shader.h"
7#include "graphics/Texture.h"
8#include "graphics/shaders/outline_post_frag_spv.inc"
10
11#include <algorithm>
12
13namespace eve::graphics {
14namespace {
15
16Shader *createOutlineShader(Graphics *gfx) {
17 if (!gfx) throw eve::Exception("Outline: null graphics");
18 std::vector<uint32_t> frag(outline_post_frag_spv, outline_post_frag_spv + outline_post_frag_spv_count);
19 Shader *sh = gfx->getBackendName() == "webgpu"
20 ? gfx->newShaderFromWgsl({}, std::string(shaders::kPostCommon) +
22 : gfx->newShaderFromSpv({}, frag);
23 if (!sh || !sh->gpuHandle)
24 throw eve::Exception("Outline: failed to create outline shader");
25 sh->declareFloat("width");
26 sh->declareFloat("depthThreshold");
27 sh->declareFloat("depthSensitivity");
28 sh->declareFloat("normalThreshold");
29 sh->declareFloat("softness");
30 sh->declareFloat("colorR");
31 sh->declareFloat("colorG");
32 sh->declareFloat("colorB");
33 sh->declareFloat("texelW");
34 sh->declareFloat("texelH");
35 sh->declareFloat("nearZ");
36 sh->declareFloat("farZ");
37 sh->sendFloat("width", 1.f);
38 sh->sendFloat("depthThreshold", 0.3f);
39 sh->sendFloat("depthSensitivity", 0.f);
40 sh->sendFloat("normalThreshold", 0.35f);
41 sh->sendFloat("softness", 0.15f);
42 sh->sendFloat("colorR", 0.05f);
43 sh->sendFloat("colorG", 0.04f);
44 sh->sendFloat("colorB", 0.07f);
45 sh->sendFloat("texelW", 1.f / 256.f);
46 sh->sendFloat("texelH", 1.f / 256.f);
47 sh->sendFloat("nearZ", 0.1f);
48 sh->sendFloat("farZ", 100.f);
49 return sh;
50}
51
52} // namespace
53
54Outline::Outline(Graphics *gfx) : gfx_(gfx) {
55 shader_ = createOutlineShader(gfx);
56}
57
58Outline::~Outline() = default;
59
60void Outline::setColor(float r, float g, float b) {
61 colorR_ = r;
62 colorG_ = g;
63 colorB_ = b;
64 if (shader_) {
65 shader_->sendFloat("colorR", r);
66 shader_->sendFloat("colorG", g);
67 shader_->sendFloat("colorB", b);
68 }
69}
70
71float Outline::getColorR() const { return colorR_; }
72float Outline::getColorG() const { return colorG_; }
73float Outline::getColorB() const { return colorB_; }
74
76 width_ = std::max(width, 0.5f);
77 if (shader_) shader_->sendFloat("width", width_);
78}
79
80float Outline::getWidth() const { return width_; }
81
82void Outline::setDepthThreshold(float threshold) {
83 depthThreshold_ = std::max(threshold, 0.f);
84 if (shader_) shader_->sendFloat("depthThreshold", depthThreshold_);
85}
86
87float Outline::getDepthThreshold() const { return depthThreshold_; }
88
89void Outline::setDepthSensitivity(float sensitivity) {
90 depthSensitivity_ = std::max(sensitivity, 0.f);
91 if (shader_) shader_->sendFloat("depthSensitivity", depthSensitivity_);
92}
93
94float Outline::getDepthSensitivity() const { return depthSensitivity_; }
95
96void Outline::setNormalThreshold(float threshold) {
97 normalThreshold_ = std::clamp(threshold, 0.f, 2.f);
98 if (shader_) shader_->sendFloat("normalThreshold", normalThreshold_);
99}
100
101float Outline::getNormalThreshold() const { return normalThreshold_; }
102
103void Outline::setSoftness(float softness) {
104 softness_ = std::clamp(softness, 0.f, 1.f);
105 if (shader_) shader_->sendFloat("softness", softness_);
106}
107
108float Outline::getSoftness() const { return softness_; }
109
110void Outline::setClip(float nearZ, float farZ) {
111 nearZ_ = nearZ > 1e-4f ? nearZ : 0.1f;
112 farZ_ = farZ > nearZ_ ? farZ : nearZ_ + 1.f;
113 if (shader_) {
114 shader_->sendFloat("nearZ", nearZ_);
115 shader_->sendFloat("farZ", farZ_);
116 }
117}
118
119bool Outline::hasParam(const std::string &name) const {
120 return shader_ && shader_->hasUniform(name);
121}
122
123void Outline::setFloat(const std::string &name, float value) {
124 if (!shader_) throw eve::Exception("Outline.setFloat: null shader");
125 shader_->sendFloat(name, value);
126}
127
128float Outline::getFloat(const std::string &name) const {
129 if (!shader_) throw eve::Exception("Outline.getFloat: null shader");
130 float v = 0.f;
131 if (shader_->getFromVar(name, &v, sizeof(v)) != int(sizeof(v)))
132 throw eve::Exception("Outline.getFloat: missing param '%s'", name.c_str());
133 return v;
134}
135
136void Outline::uploadCommon(Graphics *gfx, Texture *hwDepth) {
137 const int w = hwDepth->getWidth();
138 const int h = hwDepth->getHeight();
139 if (shader_) {
140 shader_->sendFloat("texelW", 1.f / float(std::max(w, 1)));
141 shader_->sendFloat("texelH", 1.f / float(std::max(h, 1)));
142 shader_->sendFloat("nearZ", nearZ_);
143 shader_->sendFloat("farZ", farZ_);
144 }
145}
146
147bool Outline::apply(Graphics *gfx, Texture *hwDepth, Texture *worldNormal) {
148 if (!gfx) throw eve::Exception("Outline.apply: null graphics");
149 if (!shader_) throw eve::Exception("Outline.apply: null shader");
150 if (!hwDepth) return false;
151 if (!worldNormal) return false;
152
153 uploadCommon(gfx, hwDepth);
154
155 const float dw = gfx->getCanvas() ? float(gfx->getCanvas()->getWidth()) : float(gfx->getWidth());
156 const float dh =
157 gfx->getCanvas() ? float(gfx->getCanvas()->getHeight()) : float(gfx->getHeight());
158 gfx->drawTexturedRectShaderDepth(hwDepth, worldNormal, shader_, 0.f, 0.f, dw, dh,
159 Color(1.f, 1.f, 1.f, 1.f));
160 return true;
161}
162
163bool Outline::applyTo(Graphics *gfx, Texture *hwDepth, Texture *worldNormal, Canvas *dest) {
164 if (!gfx) throw eve::Exception("Outline.applyTo: null graphics");
165 if (!dest) throw eve::Exception("Outline.applyTo: null dest");
166 Canvas *prev = gfx->getCanvas();
167 gfx->setCanvas(dest);
168 const bool ok = apply(gfx, hwDepth, worldNormal);
169 gfx->setCanvas(prev);
170 return ok;
171}
172
173} // namespace eve::graphics
double value
float w
Definition AnimClip.cpp:738
tensor::Graph g
Definition GpuGraph.cpp:7
vk::ShaderModule frag
double r
float v
int h
std::uint32_t width
std::string name
MeleePoint3 b
Definition MeleeHit.cpp:41
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
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 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,...
float getColorG() const
Returns the color g.
Definition Outline.cpp:72
void setWidth(float width)
Outline thickness in screen pixels (>= 0.5).
Definition Outline.cpp:75
float getDepthSensitivity() const
Returns the depth sensitivity.
Definition Outline.cpp:94
void setDepthThreshold(float threshold)
View-space depth discontinuity that starts a depth edge.
Definition Outline.cpp:82
float getDepthThreshold() const
Returns the depth threshold.
Definition Outline.cpp:87
float getWidth() const
Returns the width.
Definition Outline.cpp:80
float getSoftness() const
Returns the softness.
Definition Outline.cpp:108
void setFloat(const std::string &name, float value)
Sets the float.
Definition Outline.cpp:123
void setNormalThreshold(float threshold)
Normal discontinuity (1 - dot(n, nN)) that starts a crease edge.
Definition Outline.cpp:96
void setColor(float r, float g, float b)
Sets the color.
Definition Outline.cpp:60
void setSoftness(float softness)
Smoothstep band used to fade edges (0 = hard, 1 = soft).
Definition Outline.cpp:103
float getColorB() const
Returns the color b.
Definition Outline.cpp:73
bool hasParam(const std::string &name) const
True when param.
Definition Outline.cpp:119
Outline(Graphics *gfx)
Outline.
Definition Outline.cpp:54
void setDepthSensitivity(float sensitivity)
Extra per-unit-distance depth tolerance (keeps outlines distance-consistent).
Definition Outline.cpp:89
float getFloat(const std::string &name) const
Returns the float.
Definition Outline.cpp:128
void setClip(float nearZ, float farZ)
Near/far used to linearize the hardware depth.
Definition Outline.cpp:110
bool apply(Graphics *gfx, Texture *hwDepth, Texture *worldNormal)
Draw the outline over the currently bound canvas / screen. hwDepth is the D32 GBuffer (Vulkan NDC z),...
Definition Outline.cpp:147
float getNormalThreshold() const
Returns the normal threshold.
Definition Outline.cpp:101
float getColorR() const
Returns the color r.
Definition Outline.cpp:71
bool applyTo(Graphics *gfx, Texture *hwDepth, Texture *worldNormal, Canvas *dest)
Applies to.
Definition Outline.cpp:163
bool hasUniform(const std::string &name) const
Definition Shader.cpp:59
void sendFloat(const std::string &name, float x)
Definition Shader.cpp:95
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 * kPostCommon
constexpr const char * kOutline
卡牌游戏 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