载入中...
搜索中...
未找到
MaterialRuntime.cpp
浏览该文件的文档.
2
3// Optional graphics adapter for the renderer-neutral material authoring contract.
4
6
7#include "ECS.hpp"
8
9namespace eve::material_editing {
10namespace {
11
12const EditorValue::Object* properties(const MaterialDocumentTarget& target,
13 EditorValue& snapshot) {
14 snapshot = target.snapshotValue();
15 const auto* root = snapshot.getIf<EditorValue::Object>();
16 if (!root) return nullptr;
17 const auto found = root->find("properties");
18 return found == root->end() ? nullptr : found->second.getIf<EditorValue::Object>();
19}
20
21template <class T>
22const T* value(const EditorValue::Object& properties, const char* path) {
23 const auto found = properties.find(path);
24 return found == properties.end() ? nullptr : found->second.getIf<T>();
25}
26
27template <class T, class Resolver>
28Result<T*> resolveAsset(const std::string& asset, Resolver&& resolver) {
29 if (asset.empty()) return eve::editing::applied<T*>(nullptr);
30 return resolver(asset);
31}
32
33} // namespace
34
36 ecs::EntityHandle handle;
37 const IMaterialRuntimeAssetResolver* assets = nullptr;
38};
39
40Renderable3DMaterialRuntimeSink::Renderable3DMaterialRuntimeSink(
41 graphics::Renderable3D* renderable, const IMaterialRuntimeAssetResolver* assets)
42 : impl_(std::make_unique<Impl>()) {
43 impl_->handle = ecs::handle_of(renderable);
44 impl_->assets = assets;
45}
46
47double number(const EditorValue& value) {
48 if (const auto* real = value.getIf<double>()) return *real;
49 if (const auto* integer = value.getIf<std::int64_t>()) return static_cast<double>(*integer);
50 return 0.0;
51}
52
53Renderable3DMaterialRuntimeSink::~Renderable3DMaterialRuntimeSink() = default;
54
55Result<void> Renderable3DMaterialRuntimeSink::publish(
56 const MaterialDocumentTarget& candidate) {
57 if (!impl_->assets)
58 return eve::editing::failed<void>(EditorStatus::Rejected, RuleId("editor.material.runtime-input"),
59 "Material asset resolver is required");
60 auto* renderable = dynamic_cast<graphics::Renderable3D*>(ecs::try_get(impl_->handle));
61 if (!renderable)
62 return eve::editing::failed<void>(EditorStatus::Conflict, RuleId("editor.material.runtime-stale"),
63 "Renderable3D handle is missing or stale");
64 const auto diagnostics = candidate.validate();
65 for (const EditorDiagnostic& diagnostic : diagnostics) {
66 if (diagnostic.severity() == DiagnosticSeverity::Error)
67 return Result<void>::failure(eve::Status(EditorStatus::Rejected, diagnostics));
68 }
69 EditorValue snapshot;
70 const auto* values = properties(candidate, snapshot);
71 if (!values)
72 return eve::editing::failed<void>(EditorStatus::Failed, RuleId("editor.material.runtime-properties"),
73 "Material properties are unavailable");
74 const bool vegetationAlpha = *value<bool>(*values, "vegetation.alpha.enabled");
75 const bool vegetationEmission = *value<bool>(*values, "vegetation.emission.enabled");
76 const bool vegetationGradient = *value<bool>(*values, "vegetation.gradient.enabled");
77 const bool vegetationTranslucency = *value<bool>(*values, "vegetation.translucency.enabled");
78 const bool vegetationColor = *value<bool>(*values, "vegetation.color.enabled");
79 const bool vegetationDetail = *value<bool>(*values, "vegetation.detail.enabled");
80 const bool vegetationExtras = *value<bool>(*values, "vegetation.extras.enabled");
81 const bool vegetationColors = *value<bool>(*values, "vegetation.colors.enabled");
82 const bool vegetationVertex = *value<bool>(*values, "vegetation.vertex.enabled");
83 const bool vegetationMotion = *value<std::string>(*values, "vegetation.motion.mode") == "object";
84 const bool extendedTextures = !value<std::string>(*values, "textures.orm")->empty() ||
85 !value<std::string>(*values, "textures.emissive")->empty();
86 const bool vegetationExtended =
87 vegetationAlpha || vegetationEmission || vegetationGradient || vegetationTranslucency || vegetationColor ||
88 vegetationDetail || vegetationExtras || vegetationColors || vegetationVertex || vegetationMotion ||
89 extendedTextures;
90 const auto& surfaceMode = *value<std::string>(*values, "surface.mode");
91 if (*value<std::string>(*values, "shading.model") != "pbr" ||
92 (surfaceMode != "opaque" && !(vegetationAlpha && surfaceMode == "masked")) ||
93 *value<std::string>(*values, "surface.blend") != "alpha" ||
94 *value<bool>(*values, "surface.double-sided"))
95 return eve::editing::failed<void>(EditorStatus::Unsupported, RuleId("editor.material.runtime-legacy-surface"),
96 "Legacy Renderable3D supports PBR opaque single-sided materials only");
97
98 std::array<graphics::Texture*, 14> textures{};
99 constexpr const char* texturePaths[] = {
100 "textures.albedo", "textures.normal", "textures.height",
101 "textures.orm", "textures.emissive", "vegetation.alpha.noise",
102 "vegetation.detail.albedo", "vegetation.detail.normal", "vegetation.detail.mask",
103 "vegetation.extras.texture", "vegetation.colors.texture", "vegetation.vertex.texture",
104 "vegetation.motion.texture", "vegetation.motion.noise"};
105 const std::array<bool, 14> textureEnabled = {true,
106 true,
107 true,
108 true,
109 true,
110 vegetationAlpha,
111 vegetationDetail,
112 vegetationDetail,
113 vegetationDetail,
114 vegetationExtras,
115 vegetationColors,
116 vegetationVertex,
117 vegetationMotion,
118 vegetationMotion};
119 for (std::size_t i = 0; i < textures.size(); ++i) {
120 if (!textureEnabled[i]) continue;
121 auto resolved = resolveAsset<graphics::Texture>(
122 *value<std::string>(*values, texturePaths[i]),
123 [&](const std::string& asset) { return impl_->assets->resolveTexture(asset); });
124 if (!resolved.ok()) return Result<void>::failure(resolved.status());
125 textures[i] = resolved.value();
126 }
127 auto shader = resolveAsset<graphics::Shader>(
128 *value<std::string>(*values, "textures.shader"),
129 [&](const std::string& asset) { return impl_->assets->resolveShader(asset); });
130 if (!shader.ok()) return Result<void>::failure(shader.status());
131
132 graphics::Material* runtimeMaterial = renderable->getMaterial();
133 if (vegetationExtended && !runtimeMaterial)
134 return eve::editing::failed<void>(EditorStatus::Unsupported,
135 RuleId("editor.material.runtime-vegetation-material"),
136 "Extended PBR vegetation editing requires a Material bound to Renderable3D");
137 if (runtimeMaterial && (vegetationExtended || runtimeMaterial->hasPbrSurface())) {
138 graphics::PbrSurface surface = runtimeMaterial->pbrSurface();
139 surface.vegetationAlpha.enabled = vegetationAlpha;
140 surface.vegetationAlpha.noise = textures[5];
141 surface.vegetationAlpha.global = float(*value<double>(*values, "vegetation.alpha.global"));
142 surface.vegetationAlpha.variation = float(*value<double>(*values, "vegetation.alpha.variation"));
143 surface.vegetationAlpha.glancing = float(*value<double>(*values, "vegetation.alpha.glancing"));
144 surface.vegetationAlpha.camera = float(*value<double>(*values, "vegetation.alpha.camera"));
145 surface.vegetationAlpha.constant = float(*value<double>(*values, "vegetation.alpha.constant"));
146 surface.vegetationAlpha.cameraFadeMin = float(*value<double>(*values, "vegetation.alpha.camera-min"));
147 surface.vegetationAlpha.cameraFadeMax = float(*value<double>(*values, "vegetation.alpha.camera-max"));
148 surface.vegetationAlpha.noiseTiling = float(*value<double>(*values, "vegetation.alpha.noise-tiling"));
149 surface.vegetationAlpha.detailFade = *value<bool>(*values, "vegetation.alpha.detail-fade");
150 surface.vegetationEmission.enabled = vegetationEmission;
151 surface.vegetationEmission.minimum = float(*value<double>(*values, "vegetation.emission.minimum"));
152 surface.vegetationEmission.maximum = float(*value<double>(*values, "vegetation.emission.maximum"));
153 surface.vegetationEmission.phase = float(*value<double>(*values, "vegetation.emission.phase"));
154 surface.vegetationEmission.global = float(*value<double>(*values, "vegetation.emission.global"));
155 surface.vegetationGradient.enabled = vegetationGradient;
156 const auto& gradientOne = *value<EditorValue::Array>(*values, "vegetation.gradient.color-one");
157 const auto& gradientTwo = *value<EditorValue::Array>(*values, "vegetation.gradient.color-two");
158 for (std::size_t i = 0; i < 3; ++i) {
159 surface.vegetationGradient.colorOne[i] = float(number(gradientOne[i]));
160 surface.vegetationGradient.colorTwo[i] = float(number(gradientTwo[i]));
161 }
162 surface.vegetationGradient.minimum = float(*value<double>(*values, "vegetation.gradient.minimum"));
163 surface.vegetationGradient.maximum = float(*value<double>(*values, "vegetation.gradient.maximum"));
164 auto& ormBinding = surface.textures[std::size_t(graphics::PbrTextureSlot::MetallicRoughness)];
165 ormBinding.texture = textures[3];
166 ormBinding.srgbDecode = false;
167 auto& emissiveBinding = surface.textures[std::size_t(graphics::PbrTextureSlot::Emissive)];
168 emissiveBinding.texture = textures[4];
169 emissiveBinding.srgbDecode = true;
170 surface.translucency.intensity =
171 vegetationTranslucency ? float(*value<double>(*values, "vegetation.translucency.intensity")) : 0.f;
172 const auto& transColor = *value<EditorValue::Array>(*values, "vegetation.translucency.color");
173 for (std::size_t i = 0; i < 3; ++i) surface.translucency.color[i] = float(number(transColor[i]));
174 surface.translucency.strength = float(*value<double>(*values, "vegetation.translucency.strength"));
175 surface.translucency.normalDistortion =
176 float(*value<double>(*values, "vegetation.translucency.normal-distortion"));
177 surface.translucency.scattering = float(*value<double>(*values, "vegetation.translucency.scattering"));
178 surface.translucency.direct = float(*value<double>(*values, "vegetation.translucency.direct"));
179 surface.translucency.ambient = float(*value<double>(*values, "vegetation.translucency.ambient"));
180 surface.translucency.shadow = float(*value<double>(*values, "vegetation.translucency.shadow"));
181 surface.translucency.maskAmount =
182 vegetationTranslucency ? float(*value<double>(*values, "vegetation.translucency.mask-amount")) : 0.f;
183 surface.translucency.globalIntensity = float(*value<double>(*values, "vegetation.translucency.global"));
184 surface.translucency.overlay = float(*value<double>(*values, "vegetation.translucency.overlay"));
185 surface.translucency.maskMinimum =
186 float(*value<double>(*values, "vegetation.translucency.mask-minimum"));
187 surface.translucency.maskMaximum =
188 float(*value<double>(*values, "vegetation.translucency.mask-maximum"));
189 surface.vegetationColor = {};
190 if (vegetationColor) {
191 const auto& field = *value<EditorValue::Array>(*values, "vegetation.color.field");
192 const auto& overlay = *value<EditorValue::Array>(*values, "vegetation.color.overlay-color");
193 const auto& occlusion =
194 *value<EditorValue::Array>(*values, "vegetation.color.vertex-occlusion-color");
195 for (std::size_t i = 0; i < 4; ++i) surface.vegetationColor.fieldColor[i] = float(number(field[i]));
196 for (std::size_t i = 0; i < 3; ++i) {
197 surface.vegetationColor.overlayColor[i] = float(number(overlay[i]));
198 surface.vegetationColor.vertexOcclusionColor[i] = float(number(occlusion[i]));
199 }
200 const auto scalar = [&](const char* name) {
201 return float(*value<double>(*values, (std::string("vegetation.color.") + name).c_str()));
202 };
203 surface.vegetationColor.overlay = scalar("overlay");
204 surface.vegetationColor.wetness = scalar("wetness");
205 surface.vegetationColor.overlayVariation = scalar("overlay-variation");
206 surface.vegetationColor.overlayProjection = scalar("overlay-projection");
207 surface.vegetationColor.vertexOcclusionAlpha = scalar("vertex-occlusion-alpha");
208 surface.vegetationColor.overlayNormalScale = scalar("overlay-normal");
209 surface.vegetationColor.wetnessNormalScale = scalar("wetness-normal");
210 surface.vegetationColor.overlaySmoothness = scalar("overlay-smoothness");
211 surface.vegetationColor.wetnessContrast = scalar("wetness-contrast");
212 surface.vegetationColor.overlaySubsurface = scalar("overlay-subsurface");
213 surface.vegetationColor.colorsCoverage = scalar("colors-coverage");
214 surface.vegetationColor.colorsIntensity = scalar("colors-intensity");
215 surface.vegetationColor.colorsMask = scalar("colors-mask");
216 surface.vegetationColor.colorsVariation = scalar("colors-variation");
217 surface.vegetationColor.globalColorMaskMinimum = scalar("color-mask-minimum");
218 surface.vegetationColor.globalColorMaskMaximum = scalar("color-mask-maximum");
219 surface.vegetationColor.globalOverlayMaskMinimum = scalar("overlay-mask-minimum");
220 surface.vegetationColor.globalOverlayMaskMaximum = scalar("overlay-mask-maximum");
221 surface.vegetationColor.globalAlphaThresholdOffset = scalar("alpha-threshold-offset");
222 surface.vegetationColor.vertexOcclusionMinimum = scalar("vertex-occlusion-minimum");
223 surface.vegetationColor.vertexOcclusionMaximum = scalar("vertex-occlusion-maximum");
224 surface.vegetationColor.invertVertexOcclusion =
225 *value<bool>(*values, "vegetation.color.invert-vertex-occlusion");
226 surface.vegetationColor.invertVertexOcclusionColors =
227 *value<bool>(*values, "vegetation.color.invert-vertex-occlusion-colors");
228 const auto& backface = *value<std::string>(*values, "vegetation.color.backface-normal");
229 surface.vegetationColor.backfaceNormalMode =
233 }
234 surface.vegetationDetail = {};
235 if (vegetationDetail) {
236 auto& detail = surface.vegetationDetail;
237 detail.textures[0].texture = textures[6];
238 detail.textures[0].srgbDecode = true;
239 detail.textures[1].texture = textures[7];
240 detail.textures[1].srgbDecode = false;
241 detail.textures[2].texture = textures[8];
242 detail.textures[2].srgbDecode = false;
243 const auto& color = *value<EditorValue::Array>(*values, "vegetation.detail.color");
244 const auto& colorTwo = *value<EditorValue::Array>(*values, "vegetation.detail.color-two");
245 const auto& uvScale = *value<EditorValue::Array>(*values, "vegetation.detail.uv-scale");
246 const auto& uvOffset = *value<EditorValue::Array>(*values, "vegetation.detail.uv-offset");
247 for (std::size_t i = 0; i < 4; ++i) {
248 detail.color[i] = float(number(color[i]));
249 detail.colorTwo[i] = float(number(colorTwo[i]));
250 }
251 for (std::size_t i = 0; i < 2; ++i) {
252 detail.uvScale[i] = float(number(uvScale[i]));
253 detail.uvOffset[i] = float(number(uvOffset[i]));
254 }
255 const auto detailScalar = [&](const char* name) {
256 return float(*value<double>(*values, (std::string("vegetation.detail.") + name).c_str()));
257 };
258 detail.value = detailScalar("value");
259 detail.normalValue = detailScalar("normal-value");
260 detail.normalBlendValue = detailScalar("normal-blend");
261 detail.albedoValue = detailScalar("albedo-value");
262 detail.metallicValue = detailScalar("metallic");
263 detail.occlusionValue = detailScalar("occlusion");
264 detail.smoothnessValue = detailScalar("smoothness");
265 detail.blendMinimum = detailScalar("blend-minimum");
266 detail.blendMaximum = detailScalar("blend-maximum");
267 detail.maskMinimum = detailScalar("mask-minimum");
268 detail.maskMaximum = detailScalar("mask-maximum");
269 detail.meshMinimum = detailScalar("mesh-minimum");
270 detail.meshMaximum = detailScalar("mesh-maximum");
271 detail.inverseUvScale = *value<bool>(*values, "vegetation.detail.inverse-uv-scale");
272 const auto& uvMode = *value<std::string>(*values, "vegetation.detail.uv-mode");
273 detail.uvMode = uvMode == "world" ? 2u : uvMode == "detail" ? 1u : 0u;
274 detail.colorMode = *value<std::string>(*values, "vegetation.detail.color-mode") == "variation";
275 detail.blendMode = *value<std::string>(*values, "vegetation.detail.blend-mode") == "replace";
276 detail.alphaMode = *value<std::string>(*values, "vegetation.detail.alpha-mode") == "detail";
277 detail.maskMode = *value<std::string>(*values, "vegetation.detail.mask-mode") == "inverse";
278 detail.meshMode = *value<std::string>(*values, "vegetation.detail.mesh-mode") == "inverse";
279 }
280 const auto publishField = [&](const char* group, auto& field, graphics::Texture* texture) {
281 const std::string prefix = std::string("vegetation.") + group;
282 field.texture = texture;
283 field.layer = uint32_t(*value<std::int64_t>(*values, (prefix + ".layer").c_str()));
284 field.usePivotPosition = *value<bool>(*values, (prefix + ".use-pivot-position").c_str());
285 const auto& fallback = *value<EditorValue::Array>(*values, (prefix + ".fallback").c_str());
286 const auto& coords = *value<EditorValue::Array>(*values, (prefix + ".coords").c_str());
287 for (std::size_t i = 0; i < 4; ++i) {
288 field.fallback[i] = float(number(fallback[i]));
289 field.coords[i] = float(number(coords[i]));
290 }
291 for (std::size_t i = 0; i < field.usage.size(); ++i) {
292 const std::string path = prefix + ".usage-" + std::to_string(i);
293 field.usage[i] = float(*value<double>(*values, path.c_str()));
294 }
295 };
296 surface.vegetationExtras = {};
297 if (vegetationExtras) publishField("extras", surface.vegetationExtras, textures[9]);
298 surface.vegetationColors = {};
299 if (vegetationColors) publishField("colors", surface.vegetationColors, textures[10]);
300 surface.vegetationVertex = {};
301 if (vegetationVertex) {
302 auto& vertex = surface.vegetationVertex;
303 vertex.texture = textures[11];
304 vertex.layer = uint32_t(*value<std::int64_t>(*values, "vegetation.vertex.layer"));
305 const auto& fallback = *value<EditorValue::Array>(*values, "vegetation.vertex.fallback");
306 const auto& coords = *value<EditorValue::Array>(*values, "vegetation.vertex.coords");
307 for (std::size_t i = 0; i < 4; ++i) {
308 vertex.fallback[i] = float(number(fallback[i]));
309 vertex.coords[i] = float(number(coords[i]));
310 }
311 for (std::size_t i = 0; i < vertex.usage.size(); ++i) {
312 const std::string path = "vegetation.vertex.usage-" + std::to_string(i);
313 vertex.usage[i] = float(*value<double>(*values, path.c_str()));
314 }
315 vertex.globalSize = float(*value<double>(*values, "vegetation.vertex.global-size"));
316 vertex.sizeFadeStart = float(*value<double>(*values, "vegetation.vertex.size-fade-start"));
317 vertex.sizeFadeEnd = float(*value<double>(*values, "vegetation.vertex.size-fade-end"));
318 vertex.distanceFadeBias = float(*value<double>(*values, "vegetation.vertex.distance-fade-bias"));
319 const auto& source = *value<std::string>(*values, "vegetation.vertex.source");
320 vertex.source = source == "gpu-fields"
322 : source == "cpu-deformed"
325 }
326 surface.vegetationMotion = {};
327 if (vegetationMotion) {
328 auto& motion = surface.vegetationMotion;
329 motion.texture = textures[12];
330 motion.noise = textures[13];
332 motion.layer = uint32_t(*value<std::int64_t>(*values, "vegetation.motion.layer"));
333 const auto& fallback = *value<EditorValue::Array>(*values, "vegetation.motion.fallback");
334 const auto& coords = *value<EditorValue::Array>(*values, "vegetation.motion.coords");
335 const auto& direction = *value<EditorValue::Array>(*values, "vegetation.motion.global-direction");
336 const auto& origin = *value<EditorValue::Array>(*values, "vegetation.motion.world-origin");
337 for (std::size_t i = 0; i < 4; ++i) {
338 motion.fallback[i] = float(number(fallback[i]));
339 motion.coords[i] = float(number(coords[i]));
340 }
341 for (std::size_t i = 0; i < 2; ++i) motion.globalDirection[i] = float(number(direction[i]));
342 for (std::size_t i = 0; i < 3; ++i) motion.worldOrigin[i] = float(number(origin[i]));
343 for (std::size_t i = 0; i < motion.usage.size(); ++i) {
344 const std::string path = "vegetation.motion.usage-" + std::to_string(i);
345 motion.usage[i] = float(*value<double>(*values, path.c_str()));
346 }
347 const auto scalar = [&](const char* name) {
348 const std::string path = std::string("vegetation.motion.") + name;
349 return float(*value<double>(*values, path.c_str()));
350 };
351 motion.time = *value<double>(*values, "vegetation.motion.time");
352 motion.dynamicMode = scalar("dynamic-mode");
353 motion.rigidity = scalar("rigidity");
354 motion.facing = scalar("facing");
355 motion.bending = scalar("bending");
356 motion.bendingSpeed = scalar("bending-speed");
357 motion.bendingScale = scalar("bending-scale");
358 motion.bendingVariation = scalar("bending-variation");
359 motion.branch = scalar("branch");
360 motion.rolling = scalar("rolling");
361 motion.branchSpeed = scalar("branch-speed");
362 motion.branchScale = scalar("branch-scale");
363 motion.branchVariation = scalar("branch-variation");
364 motion.flutter = scalar("flutter");
365 motion.flutterSpeed = scalar("flutter-speed");
366 motion.flutterScale = scalar("flutter-scale");
367 motion.flutterVariation = scalar("flutter-variation");
368 motion.globalBending = scalar("global-bending");
369 motion.globalBranch = scalar("global-branch");
370 motion.globalFlutter = scalar("global-flutter");
371 motion.noiseTiling = scalar("noise-tiling");
372 motion.interaction = scalar("interaction");
373 motion.interactionMask = scalar("interaction-mask");
374 motion.fadeDistance = scalar("fade-distance");
375 motion.perspectivePush = scalar("perspective-push");
376 motion.perspectiveNoise = scalar("perspective-noise");
377 motion.perspectiveAngle = scalar("perspective-angle");
378 }
379 auto published = runtimeMaterial->setPbrSurface(surface);
380 if (!published)
381 return eve::editing::failed<void>(EditorStatus::Rejected,
382 RuleId("editor.material.runtime-vegetation-invalid"),
383 published.error()->message());
384 }
385
386 const auto& tint = *value<EditorValue::Array>(*values, "shading.tint");
387 if (runtimeMaterial) {
388 runtimeMaterial->setAlbedoTexture(textures[0]);
389 runtimeMaterial->setNormalTexture(textures[1]);
390 runtimeMaterial->setHeightTexture(textures[2]);
391 runtimeMaterial->setShader(shader.value());
392 runtimeMaterial->setTint(static_cast<float>(number(tint[0])), static_cast<float>(number(tint[1])),
393 static_cast<float>(number(tint[2])), static_cast<float>(number(tint[3])));
394 runtimeMaterial->setMetallic(static_cast<float>(*value<double>(*values, "shading.metallic")));
395 runtimeMaterial->setRoughness(static_cast<float>(*value<double>(*values, "shading.roughness")));
396 runtimeMaterial->setParallax(static_cast<float>(*value<double>(*values, "parallax.scale")));
397 runtimeMaterial->setReceiveLight(*value<bool>(*values, "lighting.receive"));
398 runtimeMaterial->setCastShadow(*value<bool>(*values, "shadow.cast"));
399 runtimeMaterial->setReceiveShadow(*value<bool>(*values, "shadow.receive"));
400 runtimeMaterial->setSurfaceMode(surfaceMode);
401 runtimeMaterial->setAlphaCutoff(static_cast<float>(*value<double>(*values, "surface.alpha-cutoff")));
402 runtimeMaterial->setDepthWrite(*value<bool>(*values, "surface.depth-write"));
403 runtimeMaterial->setDoubleSided(*value<bool>(*values, "surface.double-sided"));
404 return eve::editing::applied<void>();
405 }
406 renderable->setTexture(textures[0]);
407 renderable->setNormalTexture(textures[1]);
408 renderable->setHeightTexture(textures[2]);
409 renderable->setShader(shader.value());
410 renderable->setTint(static_cast<float>(number(tint[0])),
411 static_cast<float>(number(tint[1])),
412 static_cast<float>(number(tint[2])),
413 static_cast<float>(number(tint[3])));
414 renderable->setMetallic(static_cast<float>(*value<double>(*values, "shading.metallic")));
415 renderable->setRoughness(static_cast<float>(*value<double>(*values, "shading.roughness")));
416 renderable->setParallax(static_cast<float>(*value<double>(*values, "parallax.scale")));
417 renderable->setReceiveLight(*value<bool>(*values, "lighting.receive"));
418 renderable->setCastShadow(*value<bool>(*values, "shadow.cast"));
419 renderable->setReceiveShadow(*value<bool>(*values, "shadow.receive"));
420 return eve::editing::applied<void>();
421}
422
423} // namespace eve::material_editing
LogicalId target
double value
int root
Definition AnimSmr.cpp:119
building::EdgeCurveGroup group
std::map< std::string, Var > values
glm::vec4 tint
float u
Definition Grass.cpp:233
std::map< std::string, PropertyRule > properties
std::string name
std::string path
Definition PlayHost.cpp:110
int detail
Shader * shader
SurfaceMode surfaceMode
V3 origin
Definition RoadBake.cpp:138
RoadLaneDirection direction
double number
bool found
const UnitySourceAsset & source
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
Structured status and zero or more diagnostics for an operation.
Definition Status.h:68
Deterministic owning value tree shared by authoring hosts.
std::map< std::string, Value > Object
EVENGINE_API_BACKENDS public API.
editing::Diagnostic EditorDiagnostic
editing::Value EditorValue
const EditorValue * field(const EditorValue &value, const char *name)
glm::vec4 color