载入中...
搜索中...
未找到
EffectShaders.cpp
浏览该文件的文档.
2
3#include "common/Exception.h"
4#include "graphics/Graphics.h"
5#include "graphics/Shader.h"
6#include "graphics/shaders/mesh3d_toon_vert_spv.inc"
7#include "stylize/shaders/chromatic_post_frag_spv.inc"
8#include "stylize/shaders/dissolve_mesh_frag_spv.inc"
9#include "stylize/shaders/grain_post_frag_spv.inc"
10#include "stylize/shaders/hologram_mesh_frag_spv.inc"
11#include "stylize/shaders/slash_mesh_frag_spv.inc"
12#include "stylize/shaders/ember_mesh_frag_spv.inc"
13#include "stylize/shaders/aura_mesh_frag_spv.inc"
14#include "stylize/shaders/rim_mesh_frag_spv.inc"
15#include "stylize/shaders/snow_mesh_frag_spv.inc"
16#include "stylize/shaders/vignette_post_frag_spv.inc"
17
18#include <algorithm>
19#include <cstddef>
20#include <vector>
21
22namespace eve::stylize {
23namespace {
24
25// Mesh effect styles (reuse mesh3d_toon.vert; no scene buffers needed).
26const StyleDefinition kMeshEffects[] = {
27 {"rim", false, true, false, false, false, graphics::PostEffectStage::AfterOpaque, 40},
28 {"dissolve", false, true, false, false, false, graphics::PostEffectStage::AfterOpaque, 41},
29 {"hologram", false, true, false, false, false, graphics::PostEffectStage::AfterOpaque, 42},
30 {"snow", false, true, false, false, false, graphics::PostEffectStage::AfterOpaque, 43},
31 {"slash", false, true, false, false, false, graphics::PostEffectStage::AfterOpaque, 44},
32 {"ember", false, true, false, false, false, graphics::PostEffectStage::AfterOpaque, 45},
33 {"aura", false, true, false, false, false, graphics::PostEffectStage::AfterOpaque, 46},
34};
35
36// Post effect styles (full-screen passes, color input only).
37const StyleDefinition kPostEffects[] = {
38 {"vignette", true, false, false, false, false, graphics::PostEffectStage::AfterTonemap, 260},
39 {"chromatic", true, false, false, false, false, graphics::PostEffectStage::AfterTonemap, 270},
40 {"grain", true, false, false, false, false, graphics::PostEffectStage::AfterTonemap, 280},
41};
42
43const StyleParameterDesc kRimParams[] = {
44 {"colorR", 0.4f, 0.f, 2.f}, {"colorG", 0.6f, 0.f, 2.f}, {"colorB", 1.f, 0.f, 2.f},
45 {"rimPower", 3.f, 0.1f, 16.f}, {"rimIntensity", 1.f, 0.f, 4.f}, {"rimMix", 1.f, 0.f, 1.f},
46 {"ambientStrength", 0.15f, 0.f, 1.f}, {"baseLight", 1.f, 0.f, 3.f},
47};
48
49const StyleParameterDesc kDissolveParams[] = {
50 {"amount", 0.5f, 0.f, 1.f}, {"edgeWidth", 0.1f, 0.01f, 0.5f}, {"edgeColorR", 1.f, 0.f, 2.f},
51 {"edgeColorG", 0.5f, 0.f, 2.f}, {"edgeColorB", 0.1f, 0.f, 2.f}, {"edgeGlow", 2.f, 0.f, 6.f},
52 {"noiseScale", 2.f, 0.1f, 16.f}, {"hardness", 0.5f, 0.f, 1.f},
53};
54
55const StyleParameterDesc kHologramParams[] = {
56 {"colorR", 0.2f, 0.f, 2.f}, {"colorG", 0.9f, 0.f, 2.f}, {"colorB", 1.f, 0.f, 2.f},
57 {"fresnelStrength", 1.f, 0.f, 4.f}, {"scanDensity", 8.f, 1.f, 48.f}, {"scanIntensity", 0.5f, 0.f, 1.f},
58 {"flicker", 0.3f, 0.f, 1.f}, {"alphaBase", 0.35f, 0.f, 1.f}, {"glitchAmplitude", 0.15f, 0.f, 1.f},
59};
60
61const StyleParameterDesc kSnowParams[] = {
62 {"snowAmount", 0.9f, 0.f, 1.f}, {"snowHardness", 0.5f, 0.f, 1.f}, {"snowColorR", 0.93f, 0.f, 1.f},
63 {"snowColorG", 0.95f, 0.f, 1.f}, {"snowColorB", 0.98f, 0.f, 1.f}, {"noiseScale", 3.f, 0.1f, 16.f},
64 {"snowHeight", 0.f, -1000.f, 1000.f}, {"heightFade", 4.f, 0.1f, 100.f},
65};
66
67const StyleParameterDesc kSlashParams[] = {
68 {"coreR", 0.85f, 0.f, 2.f}, {"coreG", 0.95f, 0.f, 2.f}, {"coreB", 1.0f, 0.f, 2.f},
69 {"edgeR", 1.0f, 0.f, 2.f}, {"edgeG", 0.4f, 0.f, 2.f}, {"edgeB", 0.2f, 0.0f, 2.f},
70 {"intensity", 1.6f, 0.f, 4.f}, {"width", 0.06f, 0.005f, 0.3f}, {"softness", 0.12f, 0.001f, 0.5f},
71 {"noiseScale", 4.f, 0.1f, 20.f}, {"time", 0.f, 0.f, 120.f}, {"speed", 0.9f, 0.f, 3.f},
72 {"flowWarp", 0.35f, 0.f, 2.f}, {"edgeDistortion", 0.08f, 0.f, 0.5f},
73 {"depthSoftness", 0.004f, 0.0001f, 0.1f}, {"intersectionWidth", 0.006f, 0.0001f, 0.1f},
74 {"intersectionGlow", 0.8f, 0.f, 4.f},
75 {"refractionStrength", 0.f, 0.f, 1.f},
76};
77
78const StyleParameterDesc kEmberParams[] = {
79 {"coreR", 1.0f, 0.f, 2.f}, {"coreG", 0.35f, 0.f, 2.f}, {"coreB", 0.08f, 0.f, 2.f},
80 {"flareR", 1.0f, 0.f, 2.f}, {"flareG", 0.58f, 0.f, 2.f}, {"flareB", 0.2f, 0.f, 2.f},
81 {"burnAmount", 0.68f, 0.f, 1.f}, {"flicker", 0.5f, 0.f, 1.f}, {"noiseScale", 2.5f, 0.1f, 16.f},
82 {"hardness", 0.6f, 0.f, 1.f}, {"time", 0.f, 0.f, 120.f},
83};
84
85const StyleParameterDesc kAuraParams[] = {
86 {"auraR", 0.24f, 0.f, 2.f}, {"auraG", 0.62f, 0.f, 2.f}, {"auraB", 1.f, 0.f, 2.f},
87 {"pulse", 1.1f, 0.f, 4.f}, {"edge", 2.f, 0.1f, 8.f}, {"radius", 0.65f, 0.1f, 2.f},
88 {"noiseScale", 3.f, 0.1f, 16.f}, {"time", 0.f, 0.f, 120.f}, {"intensity", 1.1f, 0.f, 4.f},
89};
90
91const StyleParameterDesc kVignetteParams[] = {
92 {"strength", 0.5f, 0.f, 1.f}, {"smoothness", 0.5f, 0.01f, 1.f}, {"roundness", 0.5f, 0.f, 1.f},
93 {"colorR", 0.f, 0.f, 1.f}, {"colorG", 0.f, 0.f, 1.f}, {"colorB", 0.f, 0.f, 1.f},
94};
95
96const StyleParameterDesc kChromaticParams[] = {
97 {"strength", 0.3f, 0.f, 1.f},
98 {"radialMix", 1.f, 0.f, 1.f},
99 {"rgbSplit", 0.5f, 0.f, 1.f},
100};
101
102const StyleParameterDesc kGrainParams[] = {
103 {"strength", 0.15f, 0.f, 1.f},
104 {"grainSize", 4.f, 1.f, 32.f},
105 {"lumaAmount", 0.7f, 0.f, 1.f},
106 {"colorAmount", 0.1f, 0.f, 1.f},
107};
108
109const StyleDefinition* findMesh(const std::string& style) {
110 for (const auto& d : kMeshEffects)
111 if (style == d.id) return &d;
112 return nullptr;
113}
114const StyleDefinition* findPost(const std::string& style) {
115 for (const auto& d : kPostEffects)
116 if (style == d.id) return &d;
117 return nullptr;
118}
119
120template <size_t N>
121const StyleParameterDesc* paramAt(const StyleParameterDesc (&arr)[N], int index) {
122 return index < 0 || index >= int(N) ? nullptr : &arr[size_t(index)];
123}
124
125int meshParamCount(const std::string& style) {
126 if (style == "rim") return int(sizeof(kRimParams) / sizeof(kRimParams[0]));
127 if (style == "dissolve") return int(sizeof(kDissolveParams) / sizeof(kDissolveParams[0]));
128 if (style == "hologram") return int(sizeof(kHologramParams) / sizeof(kHologramParams[0]));
129 if (style == "snow") return int(sizeof(kSnowParams) / sizeof(kSnowParams[0]));
130 if (style == "slash") return int(sizeof(kSlashParams) / sizeof(kSlashParams[0]));
131 if (style == "ember") return int(sizeof(kEmberParams) / sizeof(kEmberParams[0]));
132 if (style == "aura") return int(sizeof(kAuraParams) / sizeof(kAuraParams[0]));
133 return 0;
134}
135const StyleParameterDesc* meshParamAt(const std::string& style, int index) {
136 if (style == "rim") return paramAt(kRimParams, index);
137 if (style == "dissolve") return paramAt(kDissolveParams, index);
138 if (style == "hologram") return paramAt(kHologramParams, index);
139 if (style == "snow") return paramAt(kSnowParams, index);
140 if (style == "slash") return paramAt(kSlashParams, index);
141 if (style == "ember") return paramAt(kEmberParams, index);
142 if (style == "aura") return paramAt(kAuraParams, index);
143 return nullptr;
144}
145int postParamCount(const std::string& style) {
146 if (style == "vignette") return int(sizeof(kVignetteParams) / sizeof(kVignetteParams[0]));
147 if (style == "chromatic") return int(sizeof(kChromaticParams) / sizeof(kChromaticParams[0]));
148 if (style == "grain") return int(sizeof(kGrainParams) / sizeof(kGrainParams[0]));
149 return 0;
150}
151const StyleParameterDesc* postParamAt(const std::string& style, int index) {
152 if (style == "vignette") return paramAt(kVignetteParams, index);
153 if (style == "chromatic") return paramAt(kChromaticParams, index);
154 if (style == "grain") return paramAt(kGrainParams, index);
155 return nullptr;
156}
157
158// The push-constant layout index of a param equals its position in the param
159// array, so bind in array order.
160void bindParamArray(graphics::Shader* shader, const std::string& style, bool mesh) {
161 if (!shader) throw eve::Exception("bindParamArray: null shader");
162 int n = mesh ? meshParamCount(style) : postParamCount(style);
163 for (int i = 0; i < n; ++i) {
164 const StyleParameterDesc* d = mesh ? meshParamAt(style, i) : postParamAt(style, i);
165 if (!d) break;
166 shader->declareFloat(d->id);
167 shader->sendFloat(d->id, d->defaultValue);
168 }
169}
170
171std::vector<uint32_t> copySpv(const uint32_t* data, size_t count) { return std::vector<uint32_t>(data, data + count); }
172
173} // namespace
174
175bool isEffectStyle(const std::string& style) { return findMesh(style) != nullptr || findPost(style) != nullptr; }
176
177const StyleDefinition* findEffectDefinition(const std::string& style) {
178 if (const StyleDefinition* d = findMesh(style)) return d;
179 return findPost(style);
180}
181
183 return int(sizeof(kMeshEffects) / sizeof(kMeshEffects[0])) + int(sizeof(kPostEffects) / sizeof(kPostEffects[0]));
184}
185
186std::string effectStyleIdAt(int index) {
187 const int meshCount = int(sizeof(kMeshEffects) / sizeof(kMeshEffects[0]));
188 if (index >= 0 && index < meshCount) return kMeshEffects[index].id;
189 index -= meshCount;
190 if (index >= 0 && index < int(sizeof(kPostEffects) / sizeof(kPostEffects[0]))) return kPostEffects[index].id;
191 return {};
192}
193
194int effectParamCount(const std::string& style) {
195 if (findMesh(style)) return meshParamCount(style);
196 return postParamCount(style);
197}
198
199std::string effectParamName(const std::string& style, int index) {
201 return d ? d->id : std::string{};
202}
203
204const StyleParameterDesc* findEffectParameter(const std::string& style, const std::string& name) {
205 const int n = effectParamCount(style);
206 for (int i = 0; i < n; ++i) {
207 const StyleParameterDesc* d = effectParameterAt(style, i);
208 if (d && name == d->id) return d;
209 }
210 return nullptr;
211}
212
213const StyleParameterDesc* effectParameterAt(const std::string& style, int index) {
214 if (findMesh(style)) return meshParamAt(style, index);
215 return postParamAt(style, index);
216}
217
218void bindEffectPostUniforms(graphics::Shader* shader, const std::string& style) {
219 bindParamArray(shader, style, /*mesh=*/false);
220 // Chromatic dispersion needs the framebuffer size to keep the RGB split
221 // aspect-correct; StylePass::uploadScreenUniforms refreshes these.
222 if (style == "chromatic") {
223 shader->declareFloat("screenW");
224 shader->declareFloat("screenH");
225 shader->sendFloat("screenW", 256.f);
226 shader->sendFloat("screenH", 256.f);
227 }
228}
229
230void bindEffectMeshUniforms(graphics::Shader* shader, const std::string& style) {
231 bindParamArray(shader, style, /*mesh=*/true);
232}
233
235 if (!gfx) throw eve::Exception("createEffectPostShader: null graphics");
236 std::vector<uint32_t> frag;
237 if (style == "vignette")
238 frag = copySpv(vignette_post_frag_spv, vignette_post_frag_spv_count);
239 else if (style == "chromatic")
240 frag = copySpv(chromatic_post_frag_spv, chromatic_post_frag_spv_count);
241 else if (style == "grain")
242 frag = copySpv(grain_post_frag_spv, grain_post_frag_spv_count);
243 else
244 throw eve::Exception("createEffectPostShader: not an effect post style '%s'", style.c_str());
245
246 graphics::Shader* sh = gfx->newShaderFromSpv({}, frag);
247 if (!sh || !sh->gpuHandle) throw eve::Exception("createEffectPostShader: failed to create '%s'", style.c_str());
248 bindEffectPostUniforms(sh, style);
249 return sh;
250}
251
253 if (!gfx) throw eve::Exception("createEffectMeshShader: null graphics");
254 std::vector<uint32_t> frag;
255 if (style == "rim")
256 frag = copySpv(rim_mesh_frag_spv, rim_mesh_frag_spv_count);
257 else if (style == "dissolve")
258 frag = copySpv(dissolve_mesh_frag_spv, dissolve_mesh_frag_spv_count);
259 else if (style == "hologram")
260 frag = copySpv(hologram_mesh_frag_spv, hologram_mesh_frag_spv_count);
261 else if (style == "snow")
262 frag = copySpv(snow_mesh_frag_spv, snow_mesh_frag_spv_count);
263 else if (style == "slash")
264 frag = copySpv(slash_mesh_frag_spv, slash_mesh_frag_spv_count);
265 else if (style == "ember")
266 frag = copySpv(ember_mesh_frag_spv, ember_mesh_frag_spv_count);
267 else if (style == "aura")
268 frag = copySpv(aura_mesh_frag_spv, aura_mesh_frag_spv_count);
269 else
270 throw eve::Exception("createEffectMeshShader: not an effect mesh style '%s'", style.c_str());
271
272 auto vert = copySpv(mesh3d_toon_vert_spv, mesh3d_toon_vert_spv_count);
274 if (!sh || !sh->gpuHandle) throw eve::Exception("createEffectMeshShader: failed to create '%s'", style.c_str());
275 bindEffectMeshUniforms(sh, style);
276 return sh;
277}
278
279} // namespace eve::stylize
vk::ShaderModule vert
vk::ShaderModule frag
glm::vec3 n
Definition Grass.cpp:63
std::string name
std::string id
Definition PlayHost.cpp:108
float d
Mesh * mesh
Shader * shader
std::uint32_t count
uint32_t index
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
virtual Shader * newMeshShaderFromSpv(const std::vector< uint32_t > &vertSpv, const std::vector< uint32_t > &fragSpv)=0
Create a Mesh3D custom shader (MeshVertex + Frame UBO + albedo). Empty vert → default mesh3d....
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...
Custom GPU program.
Definition Shader.h:39
void bindEffectMeshUniforms(graphics::Shader *shader, const std::string &style)
Binds effect mesh uniforms.
graphics::Shader * createEffectMeshShader(graphics::Graphics *gfx, const std::string &style)
Creates effect mesh shader.
std::string effectParamName(const std::string &style, int index)
Effect param name.
bool isEffectStyle(const std::string &style)
True when style names one of the ported effect shaders.
graphics::Shader * createEffectPostShader(graphics::Graphics *gfx, const std::string &style)
Creates effect post shader.
const StyleParameterDesc * findEffectParameter(const std::string &style, const std::string &name)
Finds effect parameter.
int effectStyleCount()
Effect style count.
void bindEffectPostUniforms(graphics::Shader *shader, const std::string &style)
Binds effect post uniforms.
std::string effectStyleIdAt(int index)
Effect style id at.
const StyleDefinition * findEffectDefinition(const std::string &style)
Effect-only StyleDefinition lookup, or nullptr when unknown.
int effectParamCount(const std::string &style)
Effect param count.
const StyleParameterDesc * effectParameterAt(const std::string &style, int index)
Effect parameter at.
Immutable capability metadata for one built-in stylization recipe.
Tooling metadata for one user-facing float parameter.