8#include "graphics/shaders/aa_fxaa_frag_spv.inc"
9#include "graphics/shaders/aa_nfaa_frag_spv.inc"
10#include "graphics/shaders/aa_smaa_frag_spv.inc"
11#include "graphics/shaders/aa_ssaa_frag_spv.inc"
18#include <glm/vec4.hpp>
23std::vector<uint32_t> copySpv(
const uint32_t *data,
size_t count) {
24 return std::vector<uint32_t>(data, data + count);
27Shader *createFxaaShader(Graphics *gfx) {
29 auto frag = copySpv(aa_fxaa_frag_spv, aa_fxaa_frag_spv_count);
30 Shader *sh = gfx->newShaderFromSpv({},
frag);
31 if (!sh || !sh->gpuHandle)
throw eve::Exception(
"AntiAliasing: failed to create FXAA shader");
32 sh->declareFloat(
"texelW");
33 sh->declareFloat(
"texelH");
34 sh->declareFloat(
"edgeThreshold");
35 sh->declareFloat(
"edgeThresholdMin");
36 sh->declareFloat(
"subpix");
37 sh->declareFloat(
"quality");
38 sh->sendFloat(
"texelW", 1.f / 256.f);
39 sh->sendFloat(
"texelH", 1.f / 256.f);
40 sh->sendFloat(
"edgeThreshold", 0.166f);
41 sh->sendFloat(
"edgeThresholdMin", 0.0833f);
42 sh->sendFloat(
"subpix", 0.75f);
43 sh->sendFloat(
"quality", 1.f);
47Shader *createSmaaShader(Graphics *gfx) {
49 auto frag = copySpv(aa_smaa_frag_spv, aa_smaa_frag_spv_count);
50 Shader *sh = gfx->newShaderFromSpv({},
frag);
51 if (!sh || !sh->gpuHandle)
throw eve::Exception(
"AntiAliasing: failed to create SMAA shader");
52 sh->declareFloat(
"texelW");
53 sh->declareFloat(
"texelH");
54 sh->declareFloat(
"threshold");
55 sh->declareFloat(
"localContrast");
56 sh->declareFloat(
"maxSearch");
57 sh->declareFloat(
"cornerRounding");
58 sh->sendFloat(
"texelW", 1.f / 256.f);
59 sh->sendFloat(
"texelH", 1.f / 256.f);
60 sh->sendFloat(
"threshold", 0.1f);
61 sh->sendFloat(
"localContrast", 0.5f);
62 sh->sendFloat(
"maxSearch", 8.f);
63 sh->sendFloat(
"cornerRounding", 0.25f);
67Shader *createSsaaShader(Graphics *gfx) {
69 auto frag = copySpv(aa_ssaa_frag_spv, aa_ssaa_frag_spv_count);
70 Shader *sh = gfx->newShaderFromSpv({},
frag);
71 if (!sh || !sh->gpuHandle)
throw eve::Exception(
"AntiAliasing: failed to create SSAA shader");
72 sh->declareFloat(
"texelW");
73 sh->declareFloat(
"texelH");
74 sh->declareFloat(
"scale");
75 sh->declareFloat(
"kernel");
76 sh->declareFloat(
"sampleRadius");
77 sh->sendFloat(
"texelW", 1.f / 512.f);
78 sh->sendFloat(
"texelH", 1.f / 512.f);
79 sh->sendFloat(
"scale", 2.f);
80 sh->sendFloat(
"kernel", 1.f);
81 sh->sendFloat(
"sampleRadius", 1.f);
85Shader *createNfaaShader(Graphics *gfx) {
87 auto frag = copySpv(aa_nfaa_frag_spv, aa_nfaa_frag_spv_count);
88 Shader *sh = gfx->newShaderFromSpv({},
frag);
89 if (!sh || !sh->gpuHandle)
throw eve::Exception(
"AntiAliasing: failed to create NFAA shader");
90 sh->declareFloat(
"texelW");
91 sh->declareFloat(
"texelH");
92 sh->declareFloat(
"strength");
93 sh->declareFloat(
"power");
94 sh->declareFloat(
"blurScale");
95 sh->sendFloat(
"texelW", 1.f / 256.f);
96 sh->sendFloat(
"texelH", 1.f / 256.f);
97 sh->sendFloat(
"strength", 1.f);
98 sh->sendFloat(
"power", 1.f);
99 sh->sendFloat(
"blurScale", 1.f);
106 fxaa_ = createFxaaShader(gfx);
107 smaa_ = createSmaaShader(gfx);
108 ssaa_ = createSsaaShader(gfx);
109 nfaa_ = createNfaaShader(gfx);
110 applyQualityDefaults();
115void AntiAliasing::applyQualityDefaults() {
116 if (quality_ ==
"low") {
117 fxaa_->
sendFloat(
"edgeThreshold", 0.25f);
118 fxaa_->
sendFloat(
"edgeThresholdMin", 0.0833f);
122 smaa_->
sendFloat(
"localContrast", 0.55f);
124 smaa_->
sendFloat(
"cornerRounding", 0.1f);
133 if (quality_ ==
"high") {
134 fxaa_->
sendFloat(
"edgeThreshold", 0.125f);
135 fxaa_->
sendFloat(
"edgeThresholdMin", 0.0312f);
141 smaa_->
sendFloat(
"cornerRounding", 0.4f);
152 fxaa_->
sendFloat(
"edgeThreshold", 0.166f);
153 fxaa_->
sendFloat(
"edgeThresholdMin", 0.0833f);
159 smaa_->
sendFloat(
"cornerRounding", 0.25f);
169 if (quality ==
"low" || quality ==
"medium" || quality ==
"high")
173 applyQualityDefaults();
177 if (mode ==
"fxaa" || mode ==
"smaa" || mode ==
"ssaa" || mode ==
"nfaa")
183Shader *AntiAliasing::shaderForMode()
const {
184 if (mode_ ==
"smaa")
return smaa_;
185 if (mode_ ==
"ssaa")
return ssaa_;
186 if (mode_ ==
"nfaa")
return nfaa_;
193 Shader *sh = shaderForMode();
198 Shader *sh = shaderForMode();
199 if (!sh)
throw eve::Exception(
"AntiAliasing.setFloat: null shader");
204 Shader *sh = shaderForMode();
205 if (!sh)
throw eve::Exception(
"AntiAliasing.getFloat: null shader");
213 if (mode_ !=
"ssaa")
return 1.f;
214 if (quality_ ==
"high")
return 4.f;
219 if (destSize < 1) destSize = 1;
221 return std::max(1,
int(std::floor(
float(destSize) *
s)));
224void AntiAliasing::uploadScreenUniforms(
Texture *source) {
225 if (!source)
throw eve::Exception(
"AntiAliasing: null source texture");
226 const int w = std::max(1, source->
getWidth());
227 const int h = std::max(1, source->
getHeight());
228 const float tw = 1.f / float(
w);
229 const float th = 1.f / float(
h);
230 Shader *sh = shaderForMode();
233 if (mode_ ==
"ssaa" && sh->
hasUniform(
"scale")) {
242void AntiAliasing::drawFullscreen(Graphics *gfx, Texture *source, Shader *
shader) {
244 if (!source)
throw eve::Exception(
"AntiAliasing: null source texture");
246 uploadScreenUniforms(source);
247 const float dw = gfx->getCanvas() ? float(gfx->getCanvas()->getWidth()) : float(gfx->getWidth());
249 gfx->getCanvas() ? float(gfx->getCanvas()->getHeight()) : float(gfx->getHeight());
250 gfx->drawTexturedRectShader(source,
shader, 0.f, 0.f, dw, dh, glm::vec4(1.f, 1.f, 1.f, 1.f));
256 drawFullscreen(gfx, source, shaderForMode());
260 if (!gfx)
throw eve::Exception(
"AntiAliasing.applyTo: null graphics");
261 if (!dest)
throw eve::Exception(
"AntiAliasing.applyTo: null dest");
269 if (!source)
throw eve::Exception(
"AntiAliasing.applyCanvas: null source");
271 if (!tex)
throw eve::Exception(
"AntiAliasing.applyCanvas: source has no sampleable texture");
276 if (!source)
throw eve::Exception(
"AntiAliasing.applyCanvasTo: null source");
278 if (!tex)
throw eve::Exception(
"AntiAliasing.applyCanvasTo: source has no sampleable texture");
bool hasParam(const std::string &name) const
void apply(Graphics *gfx, Texture *source)
Apply current mode to source, writing into the currently bound canvas / screen. Uploads texelW/texelH...
void setMode(const std::string &mode)
"fxaa" | "smaa" | "ssaa" | "nfaa" (unknown → fxaa).
void prepareSource(Texture *source)
Upload texel uniforms from source without drawing (3D scene-color resolve).
float suggestScale() const
Suggested supersample scale for the active quality when using "ssaa" (2 for low/medium,...
void applyTo(Graphics *gfx, Texture *source, Canvas *dest)
float getFloat(const std::string &name) const
Shader * getShader() const
void setFloat(const std::string &name, float value)
AntiAliasing(Graphics *gfx)
void applyCanvas(Graphics *gfx, Canvas *source)
int resolutionFor(int destSize) const
void applyCanvasTo(Graphics *gfx, Canvas *source, Canvas *dest)
void setQuality(const std::string &quality)
"low" | "medium" | "high" (unknown → medium).
virtual Texture * getTexture()=0
Sampleable color buffer; screen Canvas returns nullptr.
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
void sendFloat(const std::string &name, float x)
int getFromVar(const std::string &name, void *data, size_t size) const
GPU texture created via Graphics::newTexture. Owns GPU resources through an opaque backend handle.
卡牌游戏 UI 工具模块:工厂 + 脚本绑定入口。 功能参考 ycarowr/UiCard:扇形手牌布局、抽牌/洗牌、悬浮放大、拖拽到落牌区、 敌方手牌(背面/偷看)、费用不足置灰,以及可实时调节的布局...