载入中...
搜索中...
未找到
Decal.cpp
浏览该文件的文档.
1#include "decal/Decal.h"
2
3#include "common/Exception.h"
5#include "graphics/Graphics.h"
8#include "graphics/Texture.h"
9
10#include <simplesquirrel/simplesquirrel.hpp>
11
12namespace eve::decal {
13
15 std::string source;
16 std::uint32_t seed = 0;
17 int resolution = 0;
19};
20
21namespace {
22const std::vector<std::uint8_t> &bakeChannel(const ProceduralDecalBake &bake,
23 const std::string &channel) {
24 if (channel == "albedo") return bake.albedo;
25 if (channel == "normal") return bake.normal;
26 if (channel == "params") return bake.params;
27 throw eve::Exception("Decal procedural channel must be albedo, normal, or params");
28}
29
30void requireBakeChannel(const std::string &channel) {
31 if (channel != "albedo" && channel != "normal" && channel != "params")
32 throw eve::Exception("Decal procedural channel must be albedo, normal, or params");
33}
34} // namespace
35
37
38Decal::Decal() : proceduralBakeCache_(std::make_unique<ProceduralBakeCache>()) {
42 const glm::mat4 &viewProj, float aspect) {
43 DecalManager::inst().drawAll(gfx, cam.eyeX, cam.eyeY, cam.eyeZ, viewProj, aspect);
44 });
45}
46
48
49int Decal::project(float x, float y, float z, float nx, float ny, float nz,
50 graphics::Texture *albedo, const std::string &kind, float size, float depth,
51 bool randomYaw, int seed, float fadeIn, float lifetime, float fadeOut) {
52 if (!albedo) throw eve::Exception("Decal.project: null albedo texture");
53 return DecalManager::inst().project(x, y, z, nx, ny, nz, albedo, kind, size, depth, randomYaw,
54 seed, fadeIn, lifetime, fadeOut, 0.f, 0.f, 0.f, 0.f);
55}
56
57bool Decal::setStrength(int id, float normalStrength, float roughnessStrength, float metalStrength,
58 float emissiveStrength) {
59 return DecalManager::inst().setStrength(id, normalStrength, roughnessStrength,
60 metalStrength, emissiveStrength);
61}
62
63bool Decal::setUvRect(int id, float x, float y, float w, float h) {
64 return DecalManager::inst().setUvRect(id, x, y, w, h);
65}
66
70
71bool Decal::setBlend(int id, const std::string &mode) {
72 return DecalManager::inst().setBlend(id, mode);
73}
74
75DecalProjectionStatus Decal::setProjection(int id, const std::string &mode, float blendSharpness) {
76 return DecalManager::inst().setProjection(id, mode, blendSharpness);
77}
78
79DecalParallaxStatus Decal::setParallax(int id, float scale, float minLayers, float maxLayers) {
80 return DecalManager::inst().setParallax(id, scale, minLayers, maxLayers);
81}
82
86
87bool Decal::remove(int id) { return DecalManager::inst().remove(id); }
88
90
92
93void Decal::setLimit(const std::string &kind, int limit) {
95}
96
97void Decal::update(float dt) { DecalManager::inst().update(dt); }
98
100 if (!gfx) throw eve::Exception("Decal.setEnabled: null gfx");
101 if (auto *rc = gfx->getRenderControl()) {
102 if (enabled)
103 rc->enable("decal");
104 else
105 rc->disable("decal");
106 }
107}
108
109std::string Decal::proceduralPresets() const {
110 return "blood-wet,blood-dried,damage,dirt,rust,puddle,paint,moss,mold,lichen";
111}
112
114 std::uint32_t seed, int resolution,
115 const std::string &channel) {
116 if (!gfx) throw eve::Exception("Decal.bakePresetTexture: null gfx");
117 requireBakeChannel(channel);
118 const std::string source = "preset:" + preset;
119 if (proceduralBakeCache_->source != source || proceduralBakeCache_->seed != seed ||
120 proceduralBakeCache_->resolution != resolution) {
121 auto recipe = proceduralDecalPreset(preset, seed);
122 if (!recipe.ok()) throw eve::Exception("%s", recipe.status().describe().c_str());
123 recipe.value().width = resolution;
124 recipe.value().height = resolution;
125 auto baked = bakeProceduralDecal(recipe.value());
126 if (!baked.ok()) throw eve::Exception("%s", baked.status().describe().c_str());
127 proceduralBakeCache_->source = source;
128 proceduralBakeCache_->seed = seed;
129 proceduralBakeCache_->resolution = resolution;
130 proceduralBakeCache_->bake = std::move(baked.value());
131 }
132 const auto &bytes = bakeChannel(proceduralBakeCache_->bake, channel);
133 auto *texture = gfx->newTexture(resolution, resolution, bytes.data());
134 if (!texture) throw eve::Exception("Decal.bakePresetTexture: graphics upload failed");
135 return texture;
136}
137
139 int resolution, const std::string &channel) {
140 if (!gfx) throw eve::Exception("Decal.bakeSbsprsTexture: null gfx");
141 requireBakeChannel(channel);
142 const std::string source = "sbsprs:" + xml;
143 if (proceduralBakeCache_->source != source || proceduralBakeCache_->seed != 0 ||
144 proceduralBakeCache_->resolution != resolution) {
145 auto recipe = importProceduralDecalSbsprs(xml);
146 if (!recipe.ok()) throw eve::Exception("%s", recipe.status().describe().c_str());
147 recipe.value().width = resolution;
148 recipe.value().height = resolution;
149 auto baked = bakeProceduralDecal(recipe.value());
150 if (!baked.ok()) throw eve::Exception("%s", baked.status().describe().c_str());
151 proceduralBakeCache_->source = source;
152 proceduralBakeCache_->seed = 0;
153 proceduralBakeCache_->resolution = resolution;
154 proceduralBakeCache_->bake = std::move(baked.value());
155 }
156 const auto &bytes = bakeChannel(proceduralBakeCache_->bake, channel);
157 auto *texture = gfx->newTexture(resolution, resolution, bytes.data());
158 if (!texture) throw eve::Exception("Decal.bakeSbsprsTexture: graphics upload failed");
159 return texture;
160}
161
162void Decal::expose(ssq::Table &table) {
163 auto cls = table.addClass(name, Decal::create, false);
164 expose(cls);
165}
166
167void Decal::expose(ssq::Class &cls) {
168 cls.addFunc("getName", &Decal::getName);
169 cls.addFunc("project", &Decal::project);
170 cls.addFunc("setStrength", &Decal::setStrength);
171 cls.addFunc("setUvRect", &Decal::setUvRect);
172 cls.addFunc("setTextures", &Decal::setTextures);
173 cls.addFunc("setBlend", &Decal::setBlend);
174 cls.addFunc("setProjection", &Decal::setProjection);
175 cls.addFunc("setParallax", &Decal::setParallax);
176 cls.addFunc("setEdgeFade", &Decal::setEdgeFade);
177 cls.addFunc("remove", &Decal::remove);
178 cls.addFunc("clearAll", &Decal::clearAll);
179 cls.addFunc("count", &Decal::count);
180 cls.addFunc("setLimit", &Decal::setLimit);
181 cls.addFunc("update", &Decal::update);
182 cls.addFunc("setEnabled", &Decal::setEnabled);
183 cls.addFunc("proceduralPresets", &Decal::proceduralPresets);
184 cls.addFunc("bakePresetTexture", &Decal::bakePresetTexture);
185 cls.addFunc("bakeSbsprsTexture", &Decal::bakeSbsprsTexture);
186}
187
188} // namespace eve::decal
float w
Definition AnimClip.cpp:738
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
float normalStrength
float nx
float nz
float ny
graphics::Texture * albedo
HSQOBJECT cls
Definition ECS.cpp:21
int h
std::uint32_t width
TokenKind kind
std::array< float, 3 > scale
std::uint64_t bytes
std::string name
Texture * normal
#define Module_IMPL(ModuleName, newExpr)
Definition Module.h:26
std::weak_ptr< const void > lifetime
std::uint32_t seed
Definition PointSet.cpp:807
glm::mat4 viewProj
int limit
Definition TreeMesh.cpp:164
float size
Definition TreeMesh.cpp:156
const UnitySourceAsset & source
std::uint32_t depth
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
virtual std::string getName() const =0
Returns the name.
bool setUvRect(int id, float x, float y, float w, float h)
Sets the uv rect.
bool setTextures(int id, graphics::Texture *normal, graphics::Texture *params)
Sets the textures.
void drawAll(graphics::Graphics &gfx, float eyeX, float eyeY, float eyeZ, const glm::mat4 &viewProj, float aspect)
Draws all live instances into the active graphics decal pass.
bool setStrength(int id, float normalStrength, float roughnessStrength, float metalStrength, float emissiveStrength)
Sets the strength.
DecalProjectionStatus setProjection(int id, const std::string &mode, float blendSharpness=4.f)
Projection mode: "planar" (default) or "triplanar".
static DecalManager & inst()
Inst.
DecalEdgeFadeStatus setEdgeFade(int id, float width)
Configure normalized edge feather width in [0, 0.49].
void setLimit(const std::string &kind, int limit)
Per-kind quota ("blood" -> 64 etc.); oldest of the kind is evicted.
DecalParallaxStatus setParallax(int id, float scale, float minLayers=8.f, float maxLayers=24.f)
Configure POM; scale zero disables it and layers satisfy 1 <= min <= max <= 64.
void update(float dt)
Advance instance ages; expire and evict finished decals.
int count() const
Returns the number of .
bool setBlend(int id, const std::string &mode)
Sets the blend.
bool remove(int id)
Removes .
int project(float x, float y, float z, float nx, float ny, float nz, graphics::Texture *albedo, const std::string &kind, float size, float depth, bool randomYaw, int seed, float fadeIn, float lifetime, float fadeOut, float normalStrength, float roughnessStrength, float metalStrength, float emissiveStrength)
Spawn a decal at a world-space point facing along (nx,ny,nz).
Runtime decal module — project surface effects (blood, dirt, scorch, dents via normal maps,...
Definition Decal.h:29
DecalProjectionStatus setProjection(int id, const std::string &mode, float blendSharpness)
Projection: "planar", "triplanar", "spherical", or world-aligned "world".
Definition Decal.cpp:75
Decal()
Decal.
Definition Decal.cpp:38
DecalEdgeFadeStatus setEdgeFade(int id, float width)
Configure normalized edge-mask feather width in [0, 0.49].
Definition Decal.cpp:83
bool setStrength(int id, float normalStrength, float roughnessStrength, float metalStrength, float emissiveStrength)
Per-channel blend strengths for a live decal (0 disables).
Definition Decal.cpp:57
void clearAll()
Clears all.
Definition Decal.cpp:89
~Decal() override
Decal.
Definition Decal.cpp:47
bool remove(int id)
Removes .
Definition Decal.cpp:87
bool setTextures(int id, graphics::Texture *normal, graphics::Texture *params)
Optional normal / params (roughness, metallic, emissive) textures.
Definition Decal.cpp:67
int project(float x, float y, float z, float nx, float ny, float nz, graphics::Texture *albedo, const std::string &kind, float size, float depth, bool randomYaw, int seed, float fadeIn, float lifetime, float fadeOut)
Spawn a decal at (x,y,z) facing along (nx,ny,nz); returns id.
Definition Decal.cpp:49
DecalParallaxStatus setParallax(int id, float scale, float minLayers, float maxLayers)
Configure params-alpha POM; scale zero disables it.
Definition Decal.cpp:79
void update(float dt)
Advance ages / evict expired; call once per frame.
Definition Decal.cpp:97
void setEnabled(graphics::Graphics *gfx, bool enabled)
Toggle the graphics "decal" feature on the given backend.
Definition Decal.cpp:99
int count()
Returns the number of .
Definition Decal.cpp:91
void setLimit(const std::string &kind, int limit)
Sets the limit.
Definition Decal.cpp:93
bool setBlend(int id, const std::string &mode)
Blend mode: "over" (default) or "add" (emissive).
Definition Decal.cpp:71
bool setUvRect(int id, float x, float y, float w, float h)
Atlas region [x, y, w, h] (normalized) for a live decal.
Definition Decal.cpp:63
graphics::Texture * bakeSbsprsTexture(graphics::Graphics *gfx, const std::string &xml, int resolution, const std::string &channel)
Import a Procedural Decal .sbsprs document, bake it, and upload one channel.
Definition Decal.cpp:138
std::string proceduralPresets() const
Return the stable comma-separated Procedural Decal preset names.
Definition Decal.cpp:109
graphics::Texture * bakePresetTexture(graphics::Graphics *gfx, const std::string &preset, std::uint32_t seed, int resolution, const std::string &channel)
Bake one channel of a named Procedural Decal preset and upload it.
Definition Decal.cpp:113
virtual Texture * newTexture(int width, int height, const uint8_t *rgba, bool repeatU=false, bool repeatV=false)=0
Creates a texture. @ownership Caller deletes unless documented otherwise.
RenderControl * getRenderControl()
Shared compilable 3D render control (features → pass list + GBuffer). Owned by Graphics; valid for th...
Definition Graphics.cpp:254
static void addDecalExtraDrawer(DecalExtraDrawer drawer)
Adds decal extra drawer.
GPU texture created via Graphics::newTexture. Owns GPU resources through an opaque backend handle.
Definition Texture.h:18
std::vector< ParamSpec > params
DecalParallaxStatus
Outcome of applying height-driven parallax settings to a live decal.
void unregisterDecalAttackVfxExecutor()
Unregister the AttackVfx Decal layer executor.
void registerDecalCapabilities()
Register the IDecalQuery capability (implemented in DecalCapabilities.cpp).
Result< ProceduralDecalBake > bakeProceduralDecal(const ProceduralDecalRecipe &recipe)
Bake a two-layer decal recipe into renderer-ready texture bytes.
Result< ProceduralDecalRecipe > proceduralDecalPreset(std::string_view name, std::uint32_t seed)
Build a deterministic preset recipe.
DecalProjectionStatus
Outcome of DecalManager::setProjection / Decal::setProjection.
Result< ProceduralDecalRecipe > importProceduralDecalSbsprs(std::string_view xml)
Import one Substance .sbsprs preset into the native version-two recipe.
DecalEdgeFadeStatus
Outcome of changing the projection-volume edge mask width.
bool enabled
Owning, renderer-neutral output of one decal bake.
std::vector< std::uint8_t > albedo
std::vector< std::uint8_t > params
std::vector< std::uint8_t > normal