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