载入中...
搜索中...
未找到
Material.cpp
浏览该文件的文档.
1#include "graphics/Material.h"
2
4#include "graphics/Graphics.h"
5#include "graphics/Light.h"
6
7#include <cmath>
8
9namespace eve::graphics {
10
11namespace {
12eve::Diagnostic invalidMaterial(std::string message) {
14}
15} // namespace
16
18 int pageCountX, int pageCountY, int atlasSlotsX, int atlasSlotsY,
19 float borderFraction) {
20 if (!albedoAtlas || !normalAtlas || !pageTable)
22 invalidMaterial("virtual texture requires albedo, normal, and page-table textures"));
23 if (pageCountX <= 0 || pageCountY <= 0 || atlasSlotsX <= 0 || atlasSlotsY <= 0)
25 invalidMaterial("virtual texture page and atlas dimensions must be positive"));
26 if (!std::isfinite(borderFraction) || borderFraction < 0.f || borderFraction >= 0.5f)
27 return eve::Result<void>::failure(invalidMaterial("virtual texture border fraction must be in [0, 0.5)"));
28 pbr_.textures[0].texture = albedoAtlas;
29 pbr_.textures[2].texture = normalAtlas;
30 height_ = pageTable;
31 virtualPageCountX_ = pageCountX;
32 virtualPageCountY_ = pageCountY;
33 virtualAtlasSlotsX_ = atlasSlotsX;
34 virtualAtlasSlotsY_ = atlasSlotsY;
35 virtualBorderFraction_ = borderFraction;
36 virtualTextureEnabled_ = true;
38}
39
41 virtualTextureEnabled_ = false;
42 virtualPageCountX_ = 0;
43 virtualPageCountY_ = 0;
44 virtualAtlasSlotsX_ = 0;
45 virtualAtlasSlotsY_ = 0;
46 virtualBorderFraction_ = 0.f;
47}
48
49void Material::setShadingModel(const std::string& model) {
50 if (model == "unlit" || model == "hair" || model == "custom" || model == "pbr") {
51 shadingModel_ = model;
52 } else {
53 shadingModel_ = "pbr";
54 }
55 if (shadingModel_ == "hair") {
56 isHair_ = true;
57 surfaceMode_ = SurfaceMode::Transparent;
58 blendMode_ = BlendMode::Alpha;
59 doubleSided_ = true;
60 depthWrite_ = false;
61 castShadow_ = false;
62 alphaCutoff_ = 0.15f;
63 if (sortPriority_ == 0) sortPriority_ = 10;
64 }
65}
66
67void Material::setTint(float r, float g, float b, float a) {
68 r_ = r;
69 g_ = g;
70 b_ = b;
71 a_ = a;
72}
73
74void Material::setMetallic(float metallic) { metallic_ = metallic < 0.f ? 0.f : (metallic > 1.f ? 1.f : metallic); }
75
77 roughness_ = roughness < 0.04f ? 0.04f : (roughness > 1.f ? 1.f : roughness);
78}
79
80void Material::setTexCellBomb(float cellScale, float strength, float rotAmount) {
81 texBombScale_ = cellScale > 1e-3f ? cellScale : 1e-3f;
82 texBombStrength_ = strength < 0.f ? 0.f : (strength > 1.f ? 1.f : strength);
83 texBombRot_ = rotAmount < 0.f ? 0.f : (rotAmount > 1.f ? 1.f : rotAmount);
84}
85
86void Material::setParallax(float scale, float minLayers, float maxLayers) {
87 parallaxScale_ = scale < 0.f ? 0.f : (scale > 0.25f ? 0.25f : scale);
88 float minL = minLayers < 1.f ? 1.f : minLayers;
89 float maxL = maxLayers < minL ? minL : maxLayers;
90 if (maxL > 64.f) maxL = 64.f;
91 parallaxMinLayers_ = minL;
92 parallaxMaxLayers_ = maxL;
93}
94
95void Material::setHair(bool hair) {
96 isHair_ = hair;
97 if (hair) {
98 shadingModel_ = "hair";
99 surfaceMode_ = SurfaceMode::Transparent;
100 blendMode_ = BlendMode::Alpha;
101 doubleSided_ = true;
102 depthWrite_ = false;
103 castShadow_ = false;
104 alphaCutoff_ = 0.15f;
105 if (sortPriority_ == 0) sortPriority_ = 10;
106 }
107}
108
109void Material::setSurfaceMode(const std::string& mode) {
110 if (mode == "masked")
111 surfaceMode_ = SurfaceMode::Masked;
112 else if (mode == "transparent" || mode == "blend")
113 surfaceMode_ = SurfaceMode::Transparent;
114 else
115 surfaceMode_ = SurfaceMode::Opaque;
116}
117
118std::string Material::getSurfaceMode() const {
119 if (surfaceMode_ == SurfaceMode::Masked) return "masked";
120 if (surfaceMode_ == SurfaceMode::Transparent) return "transparent";
121 return "opaque";
122}
123
124void Material::setAlphaCutoff(float cutoff) { alphaCutoff_ = cutoff < 0.f ? 0.f : (cutoff > 1.f ? 1.f : cutoff); }
125
126void Material::setBlendMode(const std::string& mode) {
127 if (mode == "premultiplied" || mode == "premultiplied_alpha")
128 blendMode_ = BlendMode::Premultiplied;
129 else if (mode == "additive")
130 blendMode_ = BlendMode::Additive;
131 else if (mode == "multiply")
132 blendMode_ = BlendMode::Multiply;
133 else
134 blendMode_ = BlendMode::Alpha;
135}
136
137std::string Material::getBlendMode() const {
138 if (blendMode_ == BlendMode::Premultiplied) return "premultiplied";
139 if (blendMode_ == BlendMode::Additive) return "additive";
140 if (blendMode_ == BlendMode::Multiply) return "multiply";
141 return "alpha";
142}
143
144void Material::setAlphaTechnique(const std::string& technique) {
145 alphaTechnique_ = (technique == "dither" || technique == "coverage") ? technique : "cutoff";
146}
147
148bool Material::hasParam(const std::string& name) const { return params_.count(name) > 0; }
149
150void Material::setFloat(const std::string& name, float value) { params_[name] = value; }
151
152float Material::getFloat(const std::string& name) const {
153 auto it = params_.find(name);
154 return it == params_.end() ? 0.f : it->second;
155}
156
158 if (shadingModel_ == "custom") return shader_;
159 return shader_;
160}
161
162bool Material::isTransparentHair() const { return isHair_ || shadingModel_ == "hair"; }
163
165 auto valid = validatePbrSurface(surface);
166 if (!valid) return valid;
167 pbr_ = surface;
168 pbrEnabled_ = true;
169 setShadingModel(surface.unlit ? "unlit" : "pbr");
170 pbr_.unlit = false; // Shading mode is owned by shadingModel_; DTO snapshots derive it.
171 return Result<void>::success();
172}
173
174Result<void> Material::setFoliageTranslucency(float red, float green, float blue, float intensity, float strength,
175 float normalDistortion, float scattering, float direct, float ambient,
176 float shadow) {
177 auto candidate = pbr_;
178 candidate.translucency.color = {red, green, blue};
179 candidate.translucency.intensity = intensity;
180 candidate.translucency.strength = strength;
181 candidate.translucency.normalDistortion = normalDistortion;
182 candidate.translucency.scattering = scattering;
183 candidate.translucency.direct = direct;
184 candidate.translucency.ambient = ambient;
185 candidate.translucency.shadow = shadow;
186 candidate.vegetationColor.backfaceNormalMode = PbrVegetationBackfaceNormalMode::Flip;
187 auto accepted = setPbrSurface(candidate);
188 if (!accepted) return accepted;
189 doubleSided_ = true;
190 return Result<void>::success();
191}
192
193Result<void> Material::setFoliageWind(Texture* motionTexture, Texture* noiseTexture, float directionX, float directionZ,
194 float strength, float bending, float bendingSpeed, float branch,
195 float branchSpeed, float flutter, float flutterSpeed, float fadeDistance,
196 float bendFactor) {
197 const float directionLength = std::hypot(directionX, directionZ);
198 if (!motionTexture || !noiseTexture || !std::isfinite(directionLength) || directionLength <= .0001f ||
199 !std::isfinite(strength) || strength < 0 || !std::isfinite(bendFactor) || bendFactor < 0)
200 return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "invalid foliage wind profile",
201 {}, {}, "graphics.foliage.wind"));
202 auto candidate = pbr_;
203 auto& motion = candidate.vegetationMotion;
204 motion.texture = motionTexture;
205 motion.noise = noiseTexture;
206 motion.usage.fill(0.f);
207 motion.fallback = {directionX / directionLength, directionZ / directionLength, strength, 0.f};
208 motion.globalDirection = {directionX / directionLength, directionZ / directionLength};
209 motion.bending = bending;
210 motion.bendingSpeed = bendingSpeed;
211 motion.branch = branch;
212 motion.branchSpeed = branchSpeed;
213 motion.flutter = flutter;
214 motion.flutterSpeed = flutterSpeed;
215 motion.globalBending = bendFactor;
216 motion.globalBranch = 1.f;
217 motion.globalFlutter = 1.f;
218 motion.noiseTiling = 1.f;
219 motion.fadeDistance = fadeDistance;
221 candidate.vegetationVertex.source = PbrVegetationDeformationSource::GpuFields;
222 return setPbrSurface(candidate);
223}
224
226 if (!std::isfinite(seconds) || std::abs(seconds) > 1e12 ||
229 "foliage wind is not configured or time is invalid", {}, {},
230 "graphics.foliage.wind"));
231 auto candidate = pbr_;
232 candidate.vegetationMotion.time = seconds;
233 return setPbrSurface(candidate);
234}
235
237 auto snapshot = pbr_;
238 snapshot.unlit = shadingModel_ == "unlit";
239 auto pbrStatus = gfx.setMesh3DPbrSurface(pbrEnabled_ ? &snapshot : nullptr);
240 if (!pbrStatus) return pbrStatus;
241 const BlendMode effectiveBlend =
242 pbr_.textures[0].texture && pbr_.textures[0].texture->hasPremultipliedAlpha() && blendMode_ == BlendMode::Alpha
244 : blendMode_;
245 gfx.setMesh3DSurface(surfaceMode_, effectiveBlend, depthWrite_, doubleSided_, alphaCutoff_, alphaTechnique_);
246 gfx.setMesh3DMaterial(metallic_, roughness_);
247 gfx.setMesh3DTexCellBomb(texBombScale_, texBombStrength_, texBombRot_);
248 gfx.setMesh3DNormalTexture(pbr_.textures[2].texture);
249 gfx.setMesh3DPackedNormalMask(false);
250 gfx.setMesh3DHeightTexture(height_);
251 gfx.setMesh3DVirtualTexture(virtualTextureEnabled_, virtualPageCountX_, virtualPageCountY_, virtualAtlasSlotsX_,
252 virtualAtlasSlotsY_, virtualBorderFraction_);
253 gfx.setMesh3DParallax(parallaxScale_, parallaxMinLayers_, parallaxMaxLayers_);
254 gfx.setMesh3DShadowReceive(receiveShadow_);
255
256 if (!receiveLight_ || shadingModel_ == "unlit") {
257 // Cheap toggle only: never clobber the clustered light table that the
258 // frame uploaded once (see Graphics::setMesh3DClusteredActive).
259 gfx.setMesh3DClusteredActive(false);
260 Lighting3DPack none{};
261 none.count = 0;
262 none.ambient = glm::vec4(1.f, 1.f, 1.f, 0.f);
263 gfx.setMesh3DLighting(none);
264 }
265
266 if (shader_ && !params_.empty()) {
267 for (const auto& kv : params_) {
268 if (shader_->hasUniform(kv.first)) shader_->sendFloat(kv.first, kv.second);
269 }
270 }
271 return Result<void>::success();
272}
273
274} // namespace eve::graphics
double value
std::string message
tensor::Graph g
Definition GpuGraph.cpp:7
double r
std::array< float, 3 > scale
std::string name
bool valid
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
float roughness
float metallic
bool hair
glm::mat4 model
Vec scattering
A structured explanation of a failed, degraded, or noteworthy result.
Definition Diagnostic.h:94
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
virtual void setMesh3DMaterial(float metallic, float roughness)=0
Metallic (0..1) and roughness (0..1) for the next default mesh draw.
virtual Result< void > setMesh3DPbrSurface(const PbrSurface *surface)
Copy a validated extended surface for subsequent draws; null resets to legacy shading.
Definition Graphics.h:1192
virtual void setMesh3DPackedNormalMask(bool enabled)=0
Interpret normal texture RG as tangent XY, B as AO and A as smoothness for terrain surfaces.
virtual void setMesh3DClusteredActive(bool active)=0
Cheap per-draw toggle for the already-uploaded clustered light table. Unlike setMesh3DClusteredLighti...
virtual void setMesh3DTexCellBomb(float cellScale, float strength, float rotAmount=1.f)=0
Texture cell bombing for the next default mesh draw (breaks tiling). cellScale: cells per UV unit (ty...
virtual void setMesh3DParallax(float scale, float minLayers=8.f, float maxLayers=32.f)=0
Parallax occlusion mapping for the next default mesh draw. scale: UV displacement strength (0=off)....
virtual void setMesh3DVirtualTexture(bool enabled, int pageCountX, int pageCountY, int atlasSlotsX, int atlasSlotsY, float borderFraction)=0
Configure page-table sampling for the next mesh draw.
virtual void setMesh3DSurface(SurfaceMode mode, BlendMode blend, bool depthWrite, bool doubleSided, float alphaCutoff, const std::string &alphaTechnique="cutoff")=0
Select pipeline state for subsequent mesh draws.
virtual void setMesh3DShadowReceive(bool receive)=0
Per-draw: when false, shadow sampling is forced off for the next mesh draw.
virtual void setMesh3DNormalTexture(Texture *normal)=0
Optional normal map for the next drawMesh / drawMeshShader (nullptr = flat).
virtual void setMesh3DHeightTexture(Texture *height)=0
Optional height map for parallax (R channel; nullptr = flat / off).
virtual void setMesh3DLighting(const Lighting3DPack &pack)=0
Per-frame ambient + up to 8 lights packed into Mesh3DUBO.
float getFloat(const std::string &name) const
Returns the float.
Definition Material.cpp:152
bool hasParam(const std::string &name) const
Optional named float knobs (style / custom shader params).
Definition Material.cpp:148
void setAlphaTechnique(const std::string &technique)
Optional masked transparency quality: "cutoff", "dither", "coverage".
Definition Material.cpp:144
void setBlendMode(const std::string &mode)
Set "alpha", "premultiplied", "additive", or "multiply".
Definition Material.cpp:126
std::string getBlendMode() const
Returns the blend mode.
Definition Material.cpp:137
void setMetallic(float metallic)
Sets the metallic.
Definition Material.cpp:74
void clearVirtualTexture()
Restore conventional albedo/normal/height interpretation.
Definition Material.cpp:40
void setRoughness(float roughness)
Sets the roughness.
Definition Material.cpp:76
Result< void > setPbrSurface(const PbrSurface &surface)
Atomically replace validated PBR bindings and enable the extended forward path. Texture pointers are ...
Definition Material.cpp:164
bool isTransparentHair() const
True when this material should go through the hair transparent pass.
Definition Material.cpp:162
void setAlphaCutoff(float cutoff)
Sets the alpha cutoff.
Definition Material.cpp:124
eve::Result< void > setVirtualTexture(Texture *albedoAtlas, Texture *normalAtlas, Texture *pageTable, int pageCountX, int pageCountY, int atlasSlotsX, int atlasSlotsY, float borderFraction)
Opt this material into physical-atlas virtual-texture sampling.
Definition Material.cpp:17
void setSurfaceMode(const std::string &mode)
Set "opaque", "masked", or "transparent" surface classification.
Definition Material.cpp:109
void setShadingModel(const std::string &model)
"pbr" | "unlit" | "hair" | "custom" (unknown → pbr).
Definition Material.cpp:49
void setTexCellBomb(float cellScale, float strength, float rotAmount=1.f)
Sets the tex cell bomb.
Definition Material.cpp:80
Result< void > setFoliageTranslucency(float red, float green, float blue, float intensity, float strength, float normalDistortion, float scattering, float direct, float ambient, float shadow)
Enable validated two-sided foliage translucency while preserving imported PBR textures and factors.
Definition Material.cpp:174
void setTint(float r, float g, float b, float a=1.f)
Sets the tint.
Definition Material.cpp:67
std::string getSurfaceMode() const
Returns the surface mode.
Definition Material.cpp:118
void setParallax(float scale, float minLayers=8.f, float maxLayers=32.f)
Sets the parallax.
Definition Material.cpp:86
Result< void > bind(Graphics &gfx) const
Push this material onto Graphics mesh3d state for the next draw. Does not issue the draw itself.
Definition Material.cpp:236
Result< void > setFoliageWindTime(float seconds)
Replace only the explicit foliage-motion time in the current material snapshot.
Definition Material.cpp:225
void setFloat(const std::string &name, float value)
Sets the float.
Definition Material.cpp:150
Shader * effectiveShader() const
Return the borrowed effective shader, or nullptr for the default PBR pipeline. @lifetime The pointer ...
Definition Material.cpp:157
Result< void > setFoliageWind(Texture *motionTexture, Texture *noiseTexture, float directionX, float directionZ, float strength, float bending, float bendingSpeed, float branch, float branchSpeed, float flutter, float flutterSpeed, float fadeDistance, float bendFactor)
Publish object-space foliage wind while preserving the current PBR material snapshot.
Definition Material.cpp:193
void setHair(bool hair)
Sets the hair.
Definition Material.cpp:95
Custom GPU program.
Definition Shader.h:39
bool hasUniform(const std::string &name) const
Definition Shader.cpp:59
void sendFloat(const std::string &name, float x)
Definition Shader.cpp:95
GPU texture created via Graphics::newTexture. Owns GPU resources through an opaque backend handle.
Definition Texture.h:18
卡牌游戏 UI 工具模块:工厂 + 脚本绑定入口。 功能参考 ycarowr/UiCard:扇形手牌布局、抽牌/洗牌、悬浮放大、拖拽到落牌区、 敌方手牌(背面/偷看)、费用不足置灰,以及可实时调节的布局...
Definition Animation.h:25
Result< void > validatePbrSurface(const PbrSurface &s)
Validate finite material factors and sampler enums without changing the input.
Definition PbrSurface.cpp:4
BlendMode
Render-neutral 2D blend mode shared by graphics-facing modules.
Definition RenderTypes.h:11
Lighting3DPack public API.
Definition Light.h:172
Owning material parameter snapshot; texture pointers remain borrowed. Base color/metallic/roughness c...
Definition PbrSurface.h:218
PbrVegetationMotion vegetationMotion
Definition PbrSurface.h:259
std::array< PbrTextureBinding, std::size_t(PbrTextureSlot::Count)> textures
Definition PbrSurface.h:219
PbrTranslucency translucency
Per-light vegetation backlighting. Native ambient RGB supplies the GI term. Positive maskAmount with ...
Definition PbrSurface.h:253
std::array< float, 3 > color
Definition PbrSurface.h:60
PbrVegetationMotionMode mode
Definition PbrSurface.h:187
glm::vec4 ambient