1 | /**************************************************************************/ |
2 | /* material.cpp */ |
3 | /**************************************************************************/ |
4 | /* This file is part of: */ |
5 | /* GODOT ENGINE */ |
6 | /* https://godotengine.org */ |
7 | /**************************************************************************/ |
8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ |
9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ |
10 | /* */ |
11 | /* Permission is hereby granted, free of charge, to any person obtaining */ |
12 | /* a copy of this software and associated documentation files (the */ |
13 | /* "Software"), to deal in the Software without restriction, including */ |
14 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ |
16 | /* permit persons to whom the Software is furnished to do so, subject to */ |
17 | /* the following conditions: */ |
18 | /* */ |
19 | /* The above copyright notice and this permission notice shall be */ |
20 | /* included in all copies or substantial portions of the Software. */ |
21 | /* */ |
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ |
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ |
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ |
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
29 | /**************************************************************************/ |
30 | |
31 | #include "material.h" |
32 | |
33 | #include "core/config/engine.h" |
34 | #include "core/config/project_settings.h" |
35 | #include "core/error/error_macros.h" |
36 | #include "core/version.h" |
37 | #include "scene/main/scene_tree.h" |
38 | #include "scene/scene_string_names.h" |
39 | |
40 | void Material::set_next_pass(const Ref<Material> &p_pass) { |
41 | for (Ref<Material> pass_child = p_pass; pass_child != nullptr; pass_child = pass_child->get_next_pass()) { |
42 | ERR_FAIL_COND_MSG(pass_child == this, "Can't set as next_pass one of its parents to prevent crashes due to recursive loop." ); |
43 | } |
44 | |
45 | if (next_pass == p_pass) { |
46 | return; |
47 | } |
48 | |
49 | next_pass = p_pass; |
50 | RID next_pass_rid; |
51 | if (next_pass.is_valid()) { |
52 | next_pass_rid = next_pass->get_rid(); |
53 | } |
54 | RS::get_singleton()->material_set_next_pass(material, next_pass_rid); |
55 | } |
56 | |
57 | Ref<Material> Material::get_next_pass() const { |
58 | return next_pass; |
59 | } |
60 | |
61 | void Material::set_render_priority(int p_priority) { |
62 | ERR_FAIL_COND(p_priority < RENDER_PRIORITY_MIN); |
63 | ERR_FAIL_COND(p_priority > RENDER_PRIORITY_MAX); |
64 | render_priority = p_priority; |
65 | RS::get_singleton()->material_set_render_priority(material, p_priority); |
66 | } |
67 | |
68 | int Material::get_render_priority() const { |
69 | return render_priority; |
70 | } |
71 | |
72 | RID Material::get_rid() const { |
73 | return material; |
74 | } |
75 | |
76 | void Material::_validate_property(PropertyInfo &p_property) const { |
77 | if (!_can_do_next_pass() && p_property.name == "next_pass" ) { |
78 | p_property.usage = PROPERTY_USAGE_NONE; |
79 | } |
80 | if (!_can_use_render_priority() && p_property.name == "render_priority" ) { |
81 | p_property.usage = PROPERTY_USAGE_NONE; |
82 | } |
83 | } |
84 | |
85 | void Material::_mark_initialized(const Callable &p_queue_shader_change_callable) { |
86 | // If this is happening as part of resource loading, it is not safe to queue the update |
87 | // as an addition to the dirty list, unless the load is happening on the main thread. |
88 | if (ResourceLoader::is_within_load() && Thread::get_caller_id() != Thread::get_main_id()) { |
89 | DEV_ASSERT(init_state != INIT_STATE_READY); |
90 | if (init_state == INIT_STATE_UNINITIALIZED) { // Prevent queueing twice. |
91 | // Let's mark this material as being initialized. |
92 | init_state = INIT_STATE_INITIALIZING; |
93 | // Knowing that the ResourceLoader will eventually feed deferred calls into the main message queue, let's do these: |
94 | // 1. Queue setting the init state to INIT_STATE_READY finally. |
95 | callable_mp(this, &Material::_mark_initialized).bind(p_queue_shader_change_callable).call_deferred(); |
96 | // 2. Queue an individual update of this material. |
97 | p_queue_shader_change_callable.call_deferred(); |
98 | } |
99 | } else { |
100 | // Straightforward conditions. |
101 | init_state = INIT_STATE_READY; |
102 | p_queue_shader_change_callable.callv(Array()); |
103 | } |
104 | } |
105 | |
106 | void Material::inspect_native_shader_code() { |
107 | SceneTree *st = Object::cast_to<SceneTree>(OS::get_singleton()->get_main_loop()); |
108 | RID shader = get_shader_rid(); |
109 | if (st && shader.is_valid()) { |
110 | st->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, "_native_shader_source_visualizer" , "_inspect_shader" , shader); |
111 | } |
112 | } |
113 | |
114 | RID Material::get_shader_rid() const { |
115 | RID ret; |
116 | GDVIRTUAL_REQUIRED_CALL(_get_shader_rid, ret); |
117 | return ret; |
118 | } |
119 | Shader::Mode Material::get_shader_mode() const { |
120 | Shader::Mode ret = Shader::MODE_MAX; |
121 | GDVIRTUAL_REQUIRED_CALL(_get_shader_mode, ret); |
122 | return ret; |
123 | } |
124 | |
125 | bool Material::_can_do_next_pass() const { |
126 | bool ret = false; |
127 | GDVIRTUAL_CALL(_can_do_next_pass, ret); |
128 | return ret; |
129 | } |
130 | |
131 | bool Material::_can_use_render_priority() const { |
132 | bool ret = false; |
133 | GDVIRTUAL_CALL(_can_use_render_priority, ret); |
134 | return ret; |
135 | } |
136 | |
137 | Ref<Resource> Material::create_placeholder() const { |
138 | Ref<PlaceholderMaterial> placeholder; |
139 | placeholder.instantiate(); |
140 | return placeholder; |
141 | } |
142 | |
143 | void Material::_bind_methods() { |
144 | ClassDB::bind_method(D_METHOD("set_next_pass" , "next_pass" ), &Material::set_next_pass); |
145 | ClassDB::bind_method(D_METHOD("get_next_pass" ), &Material::get_next_pass); |
146 | |
147 | ClassDB::bind_method(D_METHOD("set_render_priority" , "priority" ), &Material::set_render_priority); |
148 | ClassDB::bind_method(D_METHOD("get_render_priority" ), &Material::get_render_priority); |
149 | |
150 | ClassDB::bind_method(D_METHOD("inspect_native_shader_code" ), &Material::inspect_native_shader_code); |
151 | ClassDB::set_method_flags(get_class_static(), _scs_create("inspect_native_shader_code" ), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); |
152 | |
153 | ClassDB::bind_method(D_METHOD("create_placeholder" ), &Material::create_placeholder); |
154 | |
155 | ADD_PROPERTY(PropertyInfo(Variant::INT, "render_priority" , PROPERTY_HINT_RANGE, itos(RENDER_PRIORITY_MIN) + "," + itos(RENDER_PRIORITY_MAX) + ",1" ), "set_render_priority" , "get_render_priority" ); |
156 | ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "next_pass" , PROPERTY_HINT_RESOURCE_TYPE, "Material" ), "set_next_pass" , "get_next_pass" ); |
157 | |
158 | BIND_CONSTANT(RENDER_PRIORITY_MAX); |
159 | BIND_CONSTANT(RENDER_PRIORITY_MIN); |
160 | |
161 | GDVIRTUAL_BIND(_get_shader_rid) |
162 | GDVIRTUAL_BIND(_get_shader_mode) |
163 | GDVIRTUAL_BIND(_can_do_next_pass) |
164 | GDVIRTUAL_BIND(_can_use_render_priority) |
165 | } |
166 | |
167 | Material::Material() { |
168 | material = RenderingServer::get_singleton()->material_create(); |
169 | render_priority = 0; |
170 | } |
171 | |
172 | Material::~Material() { |
173 | ERR_FAIL_NULL(RenderingServer::get_singleton()); |
174 | RenderingServer::get_singleton()->free(material); |
175 | } |
176 | |
177 | /////////////////////////////////// |
178 | |
179 | bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) { |
180 | if (shader.is_valid()) { |
181 | const StringName *sn = remap_cache.getptr(p_name); |
182 | if (sn) { |
183 | set_shader_parameter(*sn, p_value); |
184 | return true; |
185 | } |
186 | String s = p_name; |
187 | if (s.begins_with("shader_parameter/" )) { |
188 | String param = s.replace_first("shader_parameter/" , "" ); |
189 | remap_cache[s] = param; |
190 | set_shader_parameter(param, p_value); |
191 | return true; |
192 | } |
193 | #ifndef DISABLE_DEPRECATED |
194 | // Compatibility remaps are only needed here. |
195 | if (s.begins_with("param/" )) { |
196 | s = s.replace_first("param/" , "shader_parameter/" ); |
197 | } else if (s.begins_with("shader_param/" )) { |
198 | s = s.replace_first("shader_param/" , "shader_parameter/" ); |
199 | } else if (s.begins_with("shader_uniform/" )) { |
200 | s = s.replace_first("shader_uniform/" , "shader_parameter/" ); |
201 | } else { |
202 | return false; // Not a shader parameter. |
203 | } |
204 | |
205 | WARN_PRINT("This material (containing shader with path: '" + shader->get_path() + "') uses an old deprecated parameter names. Consider re-saving this resource (or scene which contains it) in order for it to continue working in future versions." ); |
206 | String param = s.replace_first("shader_parameter/" , "" ); |
207 | remap_cache[s] = param; |
208 | set_shader_parameter(param, p_value); |
209 | return true; |
210 | #endif |
211 | } |
212 | |
213 | return false; |
214 | } |
215 | |
216 | bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const { |
217 | if (shader.is_valid()) { |
218 | const StringName *sn = remap_cache.getptr(p_name); |
219 | if (sn) { |
220 | // Only return a parameter if it was previously set. |
221 | r_ret = get_shader_parameter(*sn); |
222 | return true; |
223 | } |
224 | } |
225 | |
226 | return false; |
227 | } |
228 | |
229 | void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const { |
230 | if (!shader.is_null()) { |
231 | List<PropertyInfo> list; |
232 | shader->get_shader_uniform_list(&list, true); |
233 | |
234 | HashMap<String, HashMap<String, List<PropertyInfo>>> groups; |
235 | LocalVector<Pair<String, LocalVector<String>>> vgroups; |
236 | { |
237 | HashMap<String, List<PropertyInfo>> none_subgroup; |
238 | none_subgroup.insert("<None>" , List<PropertyInfo>()); |
239 | groups.insert("<None>" , none_subgroup); |
240 | } |
241 | |
242 | String last_group = "<None>" ; |
243 | String last_subgroup = "<None>" ; |
244 | |
245 | bool is_none_group_undefined = true; |
246 | bool is_none_group = true; |
247 | |
248 | for (List<PropertyInfo>::Element *E = list.front(); E; E = E->next()) { |
249 | if (E->get().usage == PROPERTY_USAGE_GROUP) { |
250 | if (!E->get().name.is_empty()) { |
251 | Vector<String> vgroup = E->get().name.split("::" ); |
252 | last_group = vgroup[0]; |
253 | if (vgroup.size() > 1) { |
254 | last_subgroup = vgroup[1]; |
255 | } else { |
256 | last_subgroup = "<None>" ; |
257 | } |
258 | is_none_group = false; |
259 | |
260 | if (!groups.has(last_group)) { |
261 | PropertyInfo info; |
262 | info.usage = PROPERTY_USAGE_GROUP; |
263 | info.name = last_group.capitalize(); |
264 | info.hint_string = "shader_parameter/" ; |
265 | |
266 | List<PropertyInfo> none_subgroup; |
267 | none_subgroup.push_back(info); |
268 | |
269 | HashMap<String, List<PropertyInfo>> subgroup_map; |
270 | subgroup_map.insert("<None>" , none_subgroup); |
271 | |
272 | groups.insert(last_group, subgroup_map); |
273 | vgroups.push_back(Pair<String, LocalVector<String>>(last_group, { "<None>" })); |
274 | } |
275 | |
276 | if (!groups[last_group].has(last_subgroup)) { |
277 | PropertyInfo info; |
278 | info.usage = PROPERTY_USAGE_SUBGROUP; |
279 | info.name = last_subgroup.capitalize(); |
280 | info.hint_string = "shader_parameter/" ; |
281 | |
282 | List<PropertyInfo> subgroup; |
283 | subgroup.push_back(info); |
284 | |
285 | groups[last_group].insert(last_subgroup, subgroup); |
286 | for (Pair<String, LocalVector<String>> &group : vgroups) { |
287 | if (group.first == last_group) { |
288 | group.second.push_back(last_subgroup); |
289 | break; |
290 | } |
291 | } |
292 | } |
293 | } else { |
294 | last_group = "<None>" ; |
295 | last_subgroup = "<None>" ; |
296 | is_none_group = true; |
297 | } |
298 | continue; // Pass group. |
299 | } |
300 | |
301 | if (is_none_group_undefined && is_none_group) { |
302 | is_none_group_undefined = false; |
303 | |
304 | PropertyInfo info; |
305 | info.usage = PROPERTY_USAGE_GROUP; |
306 | info.name = "Shader Parameters" ; |
307 | info.hint_string = "shader_parameter/" ; |
308 | groups["<None>" ]["<None>" ].push_back(info); |
309 | |
310 | vgroups.push_back(Pair<String, LocalVector<String>>("<None>" , { "<None>" })); |
311 | } |
312 | |
313 | const bool is_uniform_cached = param_cache.has(E->get().name); |
314 | bool is_uniform_type_compatible = true; |
315 | |
316 | if (is_uniform_cached) { |
317 | // Check if the uniform Variant type changed, for example vec3 to vec4. |
318 | const Variant &cached = param_cache.get(E->get().name); |
319 | |
320 | if (cached.is_array()) { |
321 | // Allow some array conversions for backwards compatibility. |
322 | is_uniform_type_compatible = Variant::can_convert(E->get().type, cached.get_type()); |
323 | } else { |
324 | is_uniform_type_compatible = E->get().type == cached.get_type(); |
325 | } |
326 | |
327 | if (is_uniform_type_compatible && E->get().type == Variant::OBJECT && cached.get_type() == Variant::OBJECT) { |
328 | // Check if the Object class (hint string) changed, for example Texture2D sampler to Texture3D. |
329 | // Allow inheritance, Texture2D type sampler should also accept CompressedTexture2D. |
330 | Object *cached_obj = cached; |
331 | if (!cached_obj->is_class(E->get().hint_string)) { |
332 | is_uniform_type_compatible = false; |
333 | } |
334 | } |
335 | } |
336 | |
337 | PropertyInfo info = E->get(); |
338 | info.name = "shader_parameter/" + info.name; |
339 | if (!is_uniform_cached || !is_uniform_type_compatible) { |
340 | // Property has never been edited or its type changed, retrieve with default value. |
341 | Variant default_value = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), E->get().name); |
342 | param_cache.insert(E->get().name, default_value); |
343 | remap_cache.insert(info.name, E->get().name); |
344 | } |
345 | groups[last_group][last_subgroup].push_back(info); |
346 | } |
347 | |
348 | for (const Pair<String, LocalVector<String>> &group_pair : vgroups) { |
349 | String group = group_pair.first; |
350 | for (const String &subgroup : group_pair.second) { |
351 | List<PropertyInfo> &prop_infos = groups[group][subgroup]; |
352 | for (List<PropertyInfo>::Element *item = prop_infos.front(); item; item = item->next()) { |
353 | p_list->push_back(item->get()); |
354 | } |
355 | } |
356 | } |
357 | } |
358 | } |
359 | |
360 | bool ShaderMaterial::_property_can_revert(const StringName &p_name) const { |
361 | if (shader.is_valid()) { |
362 | const StringName *pr = remap_cache.getptr(p_name); |
363 | if (pr) { |
364 | Variant default_value = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), *pr); |
365 | Variant current_value = get_shader_parameter(*pr); |
366 | return default_value.get_type() != Variant::NIL && default_value != current_value; |
367 | } |
368 | } |
369 | return false; |
370 | } |
371 | |
372 | bool ShaderMaterial::_property_get_revert(const StringName &p_name, Variant &r_property) const { |
373 | if (shader.is_valid()) { |
374 | const StringName *pr = remap_cache.getptr(p_name); |
375 | if (*pr) { |
376 | r_property = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), *pr); |
377 | return true; |
378 | } |
379 | } |
380 | return false; |
381 | } |
382 | |
383 | void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) { |
384 | // Only connect/disconnect the signal when running in the editor. |
385 | // This can be a slow operation, and `notify_property_list_changed()` (which is called by `_shader_changed()`) |
386 | // does nothing in non-editor builds anyway. See GH-34741 for details. |
387 | if (shader.is_valid() && Engine::get_singleton()->is_editor_hint()) { |
388 | shader->disconnect_changed(callable_mp(this, &ShaderMaterial::_shader_changed)); |
389 | } |
390 | |
391 | shader = p_shader; |
392 | |
393 | RID rid; |
394 | if (shader.is_valid()) { |
395 | rid = shader->get_rid(); |
396 | |
397 | if (Engine::get_singleton()->is_editor_hint()) { |
398 | shader->connect_changed(callable_mp(this, &ShaderMaterial::_shader_changed)); |
399 | } |
400 | } |
401 | |
402 | RS::get_singleton()->material_set_shader(_get_material(), rid); |
403 | notify_property_list_changed(); //properties for shader exposed |
404 | emit_changed(); |
405 | } |
406 | |
407 | Ref<Shader> ShaderMaterial::get_shader() const { |
408 | return shader; |
409 | } |
410 | |
411 | void ShaderMaterial::set_shader_parameter(const StringName &p_param, const Variant &p_value) { |
412 | if (p_value.get_type() == Variant::NIL) { |
413 | param_cache.erase(p_param); |
414 | RS::get_singleton()->material_set_param(_get_material(), p_param, Variant()); |
415 | } else { |
416 | Variant *v = param_cache.getptr(p_param); |
417 | if (!v) { |
418 | // Never assigned, also update the remap cache. |
419 | remap_cache["shader_parameter/" + p_param.operator String()] = p_param; |
420 | param_cache.insert(p_param, p_value); |
421 | } else { |
422 | *v = p_value; |
423 | } |
424 | |
425 | if (p_value.get_type() == Variant::OBJECT) { |
426 | RID tex_rid = p_value; |
427 | if (tex_rid == RID()) { |
428 | param_cache.erase(p_param); |
429 | RS::get_singleton()->material_set_param(_get_material(), p_param, Variant()); |
430 | } else { |
431 | RS::get_singleton()->material_set_param(_get_material(), p_param, tex_rid); |
432 | } |
433 | } else { |
434 | RS::get_singleton()->material_set_param(_get_material(), p_param, p_value); |
435 | } |
436 | } |
437 | } |
438 | |
439 | Variant ShaderMaterial::get_shader_parameter(const StringName &p_param) const { |
440 | if (param_cache.has(p_param)) { |
441 | return param_cache[p_param]; |
442 | } else { |
443 | return Variant(); |
444 | } |
445 | } |
446 | |
447 | void ShaderMaterial::_shader_changed() { |
448 | notify_property_list_changed(); //update all properties |
449 | } |
450 | |
451 | void ShaderMaterial::_bind_methods() { |
452 | ClassDB::bind_method(D_METHOD("set_shader" , "shader" ), &ShaderMaterial::set_shader); |
453 | ClassDB::bind_method(D_METHOD("get_shader" ), &ShaderMaterial::get_shader); |
454 | ClassDB::bind_method(D_METHOD("set_shader_parameter" , "param" , "value" ), &ShaderMaterial::set_shader_parameter); |
455 | ClassDB::bind_method(D_METHOD("get_shader_parameter" , "param" ), &ShaderMaterial::get_shader_parameter); |
456 | |
457 | ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shader" , PROPERTY_HINT_RESOURCE_TYPE, "Shader" ), "set_shader" , "get_shader" ); |
458 | } |
459 | |
460 | void ShaderMaterial::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { |
461 | String f = p_function.operator String(); |
462 | if ((f == "get_shader_parameter" || f == "set_shader_parameter" ) && p_idx == 0) { |
463 | if (shader.is_valid()) { |
464 | List<PropertyInfo> pl; |
465 | shader->get_shader_uniform_list(&pl); |
466 | for (const PropertyInfo &E : pl) { |
467 | r_options->push_back(E.name.replace_first("shader_parameter/" , "" ).quote()); |
468 | } |
469 | } |
470 | } |
471 | Resource::get_argument_options(p_function, p_idx, r_options); |
472 | } |
473 | |
474 | bool ShaderMaterial::_can_do_next_pass() const { |
475 | return shader.is_valid() && shader->get_mode() == Shader::MODE_SPATIAL; |
476 | } |
477 | |
478 | bool ShaderMaterial::_can_use_render_priority() const { |
479 | return shader.is_valid() && shader->get_mode() == Shader::MODE_SPATIAL; |
480 | } |
481 | |
482 | Shader::Mode ShaderMaterial::get_shader_mode() const { |
483 | if (shader.is_valid()) { |
484 | return shader->get_mode(); |
485 | } else { |
486 | return Shader::MODE_SPATIAL; |
487 | } |
488 | } |
489 | RID ShaderMaterial::get_shader_rid() const { |
490 | if (shader.is_valid()) { |
491 | return shader->get_rid(); |
492 | } else { |
493 | return RID(); |
494 | } |
495 | } |
496 | |
497 | ShaderMaterial::ShaderMaterial() { |
498 | } |
499 | |
500 | ShaderMaterial::~ShaderMaterial() { |
501 | } |
502 | |
503 | ///////////////////////////////// |
504 | |
505 | Mutex BaseMaterial3D::material_mutex; |
506 | SelfList<BaseMaterial3D>::List BaseMaterial3D::dirty_materials; |
507 | HashMap<BaseMaterial3D::MaterialKey, BaseMaterial3D::ShaderData, BaseMaterial3D::MaterialKey> BaseMaterial3D::shader_map; |
508 | BaseMaterial3D::ShaderNames *BaseMaterial3D::shader_names = nullptr; |
509 | |
510 | void BaseMaterial3D::init_shaders() { |
511 | shader_names = memnew(ShaderNames); |
512 | |
513 | shader_names->albedo = "albedo" ; |
514 | shader_names->specular = "specular" ; |
515 | shader_names->roughness = "roughness" ; |
516 | shader_names->metallic = "metallic" ; |
517 | shader_names->emission = "emission" ; |
518 | shader_names->emission_energy = "emission_energy" ; |
519 | shader_names->normal_scale = "normal_scale" ; |
520 | shader_names->rim = "rim" ; |
521 | shader_names->rim_tint = "rim_tint" ; |
522 | shader_names->clearcoat = "clearcoat" ; |
523 | shader_names->clearcoat_roughness = "clearcoat_roughness" ; |
524 | shader_names->anisotropy = "anisotropy_ratio" ; |
525 | shader_names->heightmap_scale = "heightmap_scale" ; |
526 | shader_names->subsurface_scattering_strength = "subsurface_scattering_strength" ; |
527 | shader_names->backlight = "backlight" ; |
528 | shader_names->refraction = "refraction" ; |
529 | shader_names->point_size = "point_size" ; |
530 | shader_names->uv1_scale = "uv1_scale" ; |
531 | shader_names->uv1_offset = "uv1_offset" ; |
532 | shader_names->uv2_scale = "uv2_scale" ; |
533 | shader_names->uv2_offset = "uv2_offset" ; |
534 | shader_names->uv1_blend_sharpness = "uv1_blend_sharpness" ; |
535 | shader_names->uv2_blend_sharpness = "uv2_blend_sharpness" ; |
536 | |
537 | shader_names->particles_anim_h_frames = "particles_anim_h_frames" ; |
538 | shader_names->particles_anim_v_frames = "particles_anim_v_frames" ; |
539 | shader_names->particles_anim_loop = "particles_anim_loop" ; |
540 | shader_names->heightmap_min_layers = "heightmap_min_layers" ; |
541 | shader_names->heightmap_max_layers = "heightmap_max_layers" ; |
542 | shader_names->heightmap_flip = "heightmap_flip" ; |
543 | |
544 | shader_names->grow = "grow" ; |
545 | |
546 | shader_names->ao_light_affect = "ao_light_affect" ; |
547 | |
548 | shader_names->proximity_fade_distance = "proximity_fade_distance" ; |
549 | shader_names->distance_fade_min = "distance_fade_min" ; |
550 | shader_names->distance_fade_max = "distance_fade_max" ; |
551 | |
552 | shader_names->msdf_pixel_range = "msdf_pixel_range" ; |
553 | shader_names->msdf_outline_size = "msdf_outline_size" ; |
554 | |
555 | shader_names->metallic_texture_channel = "metallic_texture_channel" ; |
556 | shader_names->ao_texture_channel = "ao_texture_channel" ; |
557 | shader_names->clearcoat_texture_channel = "clearcoat_texture_channel" ; |
558 | shader_names->rim_texture_channel = "rim_texture_channel" ; |
559 | shader_names->heightmap_texture_channel = "heightmap_texture_channel" ; |
560 | shader_names->refraction_texture_channel = "refraction_texture_channel" ; |
561 | |
562 | shader_names->transmittance_color = "transmittance_color" ; |
563 | shader_names->transmittance_depth = "transmittance_depth" ; |
564 | shader_names->transmittance_boost = "transmittance_boost" ; |
565 | |
566 | shader_names->texture_names[TEXTURE_ALBEDO] = "texture_albedo" ; |
567 | shader_names->texture_names[TEXTURE_METALLIC] = "texture_metallic" ; |
568 | shader_names->texture_names[TEXTURE_ROUGHNESS] = "texture_roughness" ; |
569 | shader_names->texture_names[TEXTURE_EMISSION] = "texture_emission" ; |
570 | shader_names->texture_names[TEXTURE_NORMAL] = "texture_normal" ; |
571 | shader_names->texture_names[TEXTURE_RIM] = "texture_rim" ; |
572 | shader_names->texture_names[TEXTURE_CLEARCOAT] = "texture_clearcoat" ; |
573 | shader_names->texture_names[TEXTURE_FLOWMAP] = "texture_flowmap" ; |
574 | shader_names->texture_names[TEXTURE_AMBIENT_OCCLUSION] = "texture_ambient_occlusion" ; |
575 | shader_names->texture_names[TEXTURE_HEIGHTMAP] = "texture_heightmap" ; |
576 | shader_names->texture_names[TEXTURE_SUBSURFACE_SCATTERING] = "texture_subsurface_scattering" ; |
577 | shader_names->texture_names[TEXTURE_SUBSURFACE_TRANSMITTANCE] = "texture_subsurface_transmittance" ; |
578 | shader_names->texture_names[TEXTURE_BACKLIGHT] = "texture_backlight" ; |
579 | shader_names->texture_names[TEXTURE_REFRACTION] = "texture_refraction" ; |
580 | shader_names->texture_names[TEXTURE_DETAIL_MASK] = "texture_detail_mask" ; |
581 | shader_names->texture_names[TEXTURE_DETAIL_ALBEDO] = "texture_detail_albedo" ; |
582 | shader_names->texture_names[TEXTURE_DETAIL_NORMAL] = "texture_detail_normal" ; |
583 | shader_names->texture_names[TEXTURE_ORM] = "texture_orm" ; |
584 | |
585 | shader_names->alpha_scissor_threshold = "alpha_scissor_threshold" ; |
586 | shader_names->alpha_hash_scale = "alpha_hash_scale" ; |
587 | |
588 | shader_names->alpha_antialiasing_edge = "alpha_antialiasing_edge" ; |
589 | shader_names->albedo_texture_size = "albedo_texture_size" ; |
590 | } |
591 | |
592 | HashMap<uint64_t, Ref<StandardMaterial3D>> BaseMaterial3D::materials_for_2d; |
593 | |
594 | void BaseMaterial3D::finish_shaders() { |
595 | materials_for_2d.clear(); |
596 | |
597 | dirty_materials.clear(); |
598 | |
599 | memdelete(shader_names); |
600 | shader_names = nullptr; |
601 | } |
602 | |
603 | void BaseMaterial3D::_update_shader() { |
604 | dirty_materials.remove(&element); |
605 | |
606 | MaterialKey mk = _compute_key(); |
607 | if (mk == current_key) { |
608 | return; //no update required in the end |
609 | } |
610 | |
611 | if (shader_map.has(current_key)) { |
612 | shader_map[current_key].users--; |
613 | if (shader_map[current_key].users == 0) { |
614 | //deallocate shader, as it's no longer in use |
615 | RS::get_singleton()->free(shader_map[current_key].shader); |
616 | shader_map.erase(current_key); |
617 | } |
618 | } |
619 | |
620 | current_key = mk; |
621 | |
622 | if (shader_map.has(mk)) { |
623 | RS::get_singleton()->material_set_shader(_get_material(), shader_map[mk].shader); |
624 | shader_map[mk].users++; |
625 | return; |
626 | } |
627 | |
628 | String texfilter_str; |
629 | // Force linear filtering for the heightmap texture, as the heightmap effect |
630 | // looks broken with nearest-neighbor filtering (with and without Deep Parallax). |
631 | String texfilter_height_str; |
632 | switch (texture_filter) { |
633 | case TEXTURE_FILTER_NEAREST: |
634 | texfilter_str = "filter_nearest" ; |
635 | texfilter_height_str = "filter_linear" ; |
636 | break; |
637 | case TEXTURE_FILTER_LINEAR: |
638 | texfilter_str = "filter_linear" ; |
639 | texfilter_height_str = "filter_linear" ; |
640 | break; |
641 | case TEXTURE_FILTER_NEAREST_WITH_MIPMAPS: |
642 | texfilter_str = "filter_nearest_mipmap" ; |
643 | texfilter_height_str = "filter_linear_mipmap" ; |
644 | break; |
645 | case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS: |
646 | texfilter_str = "filter_linear_mipmap" ; |
647 | texfilter_height_str = "filter_linear_mipmap" ; |
648 | break; |
649 | case TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC: |
650 | texfilter_str = "filter_nearest_mipmap_anisotropic" ; |
651 | texfilter_height_str = "filter_linear_mipmap_anisotropic" ; |
652 | break; |
653 | case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC: |
654 | texfilter_str = "filter_linear_mipmap_anisotropic" ; |
655 | texfilter_height_str = "filter_linear_mipmap_anisotropic" ; |
656 | break; |
657 | case TEXTURE_FILTER_MAX: |
658 | break; // Internal value, skip. |
659 | } |
660 | |
661 | if (flags[FLAG_USE_TEXTURE_REPEAT]) { |
662 | texfilter_str += ",repeat_enable" ; |
663 | texfilter_height_str += ",repeat_enable" ; |
664 | } else { |
665 | texfilter_str += ",repeat_disable" ; |
666 | texfilter_height_str += ",repeat_disable" ; |
667 | } |
668 | |
669 | //must create a shader! |
670 | |
671 | // Add a comment to describe the shader origin (useful when converting to ShaderMaterial). |
672 | String code = vformat( |
673 | "// NOTE: Shader automatically converted from " VERSION_NAME " " VERSION_FULL_CONFIG "'s %s.\n\n" , |
674 | orm ? "ORMMaterial3D" : "StandardMaterial3D" ); |
675 | |
676 | code += "shader_type spatial;\nrender_mode " ; |
677 | switch (blend_mode) { |
678 | case BLEND_MODE_MIX: |
679 | code += "blend_mix" ; |
680 | break; |
681 | case BLEND_MODE_ADD: |
682 | code += "blend_add" ; |
683 | break; |
684 | case BLEND_MODE_SUB: |
685 | code += "blend_sub" ; |
686 | break; |
687 | case BLEND_MODE_MUL: |
688 | code += "blend_mul" ; |
689 | break; |
690 | case BLEND_MODE_MAX: |
691 | break; // Internal value, skip. |
692 | } |
693 | |
694 | DepthDrawMode ddm = depth_draw_mode; |
695 | if (features[FEATURE_REFRACTION]) { |
696 | ddm = DEPTH_DRAW_ALWAYS; |
697 | } |
698 | |
699 | switch (ddm) { |
700 | case DEPTH_DRAW_OPAQUE_ONLY: |
701 | code += ",depth_draw_opaque" ; |
702 | break; |
703 | case DEPTH_DRAW_ALWAYS: |
704 | code += ",depth_draw_always" ; |
705 | break; |
706 | case DEPTH_DRAW_DISABLED: |
707 | code += ",depth_draw_never" ; |
708 | break; |
709 | case DEPTH_DRAW_MAX: |
710 | break; // Internal value, skip. |
711 | } |
712 | |
713 | switch (cull_mode) { |
714 | case CULL_BACK: |
715 | code += ",cull_back" ; |
716 | break; |
717 | case CULL_FRONT: |
718 | code += ",cull_front" ; |
719 | break; |
720 | case CULL_DISABLED: |
721 | code += ",cull_disabled" ; |
722 | break; |
723 | case CULL_MAX: |
724 | break; // Internal value, skip. |
725 | } |
726 | switch (diffuse_mode) { |
727 | case DIFFUSE_BURLEY: |
728 | code += ",diffuse_burley" ; |
729 | break; |
730 | case DIFFUSE_LAMBERT: |
731 | code += ",diffuse_lambert" ; |
732 | break; |
733 | case DIFFUSE_LAMBERT_WRAP: |
734 | code += ",diffuse_lambert_wrap" ; |
735 | break; |
736 | case DIFFUSE_TOON: |
737 | code += ",diffuse_toon" ; |
738 | break; |
739 | case DIFFUSE_MAX: |
740 | break; // Internal value, skip. |
741 | } |
742 | switch (specular_mode) { |
743 | case SPECULAR_SCHLICK_GGX: |
744 | code += ",specular_schlick_ggx" ; |
745 | break; |
746 | case SPECULAR_TOON: |
747 | code += ",specular_toon" ; |
748 | break; |
749 | case SPECULAR_DISABLED: |
750 | code += ",specular_disabled" ; |
751 | break; |
752 | case SPECULAR_MAX: |
753 | break; // Internal value, skip. |
754 | } |
755 | if (features[FEATURE_SUBSURFACE_SCATTERING] && flags[FLAG_SUBSURFACE_MODE_SKIN]) { |
756 | code += ",sss_mode_skin" ; |
757 | } |
758 | |
759 | if (shading_mode == SHADING_MODE_UNSHADED) { |
760 | code += ",unshaded" ; |
761 | } |
762 | if (flags[FLAG_DISABLE_DEPTH_TEST]) { |
763 | code += ",depth_test_disabled" ; |
764 | } |
765 | if (flags[FLAG_PARTICLE_TRAILS_MODE]) { |
766 | code += ",particle_trails" ; |
767 | } |
768 | if (shading_mode == SHADING_MODE_PER_VERTEX) { |
769 | code += ",vertex_lighting" ; |
770 | } |
771 | if (flags[FLAG_DONT_RECEIVE_SHADOWS]) { |
772 | code += ",shadows_disabled" ; |
773 | } |
774 | if (flags[FLAG_DISABLE_AMBIENT_LIGHT]) { |
775 | code += ",ambient_light_disabled" ; |
776 | } |
777 | if (flags[FLAG_USE_SHADOW_TO_OPACITY]) { |
778 | code += ",shadow_to_opacity" ; |
779 | } |
780 | if (flags[FLAG_DISABLE_FOG]) { |
781 | code += ",fog_disabled" ; |
782 | } |
783 | |
784 | if (transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS) { |
785 | code += ",depth_prepass_alpha" ; |
786 | } |
787 | |
788 | // Although its technically possible to do alpha antialiasing without using alpha hash or alpha scissor, |
789 | // it is restricted in the base material because it has no use, and abusing it with regular Alpha blending can |
790 | // saturate the MSAA mask |
791 | if (transparency == TRANSPARENCY_ALPHA_HASH || transparency == TRANSPARENCY_ALPHA_SCISSOR) { |
792 | // alpha antialiasing is only useful in ALPHA_HASH or ALPHA_SCISSOR |
793 | if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE) { |
794 | code += ",alpha_to_coverage" ; |
795 | } else if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE) { |
796 | code += ",alpha_to_coverage_and_one" ; |
797 | } |
798 | } |
799 | |
800 | code += ";\n" ; |
801 | |
802 | code += "uniform vec4 albedo : source_color;\n" ; |
803 | code += "uniform sampler2D texture_albedo : source_color," + texfilter_str + ";\n" ; |
804 | if (grow_enabled) { |
805 | code += "uniform float grow;\n" ; |
806 | } |
807 | |
808 | if (proximity_fade_enabled) { |
809 | code += "uniform float proximity_fade_distance;\n" ; |
810 | } |
811 | if (distance_fade != DISTANCE_FADE_DISABLED) { |
812 | code += "uniform float distance_fade_min;\n" ; |
813 | code += "uniform float distance_fade_max;\n" ; |
814 | } |
815 | |
816 | if (flags[FLAG_ALBEDO_TEXTURE_MSDF]) { |
817 | code += "uniform float msdf_pixel_range;\n" ; |
818 | code += "uniform float msdf_outline_size;\n" ; |
819 | } |
820 | |
821 | // alpha scissor is only valid if there is not antialiasing edge |
822 | // alpha hash is valid whenever, but not with alpha scissor |
823 | if (transparency == TRANSPARENCY_ALPHA_SCISSOR) { |
824 | code += "uniform float alpha_scissor_threshold;\n" ; |
825 | } else if (transparency == TRANSPARENCY_ALPHA_HASH) { |
826 | code += "uniform float alpha_hash_scale;\n" ; |
827 | } |
828 | // if alpha antialiasing isn't off, add in the edge variable |
829 | if (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF && |
830 | (transparency == TRANSPARENCY_ALPHA_SCISSOR || transparency == TRANSPARENCY_ALPHA_HASH)) { |
831 | code += "uniform float alpha_antialiasing_edge;\n" ; |
832 | code += "uniform ivec2 albedo_texture_size;\n" ; |
833 | } |
834 | |
835 | code += "uniform float point_size : hint_range(0,128);\n" ; |
836 | |
837 | //TODO ALL HINTS |
838 | if (!orm) { |
839 | code += "uniform float roughness : hint_range(0,1);\n" ; |
840 | code += "uniform sampler2D texture_metallic : hint_default_white," + texfilter_str + ";\n" ; |
841 | code += "uniform vec4 metallic_texture_channel;\n" ; |
842 | switch (roughness_texture_channel) { |
843 | case TEXTURE_CHANNEL_RED: { |
844 | code += "uniform sampler2D texture_roughness : hint_roughness_r," + texfilter_str + ";\n" ; |
845 | } break; |
846 | case TEXTURE_CHANNEL_GREEN: { |
847 | code += "uniform sampler2D texture_roughness : hint_roughness_g," + texfilter_str + ";\n" ; |
848 | } break; |
849 | case TEXTURE_CHANNEL_BLUE: { |
850 | code += "uniform sampler2D texture_roughness : hint_roughness_b," + texfilter_str + ";\n" ; |
851 | } break; |
852 | case TEXTURE_CHANNEL_ALPHA: { |
853 | code += "uniform sampler2D texture_roughness : hint_roughness_a," + texfilter_str + ";\n" ; |
854 | } break; |
855 | case TEXTURE_CHANNEL_GRAYSCALE: { |
856 | code += "uniform sampler2D texture_roughness : hint_roughness_gray," + texfilter_str + ";\n" ; |
857 | } break; |
858 | case TEXTURE_CHANNEL_MAX: |
859 | break; // Internal value, skip. |
860 | } |
861 | |
862 | code += "uniform float specular;\n" ; |
863 | code += "uniform float metallic;\n" ; |
864 | } else { |
865 | code += "uniform sampler2D texture_orm : hint_roughness_g," + texfilter_str + ";\n" ; |
866 | } |
867 | |
868 | if (billboard_mode == BILLBOARD_PARTICLES) { |
869 | code += "uniform int particles_anim_h_frames;\n" ; |
870 | code += "uniform int particles_anim_v_frames;\n" ; |
871 | code += "uniform bool particles_anim_loop;\n" ; |
872 | } |
873 | |
874 | if (features[FEATURE_EMISSION]) { |
875 | code += "uniform sampler2D texture_emission : source_color, hint_default_black," + texfilter_str + ";\n" ; |
876 | code += "uniform vec4 emission : source_color;\n" ; |
877 | code += "uniform float emission_energy;\n" ; |
878 | } |
879 | |
880 | if (features[FEATURE_REFRACTION]) { |
881 | code += "uniform sampler2D texture_refraction : " + texfilter_str + ";\n" ; |
882 | code += "uniform float refraction : hint_range(-16,16);\n" ; |
883 | code += "uniform vec4 refraction_texture_channel;\n" ; |
884 | } |
885 | |
886 | if (features[FEATURE_REFRACTION]) { |
887 | code += "uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_linear_mipmap;" ; |
888 | } |
889 | |
890 | if (proximity_fade_enabled) { |
891 | code += "uniform sampler2D depth_texture : hint_depth_texture, repeat_disable, filter_nearest;" ; |
892 | } |
893 | |
894 | if (features[FEATURE_NORMAL_MAPPING]) { |
895 | code += "uniform sampler2D texture_normal : hint_roughness_normal," + texfilter_str + ";\n" ; |
896 | code += "uniform float normal_scale : hint_range(-16,16);\n" ; |
897 | } |
898 | if (features[FEATURE_RIM]) { |
899 | code += "uniform float rim : hint_range(0,1);\n" ; |
900 | code += "uniform float rim_tint : hint_range(0,1);\n" ; |
901 | code += "uniform sampler2D texture_rim : hint_default_white," + texfilter_str + ";\n" ; |
902 | } |
903 | if (features[FEATURE_CLEARCOAT]) { |
904 | code += "uniform float clearcoat : hint_range(0,1);\n" ; |
905 | code += "uniform float clearcoat_roughness : hint_range(0,1);\n" ; |
906 | code += "uniform sampler2D texture_clearcoat : hint_default_white," + texfilter_str + ";\n" ; |
907 | } |
908 | if (features[FEATURE_ANISOTROPY]) { |
909 | code += "uniform float anisotropy_ratio : hint_range(0,256);\n" ; |
910 | code += "uniform sampler2D texture_flowmap : hint_anisotropy," + texfilter_str + ";\n" ; |
911 | } |
912 | if (features[FEATURE_AMBIENT_OCCLUSION]) { |
913 | code += "uniform sampler2D texture_ambient_occlusion : hint_default_white, " + texfilter_str + ";\n" ; |
914 | code += "uniform vec4 ao_texture_channel;\n" ; |
915 | code += "uniform float ao_light_affect;\n" ; |
916 | } |
917 | |
918 | if (features[FEATURE_DETAIL]) { |
919 | code += "uniform sampler2D texture_detail_albedo : source_color," + texfilter_str + ";\n" ; |
920 | code += "uniform sampler2D texture_detail_normal : hint_normal," + texfilter_str + ";\n" ; |
921 | code += "uniform sampler2D texture_detail_mask : hint_default_white," + texfilter_str + ";\n" ; |
922 | } |
923 | |
924 | if (features[FEATURE_SUBSURFACE_SCATTERING]) { |
925 | code += "uniform float subsurface_scattering_strength : hint_range(0,1);\n" ; |
926 | code += "uniform sampler2D texture_subsurface_scattering : hint_default_white," + texfilter_str + ";\n" ; |
927 | } |
928 | |
929 | if (features[FEATURE_SUBSURFACE_TRANSMITTANCE]) { |
930 | code += "uniform vec4 transmittance_color : source_color;\n" ; |
931 | code += "uniform float transmittance_depth;\n" ; |
932 | code += "uniform sampler2D texture_subsurface_transmittance : hint_default_white," + texfilter_str + ";\n" ; |
933 | code += "uniform float transmittance_boost;\n" ; |
934 | } |
935 | |
936 | if (features[FEATURE_BACKLIGHT]) { |
937 | code += "uniform vec4 backlight : source_color;\n" ; |
938 | code += "uniform sampler2D texture_backlight : hint_default_black," + texfilter_str + ";\n" ; |
939 | } |
940 | |
941 | if (features[FEATURE_HEIGHT_MAPPING]) { |
942 | code += "uniform sampler2D texture_heightmap : hint_default_black," + texfilter_height_str + ";\n" ; |
943 | code += "uniform float heightmap_scale;\n" ; |
944 | code += "uniform int heightmap_min_layers;\n" ; |
945 | code += "uniform int heightmap_max_layers;\n" ; |
946 | code += "uniform vec2 heightmap_flip;\n" ; |
947 | } |
948 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
949 | code += "varying vec3 uv1_triplanar_pos;\n" ; |
950 | } |
951 | if (flags[FLAG_UV2_USE_TRIPLANAR]) { |
952 | code += "varying vec3 uv2_triplanar_pos;\n" ; |
953 | } |
954 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
955 | code += "uniform float uv1_blend_sharpness;\n" ; |
956 | code += "varying vec3 uv1_power_normal;\n" ; |
957 | } |
958 | |
959 | if (flags[FLAG_UV2_USE_TRIPLANAR]) { |
960 | code += "uniform float uv2_blend_sharpness;\n" ; |
961 | code += "varying vec3 uv2_power_normal;\n" ; |
962 | } |
963 | |
964 | code += "uniform vec3 uv1_scale;\n" ; |
965 | code += "uniform vec3 uv1_offset;\n" ; |
966 | code += "uniform vec3 uv2_scale;\n" ; |
967 | code += "uniform vec3 uv2_offset;\n" ; |
968 | |
969 | code += "\n\n" ; |
970 | |
971 | code += "void vertex() {\n" ; |
972 | |
973 | if (flags[FLAG_SRGB_VERTEX_COLOR]) { |
974 | code += " if (!OUTPUT_IS_SRGB) {\n" ; |
975 | code += " COLOR.rgb = mix(pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb * (1.0 / 12.92), lessThan(COLOR.rgb, vec3(0.04045)));\n" ; |
976 | code += " }\n" ; |
977 | } |
978 | if (flags[FLAG_USE_POINT_SIZE]) { |
979 | code += " POINT_SIZE=point_size;\n" ; |
980 | } |
981 | |
982 | if (shading_mode == SHADING_MODE_PER_VERTEX) { |
983 | code += " ROUGHNESS=roughness;\n" ; |
984 | } |
985 | |
986 | if (!flags[FLAG_UV1_USE_TRIPLANAR]) { |
987 | code += " UV=UV*uv1_scale.xy+uv1_offset.xy;\n" ; |
988 | } |
989 | |
990 | switch (billboard_mode) { |
991 | case BILLBOARD_DISABLED: { |
992 | } break; |
993 | case BILLBOARD_ENABLED: { |
994 | code += " MODELVIEW_MATRIX = VIEW_MATRIX * mat4(INV_VIEW_MATRIX[0], INV_VIEW_MATRIX[1], INV_VIEW_MATRIX[2], MODEL_MATRIX[3]);\n" ; |
995 | |
996 | if (flags[FLAG_BILLBOARD_KEEP_SCALE]) { |
997 | code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n" ; |
998 | } |
999 | code += " MODELVIEW_NORMAL_MATRIX = mat3(MODELVIEW_MATRIX);\n" ; |
1000 | } break; |
1001 | case BILLBOARD_FIXED_Y: { |
1002 | code += " MODELVIEW_MATRIX = VIEW_MATRIX * mat4(vec4(normalize(cross(vec3(0.0, 1.0, 0.0), INV_VIEW_MATRIX[2].xyz)), 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(normalize(cross(INV_VIEW_MATRIX[0].xyz, vec3(0.0, 1.0, 0.0))), 0.0), MODEL_MATRIX[3]);\n" ; |
1003 | |
1004 | if (flags[FLAG_BILLBOARD_KEEP_SCALE]) { |
1005 | code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n" ; |
1006 | } |
1007 | code += " MODELVIEW_NORMAL_MATRIX = mat3(MODELVIEW_MATRIX);\n" ; |
1008 | } break; |
1009 | case BILLBOARD_PARTICLES: { |
1010 | //make billboard |
1011 | code += " mat4 mat_world = mat4(normalize(INV_VIEW_MATRIX[0]), normalize(INV_VIEW_MATRIX[1]) ,normalize(INV_VIEW_MATRIX[2]), MODEL_MATRIX[3]);\n" ; |
1012 | //rotate by rotation |
1013 | code += " mat_world = mat_world * mat4(vec4(cos(INSTANCE_CUSTOM.x), -sin(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(sin(INSTANCE_CUSTOM.x), cos(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n" ; |
1014 | //set modelview |
1015 | code += " MODELVIEW_MATRIX = VIEW_MATRIX * mat_world;\n" ; |
1016 | if (flags[FLAG_BILLBOARD_KEEP_SCALE]) { |
1017 | code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n" ; |
1018 | } |
1019 | //set modelview normal |
1020 | code += " MODELVIEW_NORMAL_MATRIX = mat3(MODELVIEW_MATRIX);\n" ; |
1021 | |
1022 | //handle animation |
1023 | code += " float h_frames = float(particles_anim_h_frames);\n" ; |
1024 | code += " float v_frames = float(particles_anim_v_frames);\n" ; |
1025 | code += " float particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);\n" ; |
1026 | code += " float particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n" ; |
1027 | code += " if (!particles_anim_loop) {\n" ; |
1028 | code += " particle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n" ; |
1029 | code += " } else {\n" ; |
1030 | code += " particle_frame = mod(particle_frame, particle_total_frames);\n" ; |
1031 | code += " }\n" ; |
1032 | code += " UV /= vec2(h_frames, v_frames);\n" ; |
1033 | code += " UV += vec2(mod(particle_frame, h_frames) / h_frames, floor((particle_frame + 0.5) / h_frames) / v_frames);\n" ; |
1034 | } break; |
1035 | case BILLBOARD_MAX: |
1036 | break; // Internal value, skip. |
1037 | } |
1038 | |
1039 | if (flags[FLAG_FIXED_SIZE]) { |
1040 | code += " if (PROJECTION_MATRIX[3][3] != 0.0) {\n" ; |
1041 | //orthogonal matrix, try to do about the same |
1042 | //with viewport size |
1043 | code += " float h = abs(1.0 / (2.0 * PROJECTION_MATRIX[1][1]));\n" ; |
1044 | code += " float sc = (h * 2.0); //consistent with Y-fov\n" ; |
1045 | code += " MODELVIEW_MATRIX[0]*=sc;\n" ; |
1046 | code += " MODELVIEW_MATRIX[1]*=sc;\n" ; |
1047 | code += " MODELVIEW_MATRIX[2]*=sc;\n" ; |
1048 | code += " } else {\n" ; |
1049 | //just scale by depth |
1050 | code += " float sc = -(MODELVIEW_MATRIX)[3].z;\n" ; |
1051 | code += " MODELVIEW_MATRIX[0]*=sc;\n" ; |
1052 | code += " MODELVIEW_MATRIX[1]*=sc;\n" ; |
1053 | code += " MODELVIEW_MATRIX[2]*=sc;\n" ; |
1054 | code += " }\n" ; |
1055 | } |
1056 | |
1057 | if (detail_uv == DETAIL_UV_2 && !flags[FLAG_UV2_USE_TRIPLANAR]) { |
1058 | code += " UV2=UV2*uv2_scale.xy+uv2_offset.xy;\n" ; |
1059 | } |
1060 | if (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR]) { |
1061 | //generate tangent and binormal in world space |
1062 | code += " TANGENT = vec3(0.0,0.0,-1.0) * abs(NORMAL.x);\n" ; |
1063 | code += " TANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.y);\n" ; |
1064 | code += " TANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.z);\n" ; |
1065 | code += " TANGENT = normalize(TANGENT);\n" ; |
1066 | |
1067 | code += " BINORMAL = vec3(0.0,1.0,0.0) * abs(NORMAL.x);\n" ; |
1068 | code += " BINORMAL+= vec3(0.0,0.0,-1.0) * abs(NORMAL.y);\n" ; |
1069 | code += " BINORMAL+= vec3(0.0,1.0,0.0) * abs(NORMAL.z);\n" ; |
1070 | code += " BINORMAL = normalize(BINORMAL);\n" ; |
1071 | } |
1072 | |
1073 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
1074 | if (flags[FLAG_UV1_USE_WORLD_TRIPLANAR]) { |
1075 | code += " uv1_power_normal=pow(abs(mat3(MODEL_MATRIX) * NORMAL),vec3(uv1_blend_sharpness));\n" ; |
1076 | code += " uv1_triplanar_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0f)).xyz * uv1_scale + uv1_offset;\n" ; |
1077 | } else { |
1078 | code += " uv1_power_normal=pow(abs(NORMAL),vec3(uv1_blend_sharpness));\n" ; |
1079 | code += " uv1_triplanar_pos = VERTEX * uv1_scale + uv1_offset;\n" ; |
1080 | } |
1081 | code += " uv1_power_normal/=dot(uv1_power_normal,vec3(1.0));\n" ; |
1082 | code += " uv1_triplanar_pos *= vec3(1.0,-1.0, 1.0);\n" ; |
1083 | } |
1084 | |
1085 | if (flags[FLAG_UV2_USE_TRIPLANAR]) { |
1086 | if (flags[FLAG_UV2_USE_WORLD_TRIPLANAR]) { |
1087 | code += " uv2_power_normal=pow(abs(mat3(MODEL_MATRIX) * NORMAL), vec3(uv2_blend_sharpness));\n" ; |
1088 | code += " uv2_triplanar_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0f)).xyz * uv2_scale + uv2_offset;\n" ; |
1089 | } else { |
1090 | code += " uv2_power_normal=pow(abs(NORMAL), vec3(uv2_blend_sharpness));\n" ; |
1091 | code += " uv2_triplanar_pos = VERTEX * uv2_scale + uv2_offset;\n" ; |
1092 | } |
1093 | code += " uv2_power_normal/=dot(uv2_power_normal,vec3(1.0));\n" ; |
1094 | code += " uv2_triplanar_pos *= vec3(1.0,-1.0, 1.0);\n" ; |
1095 | } |
1096 | |
1097 | if (grow_enabled) { |
1098 | code += " VERTEX+=NORMAL*grow;\n" ; |
1099 | } |
1100 | |
1101 | code += "}\n" ; |
1102 | code += "\n\n" ; |
1103 | if (flags[FLAG_ALBEDO_TEXTURE_MSDF]) { |
1104 | code += "float msdf_median(float r, float g, float b, float a) {\n" ; |
1105 | code += " return min(max(min(r, g), min(max(r, g), b)), a);\n" ; |
1106 | code += "}\n" ; |
1107 | } |
1108 | code += "\n\n" ; |
1109 | if (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR]) { |
1110 | code += "vec4 triplanar_texture(sampler2D p_sampler,vec3 p_weights,vec3 p_triplanar_pos) {\n" ; |
1111 | code += " vec4 samp=vec4(0.0);\n" ; |
1112 | code += " samp+= texture(p_sampler,p_triplanar_pos.xy) * p_weights.z;\n" ; |
1113 | code += " samp+= texture(p_sampler,p_triplanar_pos.xz) * p_weights.y;\n" ; |
1114 | code += " samp+= texture(p_sampler,p_triplanar_pos.zy * vec2(-1.0,1.0)) * p_weights.x;\n" ; |
1115 | code += " return samp;\n" ; |
1116 | code += "}\n" ; |
1117 | } |
1118 | code += "\n\n" ; |
1119 | code += "void fragment() {\n" ; |
1120 | |
1121 | if (!flags[FLAG_UV1_USE_TRIPLANAR]) { |
1122 | code += " vec2 base_uv = UV;\n" ; |
1123 | } |
1124 | |
1125 | if ((features[FEATURE_DETAIL] && detail_uv == DETAIL_UV_2) || (features[FEATURE_AMBIENT_OCCLUSION] && flags[FLAG_AO_ON_UV2]) || (features[FEATURE_EMISSION] && flags[FLAG_EMISSION_ON_UV2])) { |
1126 | code += " vec2 base_uv2 = UV2;\n" ; |
1127 | } |
1128 | |
1129 | if (features[FEATURE_HEIGHT_MAPPING] && flags[FLAG_UV1_USE_TRIPLANAR]) { |
1130 | // Display both resource name and albedo texture name. |
1131 | // Materials are often built-in to scenes, so displaying the resource name alone may not be meaningful. |
1132 | // On the other hand, albedo textures are almost always external to the scene. |
1133 | if (textures[TEXTURE_ALBEDO].is_valid()) { |
1134 | WARN_PRINT(vformat("%s (albedo %s): Height mapping is not supported on triplanar materials. Ignoring height mapping in favor of triplanar mapping." , get_path(), textures[TEXTURE_ALBEDO]->get_path())); |
1135 | } else if (!get_path().is_empty()) { |
1136 | WARN_PRINT(vformat("%s: Height mapping is not supported on triplanar materials. Ignoring height mapping in favor of triplanar mapping." , get_path())); |
1137 | } else { |
1138 | // Resource wasn't saved yet. |
1139 | WARN_PRINT("Height mapping is not supported on triplanar materials. Ignoring height mapping in favor of triplanar mapping." ); |
1140 | } |
1141 | } |
1142 | |
1143 | if (!RenderingServer::get_singleton()->is_low_end() && features[FEATURE_HEIGHT_MAPPING] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //heightmap not supported with triplanar |
1144 | code += " {\n" ; |
1145 | code += " vec3 view_dir = normalize(normalize(-VERTEX + EYE_OFFSET) * mat3(TANGENT * heightmap_flip.x, -BINORMAL * heightmap_flip.y, NORMAL));\n" ; // binormal is negative due to mikktspace, flip 'unflips' it ;-) |
1146 | |
1147 | if (deep_parallax) { |
1148 | code += " float num_layers = mix(float(heightmap_max_layers),float(heightmap_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n" ; |
1149 | code += " float layer_depth = 1.0 / num_layers;\n" ; |
1150 | code += " float current_layer_depth = 0.0;\n" ; |
1151 | // Multiply the heightmap scale by 0.01 to improve heightmap scale usability. |
1152 | code += " vec2 P = view_dir.xy * heightmap_scale * 0.01;\n" ; |
1153 | code += " vec2 delta = P / num_layers;\n" ; |
1154 | code += " vec2 ofs = base_uv;\n" ; |
1155 | if (flags[FLAG_INVERT_HEIGHTMAP]) { |
1156 | code += " float depth = texture(texture_heightmap, ofs).r;\n" ; |
1157 | } else { |
1158 | code += " float depth = 1.0 - texture(texture_heightmap, ofs).r;\n" ; |
1159 | } |
1160 | code += " float current_depth = 0.0;\n" ; |
1161 | code += " while(current_depth < depth) {\n" ; |
1162 | code += " ofs -= delta;\n" ; |
1163 | if (flags[FLAG_INVERT_HEIGHTMAP]) { |
1164 | code += " depth = texture(texture_heightmap, ofs).r;\n" ; |
1165 | } else { |
1166 | code += " depth = 1.0 - texture(texture_heightmap, ofs).r;\n" ; |
1167 | } |
1168 | code += " current_depth += layer_depth;\n" ; |
1169 | code += " }\n" ; |
1170 | code += " vec2 prev_ofs = ofs + delta;\n" ; |
1171 | code += " float after_depth = depth - current_depth;\n" ; |
1172 | if (flags[FLAG_INVERT_HEIGHTMAP]) { |
1173 | code += " float before_depth = texture(texture_heightmap, prev_ofs).r - current_depth + layer_depth;\n" ; |
1174 | } else { |
1175 | code += " float before_depth = ( 1.0 - texture(texture_heightmap, prev_ofs).r ) - current_depth + layer_depth;\n" ; |
1176 | } |
1177 | code += " float weight = after_depth / (after_depth - before_depth);\n" ; |
1178 | code += " ofs = mix(ofs,prev_ofs,weight);\n" ; |
1179 | |
1180 | } else { |
1181 | if (flags[FLAG_INVERT_HEIGHTMAP]) { |
1182 | code += " float depth = texture(texture_heightmap, base_uv).r;\n" ; |
1183 | } else { |
1184 | code += " float depth = 1.0 - texture(texture_heightmap, base_uv).r;\n" ; |
1185 | } |
1186 | // Use offset limiting to improve the appearance of non-deep parallax. |
1187 | // This reduces the impression of depth, but avoids visible warping in the distance. |
1188 | // Multiply the heightmap scale by 0.01 to improve heightmap scale usability. |
1189 | code += " vec2 ofs = base_uv - view_dir.xy * depth * heightmap_scale * 0.01;\n" ; |
1190 | } |
1191 | |
1192 | code += " base_uv=ofs;\n" ; |
1193 | if (features[FEATURE_DETAIL] && detail_uv == DETAIL_UV_2) { |
1194 | code += " base_uv2-=ofs;\n" ; |
1195 | } |
1196 | |
1197 | code += " }\n" ; |
1198 | } |
1199 | |
1200 | if (flags[FLAG_USE_POINT_SIZE]) { |
1201 | code += " vec4 albedo_tex = texture(texture_albedo,POINT_COORD);\n" ; |
1202 | } else { |
1203 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
1204 | code += " vec4 albedo_tex = triplanar_texture(texture_albedo,uv1_power_normal,uv1_triplanar_pos);\n" ; |
1205 | } else { |
1206 | code += " vec4 albedo_tex = texture(texture_albedo,base_uv);\n" ; |
1207 | } |
1208 | } |
1209 | |
1210 | if (flags[FLAG_ALBEDO_TEXTURE_MSDF]) { |
1211 | code += " {\n" ; |
1212 | code += " albedo_tex.rgb = mix(vec3(1.0 + 0.055) * pow(albedo_tex.rgb, vec3(1.0 / 2.4)) - vec3(0.055), vec3(12.92) * albedo_tex.rgb.rgb, lessThan(albedo_tex.rgb, vec3(0.0031308)));\n" ; |
1213 | code += " vec2 msdf_size = vec2(msdf_pixel_range) / vec2(textureSize(texture_albedo, 0));\n" ; |
1214 | if (flags[FLAG_USE_POINT_SIZE]) { |
1215 | code += " vec2 dest_size = vec2(1.0) / fwidth(POINT_COORD);\n" ; |
1216 | } else { |
1217 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
1218 | code += " vec2 dest_size = vec2(1.0) / fwidth(uv1_triplanar_pos);\n" ; |
1219 | } else { |
1220 | code += " vec2 dest_size = vec2(1.0) / fwidth(base_uv);\n" ; |
1221 | } |
1222 | } |
1223 | code += " float px_size = max(0.5 * dot(msdf_size, dest_size), 1.0);\n" ; |
1224 | code += " float d = msdf_median(albedo_tex.r, albedo_tex.g, albedo_tex.b, albedo_tex.a) - 0.5;\n" ; |
1225 | code += " if (msdf_outline_size > 0.0) {\n" ; |
1226 | code += " float cr = clamp(msdf_outline_size, 0.0, msdf_pixel_range / 2.0) / msdf_pixel_range;\n" ; |
1227 | code += " albedo_tex.a = clamp((d + cr) * px_size, 0.0, 1.0);\n" ; |
1228 | code += " } else {\n" ; |
1229 | code += " albedo_tex.a = clamp(d * px_size + 0.5, 0.0, 1.0);\n" ; |
1230 | code += " }\n" ; |
1231 | code += " albedo_tex.rgb = vec3(1.0);\n" ; |
1232 | code += " }\n" ; |
1233 | } else if (flags[FLAG_ALBEDO_TEXTURE_FORCE_SRGB]) { |
1234 | code += " albedo_tex.rgb = mix(pow((albedo_tex.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)),vec3(2.4)),albedo_tex.rgb.rgb * (1.0 / 12.92),lessThan(albedo_tex.rgb,vec3(0.04045)));\n" ; |
1235 | } |
1236 | |
1237 | if (flags[FLAG_ALBEDO_FROM_VERTEX_COLOR]) { |
1238 | code += " albedo_tex *= COLOR;\n" ; |
1239 | } |
1240 | code += " ALBEDO = albedo.rgb * albedo_tex.rgb;\n" ; |
1241 | |
1242 | if (!orm) { |
1243 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
1244 | code += " float metallic_tex = dot(triplanar_texture(texture_metallic,uv1_power_normal,uv1_triplanar_pos),metallic_texture_channel);\n" ; |
1245 | } else { |
1246 | code += " float metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);\n" ; |
1247 | } |
1248 | code += " METALLIC = metallic_tex * metallic;\n" ; |
1249 | |
1250 | switch (roughness_texture_channel) { |
1251 | case TEXTURE_CHANNEL_RED: { |
1252 | code += " vec4 roughness_texture_channel = vec4(1.0,0.0,0.0,0.0);\n" ; |
1253 | } break; |
1254 | case TEXTURE_CHANNEL_GREEN: { |
1255 | code += " vec4 roughness_texture_channel = vec4(0.0,1.0,0.0,0.0);\n" ; |
1256 | } break; |
1257 | case TEXTURE_CHANNEL_BLUE: { |
1258 | code += " vec4 roughness_texture_channel = vec4(0.0,0.0,1.0,0.0);\n" ; |
1259 | } break; |
1260 | case TEXTURE_CHANNEL_ALPHA: { |
1261 | code += " vec4 roughness_texture_channel = vec4(0.0,0.0,0.0,1.0);\n" ; |
1262 | } break; |
1263 | case TEXTURE_CHANNEL_GRAYSCALE: { |
1264 | code += " vec4 roughness_texture_channel = vec4(0.333333,0.333333,0.333333,0.0);\n" ; |
1265 | } break; |
1266 | case TEXTURE_CHANNEL_MAX: |
1267 | break; // Internal value, skip. |
1268 | } |
1269 | |
1270 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
1271 | code += " float roughness_tex = dot(triplanar_texture(texture_roughness,uv1_power_normal,uv1_triplanar_pos),roughness_texture_channel);\n" ; |
1272 | } else { |
1273 | code += " float roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);\n" ; |
1274 | } |
1275 | code += " ROUGHNESS = roughness_tex * roughness;\n" ; |
1276 | code += " SPECULAR = specular;\n" ; |
1277 | } else { |
1278 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
1279 | code += " vec4 orm_tex = triplanar_texture(texture_orm,uv1_power_normal,uv1_triplanar_pos);\n" ; |
1280 | } else { |
1281 | code += " vec4 orm_tex = texture(texture_orm,base_uv);\n" ; |
1282 | } |
1283 | |
1284 | code += " ROUGHNESS = orm_tex.g;\n" ; |
1285 | code += " METALLIC = orm_tex.b;\n" ; |
1286 | } |
1287 | |
1288 | if (features[FEATURE_NORMAL_MAPPING]) { |
1289 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
1290 | code += " NORMAL_MAP = triplanar_texture(texture_normal,uv1_power_normal,uv1_triplanar_pos).rgb;\n" ; |
1291 | } else { |
1292 | code += " NORMAL_MAP = texture(texture_normal,base_uv).rgb;\n" ; |
1293 | } |
1294 | code += " NORMAL_MAP_DEPTH = normal_scale;\n" ; |
1295 | } |
1296 | |
1297 | if (features[FEATURE_EMISSION]) { |
1298 | if (flags[FLAG_EMISSION_ON_UV2]) { |
1299 | if (flags[FLAG_UV2_USE_TRIPLANAR]) { |
1300 | code += " vec3 emission_tex = triplanar_texture(texture_emission,uv2_power_normal,uv2_triplanar_pos).rgb;\n" ; |
1301 | } else { |
1302 | code += " vec3 emission_tex = texture(texture_emission,base_uv2).rgb;\n" ; |
1303 | } |
1304 | } else { |
1305 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
1306 | code += " vec3 emission_tex = triplanar_texture(texture_emission,uv1_power_normal,uv1_triplanar_pos).rgb;\n" ; |
1307 | } else { |
1308 | code += " vec3 emission_tex = texture(texture_emission,base_uv).rgb;\n" ; |
1309 | } |
1310 | } |
1311 | |
1312 | if (emission_op == EMISSION_OP_ADD) { |
1313 | code += " EMISSION = (emission.rgb+emission_tex)*emission_energy;\n" ; |
1314 | } else { |
1315 | code += " EMISSION = (emission.rgb*emission_tex)*emission_energy;\n" ; |
1316 | } |
1317 | } |
1318 | |
1319 | if (features[FEATURE_REFRACTION]) { |
1320 | if (features[FEATURE_NORMAL_MAPPING]) { |
1321 | code += " vec3 unpacked_normal = NORMAL_MAP;\n" ; |
1322 | code += " unpacked_normal.xy = unpacked_normal.xy * 2.0 - 1.0;\n" ; |
1323 | code += " unpacked_normal.z = sqrt(max(0.0, 1.0 - dot(unpacked_normal.xy, unpacked_normal.xy)));\n" ; |
1324 | code += " vec3 ref_normal = normalize( mix(NORMAL,TANGENT * unpacked_normal.x + BINORMAL * unpacked_normal.y + NORMAL * unpacked_normal.z,NORMAL_MAP_DEPTH) );\n" ; |
1325 | } else { |
1326 | code += " vec3 ref_normal = NORMAL;\n" ; |
1327 | } |
1328 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
1329 | code += " vec2 ref_ofs = SCREEN_UV - ref_normal.xy * dot(triplanar_texture(texture_refraction,uv1_power_normal,uv1_triplanar_pos),refraction_texture_channel) * refraction;\n" ; |
1330 | } else { |
1331 | code += " vec2 ref_ofs = SCREEN_UV - ref_normal.xy * dot(texture(texture_refraction,base_uv),refraction_texture_channel) * refraction;\n" ; |
1332 | } |
1333 | code += " float ref_amount = 1.0 - albedo.a * albedo_tex.a;\n" ; |
1334 | code += " EMISSION += textureLod(screen_texture,ref_ofs,ROUGHNESS * 8.0).rgb * ref_amount * EXPOSURE;\n" ; |
1335 | code += " ALBEDO *= 1.0 - ref_amount;\n" ; |
1336 | code += " ALPHA = 1.0;\n" ; |
1337 | |
1338 | } else if (transparency != TRANSPARENCY_DISABLED || flags[FLAG_USE_SHADOW_TO_OPACITY] || (distance_fade == DISTANCE_FADE_PIXEL_ALPHA) || proximity_fade_enabled) { |
1339 | code += " ALPHA *= albedo.a * albedo_tex.a;\n" ; |
1340 | } |
1341 | if (transparency == TRANSPARENCY_ALPHA_HASH) { |
1342 | code += " ALPHA_HASH_SCALE = alpha_hash_scale;\n" ; |
1343 | } else if (transparency == TRANSPARENCY_ALPHA_SCISSOR) { |
1344 | code += " ALPHA_SCISSOR_THRESHOLD = alpha_scissor_threshold;\n" ; |
1345 | } |
1346 | if (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF && (transparency == TRANSPARENCY_ALPHA_HASH || transparency == TRANSPARENCY_ALPHA_SCISSOR)) { |
1347 | code += " ALPHA_ANTIALIASING_EDGE = alpha_antialiasing_edge;\n" ; |
1348 | code += " ALPHA_TEXTURE_COORDINATE = UV * vec2(albedo_texture_size);\n" ; |
1349 | } |
1350 | |
1351 | if (proximity_fade_enabled) { |
1352 | code += " float depth_tex = textureLod(depth_texture,SCREEN_UV,0.0).r;\n" ; |
1353 | code += " vec4 world_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV*2.0-1.0,depth_tex,1.0);\n" ; |
1354 | code += " world_pos.xyz/=world_pos.w;\n" ; |
1355 | code += " ALPHA*=clamp(1.0-smoothstep(world_pos.z+proximity_fade_distance,world_pos.z,VERTEX.z),0.0,1.0);\n" ; |
1356 | } |
1357 | |
1358 | if (distance_fade != DISTANCE_FADE_DISABLED) { |
1359 | // Use the slightly more expensive circular fade (distance to the object) instead of linear |
1360 | // (Z distance), so that the fade is always the same regardless of the camera angle. |
1361 | if ((distance_fade == DISTANCE_FADE_OBJECT_DITHER || distance_fade == DISTANCE_FADE_PIXEL_DITHER)) { |
1362 | if (!RenderingServer::get_singleton()->is_low_end()) { |
1363 | code += " {\n" ; |
1364 | |
1365 | if (distance_fade == DISTANCE_FADE_OBJECT_DITHER) { |
1366 | code += " float fade_distance = length((VIEW_MATRIX * MODEL_MATRIX[3]));\n" ; |
1367 | } else { |
1368 | code += " float fade_distance = length(VERTEX);\n" ; |
1369 | } |
1370 | // Use interleaved gradient noise, which is fast but still looks good. |
1371 | code += " const vec3 magic = vec3(0.06711056f, 0.00583715f, 52.9829189f);" ; |
1372 | code += " float fade = clamp(smoothstep(distance_fade_min, distance_fade_max, fade_distance), 0.0, 1.0);\n" ; |
1373 | // Use a hard cap to prevent a few stray pixels from remaining when past the fade-out distance. |
1374 | code += " if (fade < 0.001 || fade < fract(magic.z * fract(dot(FRAGCOORD.xy, magic.xy)))) {\n" ; |
1375 | code += " discard;\n" ; |
1376 | code += " }\n" ; |
1377 | |
1378 | code += " }\n\n" ; |
1379 | } |
1380 | |
1381 | } else { |
1382 | code += " ALPHA *= clamp(smoothstep(distance_fade_min, distance_fade_max, length(VERTEX)), 0.0, 1.0);\n" ; |
1383 | } |
1384 | } |
1385 | |
1386 | if (features[FEATURE_RIM]) { |
1387 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
1388 | code += " vec2 rim_tex = triplanar_texture(texture_rim,uv1_power_normal,uv1_triplanar_pos).xy;\n" ; |
1389 | } else { |
1390 | code += " vec2 rim_tex = texture(texture_rim,base_uv).xy;\n" ; |
1391 | } |
1392 | code += " RIM = rim*rim_tex.x;" ; |
1393 | code += " RIM_TINT = rim_tint*rim_tex.y;\n" ; |
1394 | } |
1395 | |
1396 | if (features[FEATURE_CLEARCOAT]) { |
1397 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
1398 | code += " vec2 clearcoat_tex = triplanar_texture(texture_clearcoat,uv1_power_normal,uv1_triplanar_pos).xy;\n" ; |
1399 | } else { |
1400 | code += " vec2 clearcoat_tex = texture(texture_clearcoat,base_uv).xy;\n" ; |
1401 | } |
1402 | code += " CLEARCOAT = clearcoat*clearcoat_tex.x;" ; |
1403 | code += " CLEARCOAT_ROUGHNESS = clearcoat_roughness*clearcoat_tex.y;\n" ; |
1404 | } |
1405 | |
1406 | if (features[FEATURE_ANISOTROPY]) { |
1407 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
1408 | code += " vec3 anisotropy_tex = triplanar_texture(texture_flowmap,uv1_power_normal,uv1_triplanar_pos).rga;\n" ; |
1409 | } else { |
1410 | code += " vec3 anisotropy_tex = texture(texture_flowmap,base_uv).rga;\n" ; |
1411 | } |
1412 | code += " ANISOTROPY = anisotropy_ratio*anisotropy_tex.b;\n" ; |
1413 | code += " ANISOTROPY_FLOW = anisotropy_tex.rg*2.0-1.0;\n" ; |
1414 | } |
1415 | |
1416 | if (features[FEATURE_AMBIENT_OCCLUSION]) { |
1417 | if (!orm) { |
1418 | if (flags[FLAG_AO_ON_UV2]) { |
1419 | if (flags[FLAG_UV2_USE_TRIPLANAR]) { |
1420 | code += " AO = dot(triplanar_texture(texture_ambient_occlusion,uv2_power_normal,uv2_triplanar_pos),ao_texture_channel);\n" ; |
1421 | } else { |
1422 | code += " AO = dot(texture(texture_ambient_occlusion,base_uv2),ao_texture_channel);\n" ; |
1423 | } |
1424 | } else { |
1425 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
1426 | code += " AO = dot(triplanar_texture(texture_ambient_occlusion,uv1_power_normal,uv1_triplanar_pos),ao_texture_channel);\n" ; |
1427 | } else { |
1428 | code += " AO = dot(texture(texture_ambient_occlusion,base_uv),ao_texture_channel);\n" ; |
1429 | } |
1430 | } |
1431 | } else { |
1432 | code += " AO = orm_tex.r;\n" ; |
1433 | } |
1434 | |
1435 | code += " AO_LIGHT_AFFECT = ao_light_affect;\n" ; |
1436 | } |
1437 | |
1438 | if (features[FEATURE_SUBSURFACE_SCATTERING]) { |
1439 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
1440 | code += " float sss_tex = triplanar_texture(texture_subsurface_scattering,uv1_power_normal,uv1_triplanar_pos).r;\n" ; |
1441 | } else { |
1442 | code += " float sss_tex = texture(texture_subsurface_scattering,base_uv).r;\n" ; |
1443 | } |
1444 | code += " SSS_STRENGTH=subsurface_scattering_strength*sss_tex;\n" ; |
1445 | } |
1446 | |
1447 | if (features[FEATURE_SUBSURFACE_TRANSMITTANCE]) { |
1448 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
1449 | code += " vec4 trans_color_tex = triplanar_texture(texture_subsurface_transmittance,uv1_power_normal,uv1_triplanar_pos);\n" ; |
1450 | } else { |
1451 | code += " vec4 trans_color_tex = texture(texture_subsurface_transmittance,base_uv);\n" ; |
1452 | } |
1453 | code += " SSS_TRANSMITTANCE_COLOR=transmittance_color*trans_color_tex;\n" ; |
1454 | |
1455 | code += " SSS_TRANSMITTANCE_DEPTH=transmittance_depth;\n" ; |
1456 | code += " SSS_TRANSMITTANCE_BOOST=transmittance_boost;\n" ; |
1457 | } |
1458 | |
1459 | if (features[FEATURE_BACKLIGHT]) { |
1460 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
1461 | code += " vec3 backlight_tex = triplanar_texture(texture_backlight,uv1_power_normal,uv1_triplanar_pos).rgb;\n" ; |
1462 | } else { |
1463 | code += " vec3 backlight_tex = texture(texture_backlight,base_uv).rgb;\n" ; |
1464 | } |
1465 | code += " BACKLIGHT = (backlight.rgb+backlight_tex);\n" ; |
1466 | } |
1467 | |
1468 | if (features[FEATURE_DETAIL]) { |
1469 | bool triplanar = (flags[FLAG_UV1_USE_TRIPLANAR] && detail_uv == DETAIL_UV_1) || (flags[FLAG_UV2_USE_TRIPLANAR] && detail_uv == DETAIL_UV_2); |
1470 | |
1471 | if (triplanar) { |
1472 | String tp_uv = detail_uv == DETAIL_UV_1 ? "uv1" : "uv2" ; |
1473 | code += " vec4 detail_tex = triplanar_texture(texture_detail_albedo," + tp_uv + "_power_normal," + tp_uv + "_triplanar_pos);\n" ; |
1474 | code += " vec4 detail_norm_tex = triplanar_texture(texture_detail_normal," + tp_uv + "_power_normal," + tp_uv + "_triplanar_pos);\n" ; |
1475 | |
1476 | } else { |
1477 | String det_uv = detail_uv == DETAIL_UV_1 ? "base_uv" : "base_uv2" ; |
1478 | code += " vec4 detail_tex = texture(texture_detail_albedo," + det_uv + ");\n" ; |
1479 | code += " vec4 detail_norm_tex = texture(texture_detail_normal," + det_uv + ");\n" ; |
1480 | } |
1481 | |
1482 | if (flags[FLAG_UV1_USE_TRIPLANAR]) { |
1483 | code += " vec4 detail_mask_tex = triplanar_texture(texture_detail_mask,uv1_power_normal,uv1_triplanar_pos);\n" ; |
1484 | } else { |
1485 | code += " vec4 detail_mask_tex = texture(texture_detail_mask,base_uv);\n" ; |
1486 | } |
1487 | |
1488 | switch (detail_blend_mode) { |
1489 | case BLEND_MODE_MIX: { |
1490 | code += " vec3 detail = mix(ALBEDO.rgb,detail_tex.rgb,detail_tex.a);\n" ; |
1491 | } break; |
1492 | case BLEND_MODE_ADD: { |
1493 | code += " vec3 detail = mix(ALBEDO.rgb,ALBEDO.rgb+detail_tex.rgb,detail_tex.a);\n" ; |
1494 | } break; |
1495 | case BLEND_MODE_SUB: { |
1496 | code += " vec3 detail = mix(ALBEDO.rgb,ALBEDO.rgb-detail_tex.rgb,detail_tex.a);\n" ; |
1497 | } break; |
1498 | case BLEND_MODE_MUL: { |
1499 | code += " vec3 detail = mix(ALBEDO.rgb,ALBEDO.rgb*detail_tex.rgb,detail_tex.a);\n" ; |
1500 | } break; |
1501 | case BLEND_MODE_MAX: |
1502 | break; // Internal value, skip. |
1503 | } |
1504 | |
1505 | code += " vec3 detail_norm = mix(NORMAL_MAP,detail_norm_tex.rgb,detail_tex.a);\n" ; |
1506 | code += " NORMAL_MAP = mix(NORMAL_MAP,detail_norm,detail_mask_tex.r);\n" ; |
1507 | code += " ALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n" ; |
1508 | } |
1509 | |
1510 | code += "}\n" ; |
1511 | |
1512 | ShaderData shader_data; |
1513 | shader_data.shader = RS::get_singleton()->shader_create(); |
1514 | shader_data.users = 1; |
1515 | |
1516 | RS::get_singleton()->shader_set_code(shader_data.shader, code); |
1517 | |
1518 | shader_map[mk] = shader_data; |
1519 | |
1520 | RS::get_singleton()->material_set_shader(_get_material(), shader_data.shader); |
1521 | } |
1522 | |
1523 | void BaseMaterial3D::flush_changes() { |
1524 | MutexLock lock(material_mutex); |
1525 | |
1526 | while (dirty_materials.first()) { |
1527 | dirty_materials.first()->self()->_update_shader(); |
1528 | } |
1529 | } |
1530 | |
1531 | void BaseMaterial3D::_queue_shader_change() { |
1532 | MutexLock lock(material_mutex); |
1533 | |
1534 | if (_is_initialized() && !element.in_list()) { |
1535 | dirty_materials.add(&element); |
1536 | } |
1537 | } |
1538 | |
1539 | bool BaseMaterial3D::_is_shader_dirty() const { |
1540 | MutexLock lock(material_mutex); |
1541 | |
1542 | return element.in_list(); |
1543 | } |
1544 | |
1545 | void BaseMaterial3D::set_albedo(const Color &p_albedo) { |
1546 | albedo = p_albedo; |
1547 | |
1548 | RS::get_singleton()->material_set_param(_get_material(), shader_names->albedo, p_albedo); |
1549 | } |
1550 | |
1551 | Color BaseMaterial3D::get_albedo() const { |
1552 | return albedo; |
1553 | } |
1554 | |
1555 | void BaseMaterial3D::set_specular(float p_specular) { |
1556 | specular = p_specular; |
1557 | RS::get_singleton()->material_set_param(_get_material(), shader_names->specular, p_specular); |
1558 | } |
1559 | |
1560 | float BaseMaterial3D::get_specular() const { |
1561 | return specular; |
1562 | } |
1563 | |
1564 | void BaseMaterial3D::set_roughness(float p_roughness) { |
1565 | roughness = p_roughness; |
1566 | RS::get_singleton()->material_set_param(_get_material(), shader_names->roughness, p_roughness); |
1567 | } |
1568 | |
1569 | float BaseMaterial3D::get_roughness() const { |
1570 | return roughness; |
1571 | } |
1572 | |
1573 | void BaseMaterial3D::set_metallic(float p_metallic) { |
1574 | metallic = p_metallic; |
1575 | RS::get_singleton()->material_set_param(_get_material(), shader_names->metallic, p_metallic); |
1576 | } |
1577 | |
1578 | float BaseMaterial3D::get_metallic() const { |
1579 | return metallic; |
1580 | } |
1581 | |
1582 | void BaseMaterial3D::set_emission(const Color &p_emission) { |
1583 | emission = p_emission; |
1584 | RS::get_singleton()->material_set_param(_get_material(), shader_names->emission, p_emission); |
1585 | } |
1586 | |
1587 | Color BaseMaterial3D::get_emission() const { |
1588 | return emission; |
1589 | } |
1590 | |
1591 | void BaseMaterial3D::set_emission_energy_multiplier(float p_emission_energy_multiplier) { |
1592 | emission_energy_multiplier = p_emission_energy_multiplier; |
1593 | if (GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units" )) { |
1594 | RS::get_singleton()->material_set_param(_get_material(), shader_names->emission_energy, p_emission_energy_multiplier * emission_intensity); |
1595 | } else { |
1596 | RS::get_singleton()->material_set_param(_get_material(), shader_names->emission_energy, p_emission_energy_multiplier); |
1597 | } |
1598 | } |
1599 | |
1600 | float BaseMaterial3D::get_emission_energy_multiplier() const { |
1601 | return emission_energy_multiplier; |
1602 | } |
1603 | |
1604 | void BaseMaterial3D::set_emission_intensity(float p_emission_intensity) { |
1605 | ERR_FAIL_COND_EDMSG(!GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units" ), "Cannot set material emission intensity when Physical Light Units disabled." ); |
1606 | emission_intensity = p_emission_intensity; |
1607 | RS::get_singleton()->material_set_param(_get_material(), shader_names->emission_energy, emission_energy_multiplier * emission_intensity); |
1608 | } |
1609 | |
1610 | float BaseMaterial3D::get_emission_intensity() const { |
1611 | return emission_intensity; |
1612 | } |
1613 | |
1614 | void BaseMaterial3D::set_normal_scale(float p_normal_scale) { |
1615 | normal_scale = p_normal_scale; |
1616 | RS::get_singleton()->material_set_param(_get_material(), shader_names->normal_scale, p_normal_scale); |
1617 | } |
1618 | |
1619 | float BaseMaterial3D::get_normal_scale() const { |
1620 | return normal_scale; |
1621 | } |
1622 | |
1623 | void BaseMaterial3D::set_rim(float p_rim) { |
1624 | rim = p_rim; |
1625 | RS::get_singleton()->material_set_param(_get_material(), shader_names->rim, p_rim); |
1626 | } |
1627 | |
1628 | float BaseMaterial3D::get_rim() const { |
1629 | return rim; |
1630 | } |
1631 | |
1632 | void BaseMaterial3D::set_rim_tint(float p_rim_tint) { |
1633 | rim_tint = p_rim_tint; |
1634 | RS::get_singleton()->material_set_param(_get_material(), shader_names->rim_tint, p_rim_tint); |
1635 | } |
1636 | |
1637 | float BaseMaterial3D::get_rim_tint() const { |
1638 | return rim_tint; |
1639 | } |
1640 | |
1641 | void BaseMaterial3D::set_ao_light_affect(float p_ao_light_affect) { |
1642 | ao_light_affect = p_ao_light_affect; |
1643 | RS::get_singleton()->material_set_param(_get_material(), shader_names->ao_light_affect, p_ao_light_affect); |
1644 | } |
1645 | |
1646 | float BaseMaterial3D::get_ao_light_affect() const { |
1647 | return ao_light_affect; |
1648 | } |
1649 | |
1650 | void BaseMaterial3D::set_clearcoat(float p_clearcoat) { |
1651 | clearcoat = p_clearcoat; |
1652 | RS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat, p_clearcoat); |
1653 | } |
1654 | |
1655 | float BaseMaterial3D::get_clearcoat() const { |
1656 | return clearcoat; |
1657 | } |
1658 | |
1659 | void BaseMaterial3D::set_clearcoat_roughness(float p_clearcoat_roughness) { |
1660 | clearcoat_roughness = p_clearcoat_roughness; |
1661 | RS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat_roughness, p_clearcoat_roughness); |
1662 | } |
1663 | |
1664 | float BaseMaterial3D::get_clearcoat_roughness() const { |
1665 | return clearcoat_roughness; |
1666 | } |
1667 | |
1668 | void BaseMaterial3D::set_anisotropy(float p_anisotropy) { |
1669 | anisotropy = p_anisotropy; |
1670 | RS::get_singleton()->material_set_param(_get_material(), shader_names->anisotropy, p_anisotropy); |
1671 | } |
1672 | |
1673 | float BaseMaterial3D::get_anisotropy() const { |
1674 | return anisotropy; |
1675 | } |
1676 | |
1677 | void BaseMaterial3D::set_heightmap_scale(float p_heightmap_scale) { |
1678 | heightmap_scale = p_heightmap_scale; |
1679 | RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_scale, p_heightmap_scale); |
1680 | } |
1681 | |
1682 | float BaseMaterial3D::get_heightmap_scale() const { |
1683 | return heightmap_scale; |
1684 | } |
1685 | |
1686 | void BaseMaterial3D::set_subsurface_scattering_strength(float p_subsurface_scattering_strength) { |
1687 | subsurface_scattering_strength = p_subsurface_scattering_strength; |
1688 | RS::get_singleton()->material_set_param(_get_material(), shader_names->subsurface_scattering_strength, subsurface_scattering_strength); |
1689 | } |
1690 | |
1691 | float BaseMaterial3D::get_subsurface_scattering_strength() const { |
1692 | return subsurface_scattering_strength; |
1693 | } |
1694 | |
1695 | void BaseMaterial3D::set_transmittance_color(const Color &p_color) { |
1696 | transmittance_color = p_color; |
1697 | RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_color, p_color); |
1698 | } |
1699 | |
1700 | Color BaseMaterial3D::get_transmittance_color() const { |
1701 | return transmittance_color; |
1702 | } |
1703 | |
1704 | void BaseMaterial3D::set_transmittance_depth(float p_depth) { |
1705 | transmittance_depth = p_depth; |
1706 | RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_depth, p_depth); |
1707 | } |
1708 | |
1709 | float BaseMaterial3D::get_transmittance_depth() const { |
1710 | return transmittance_depth; |
1711 | } |
1712 | |
1713 | void BaseMaterial3D::set_transmittance_boost(float p_boost) { |
1714 | transmittance_boost = p_boost; |
1715 | RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_boost, p_boost); |
1716 | } |
1717 | |
1718 | float BaseMaterial3D::get_transmittance_boost() const { |
1719 | return transmittance_boost; |
1720 | } |
1721 | |
1722 | void BaseMaterial3D::set_backlight(const Color &p_backlight) { |
1723 | backlight = p_backlight; |
1724 | RS::get_singleton()->material_set_param(_get_material(), shader_names->backlight, backlight); |
1725 | } |
1726 | |
1727 | Color BaseMaterial3D::get_backlight() const { |
1728 | return backlight; |
1729 | } |
1730 | |
1731 | void BaseMaterial3D::set_refraction(float p_refraction) { |
1732 | refraction = p_refraction; |
1733 | RS::get_singleton()->material_set_param(_get_material(), shader_names->refraction, refraction); |
1734 | } |
1735 | |
1736 | float BaseMaterial3D::get_refraction() const { |
1737 | return refraction; |
1738 | } |
1739 | |
1740 | void BaseMaterial3D::set_detail_uv(DetailUV p_detail_uv) { |
1741 | if (detail_uv == p_detail_uv) { |
1742 | return; |
1743 | } |
1744 | |
1745 | detail_uv = p_detail_uv; |
1746 | _queue_shader_change(); |
1747 | } |
1748 | |
1749 | BaseMaterial3D::DetailUV BaseMaterial3D::get_detail_uv() const { |
1750 | return detail_uv; |
1751 | } |
1752 | |
1753 | void BaseMaterial3D::set_blend_mode(BlendMode p_mode) { |
1754 | if (blend_mode == p_mode) { |
1755 | return; |
1756 | } |
1757 | |
1758 | blend_mode = p_mode; |
1759 | _queue_shader_change(); |
1760 | } |
1761 | |
1762 | BaseMaterial3D::BlendMode BaseMaterial3D::get_blend_mode() const { |
1763 | return blend_mode; |
1764 | } |
1765 | |
1766 | void BaseMaterial3D::set_detail_blend_mode(BlendMode p_mode) { |
1767 | detail_blend_mode = p_mode; |
1768 | _queue_shader_change(); |
1769 | } |
1770 | |
1771 | BaseMaterial3D::BlendMode BaseMaterial3D::get_detail_blend_mode() const { |
1772 | return detail_blend_mode; |
1773 | } |
1774 | |
1775 | void BaseMaterial3D::set_transparency(Transparency p_transparency) { |
1776 | if (transparency == p_transparency) { |
1777 | return; |
1778 | } |
1779 | |
1780 | transparency = p_transparency; |
1781 | _queue_shader_change(); |
1782 | notify_property_list_changed(); |
1783 | } |
1784 | |
1785 | BaseMaterial3D::Transparency BaseMaterial3D::get_transparency() const { |
1786 | return transparency; |
1787 | } |
1788 | |
1789 | void BaseMaterial3D::set_alpha_antialiasing(AlphaAntiAliasing p_alpha_aa) { |
1790 | if (alpha_antialiasing_mode == p_alpha_aa) { |
1791 | return; |
1792 | } |
1793 | |
1794 | alpha_antialiasing_mode = p_alpha_aa; |
1795 | _queue_shader_change(); |
1796 | notify_property_list_changed(); |
1797 | } |
1798 | |
1799 | BaseMaterial3D::AlphaAntiAliasing BaseMaterial3D::get_alpha_antialiasing() const { |
1800 | return alpha_antialiasing_mode; |
1801 | } |
1802 | |
1803 | void BaseMaterial3D::set_shading_mode(ShadingMode p_shading_mode) { |
1804 | if (shading_mode == p_shading_mode) { |
1805 | return; |
1806 | } |
1807 | |
1808 | shading_mode = p_shading_mode; |
1809 | _queue_shader_change(); |
1810 | notify_property_list_changed(); |
1811 | } |
1812 | |
1813 | BaseMaterial3D::ShadingMode BaseMaterial3D::get_shading_mode() const { |
1814 | return shading_mode; |
1815 | } |
1816 | |
1817 | void BaseMaterial3D::set_depth_draw_mode(DepthDrawMode p_mode) { |
1818 | if (depth_draw_mode == p_mode) { |
1819 | return; |
1820 | } |
1821 | |
1822 | depth_draw_mode = p_mode; |
1823 | _queue_shader_change(); |
1824 | } |
1825 | |
1826 | BaseMaterial3D::DepthDrawMode BaseMaterial3D::get_depth_draw_mode() const { |
1827 | return depth_draw_mode; |
1828 | } |
1829 | |
1830 | void BaseMaterial3D::set_cull_mode(CullMode p_mode) { |
1831 | if (cull_mode == p_mode) { |
1832 | return; |
1833 | } |
1834 | |
1835 | cull_mode = p_mode; |
1836 | _queue_shader_change(); |
1837 | } |
1838 | |
1839 | BaseMaterial3D::CullMode BaseMaterial3D::get_cull_mode() const { |
1840 | return cull_mode; |
1841 | } |
1842 | |
1843 | void BaseMaterial3D::set_diffuse_mode(DiffuseMode p_mode) { |
1844 | if (diffuse_mode == p_mode) { |
1845 | return; |
1846 | } |
1847 | |
1848 | diffuse_mode = p_mode; |
1849 | _queue_shader_change(); |
1850 | } |
1851 | |
1852 | BaseMaterial3D::DiffuseMode BaseMaterial3D::get_diffuse_mode() const { |
1853 | return diffuse_mode; |
1854 | } |
1855 | |
1856 | void BaseMaterial3D::set_specular_mode(SpecularMode p_mode) { |
1857 | if (specular_mode == p_mode) { |
1858 | return; |
1859 | } |
1860 | |
1861 | specular_mode = p_mode; |
1862 | _queue_shader_change(); |
1863 | } |
1864 | |
1865 | BaseMaterial3D::SpecularMode BaseMaterial3D::get_specular_mode() const { |
1866 | return specular_mode; |
1867 | } |
1868 | |
1869 | void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) { |
1870 | ERR_FAIL_INDEX(p_flag, FLAG_MAX); |
1871 | |
1872 | if (flags[p_flag] == p_enabled) { |
1873 | return; |
1874 | } |
1875 | |
1876 | flags[p_flag] = p_enabled; |
1877 | |
1878 | if ( |
1879 | p_flag == FLAG_USE_SHADOW_TO_OPACITY || |
1880 | p_flag == FLAG_USE_TEXTURE_REPEAT || |
1881 | p_flag == FLAG_SUBSURFACE_MODE_SKIN || |
1882 | p_flag == FLAG_USE_POINT_SIZE || |
1883 | p_flag == FLAG_UV1_USE_TRIPLANAR || |
1884 | p_flag == FLAG_UV2_USE_TRIPLANAR) { |
1885 | notify_property_list_changed(); |
1886 | } |
1887 | |
1888 | if (p_flag == FLAG_PARTICLE_TRAILS_MODE) { |
1889 | update_configuration_warning(); |
1890 | } |
1891 | |
1892 | _queue_shader_change(); |
1893 | } |
1894 | |
1895 | bool BaseMaterial3D::get_flag(Flags p_flag) const { |
1896 | ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false); |
1897 | return flags[p_flag]; |
1898 | } |
1899 | |
1900 | void BaseMaterial3D::set_feature(Feature p_feature, bool p_enabled) { |
1901 | ERR_FAIL_INDEX(p_feature, FEATURE_MAX); |
1902 | if (features[p_feature] == p_enabled) { |
1903 | return; |
1904 | } |
1905 | |
1906 | features[p_feature] = p_enabled; |
1907 | notify_property_list_changed(); |
1908 | _queue_shader_change(); |
1909 | } |
1910 | |
1911 | bool BaseMaterial3D::get_feature(Feature p_feature) const { |
1912 | ERR_FAIL_INDEX_V(p_feature, FEATURE_MAX, false); |
1913 | return features[p_feature]; |
1914 | } |
1915 | |
1916 | void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture) { |
1917 | ERR_FAIL_INDEX(p_param, TEXTURE_MAX); |
1918 | |
1919 | textures[p_param] = p_texture; |
1920 | RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); |
1921 | RS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid); |
1922 | |
1923 | if (p_texture.is_valid() && p_param == TEXTURE_ALBEDO) { |
1924 | RS::get_singleton()->material_set_param(_get_material(), shader_names->albedo_texture_size, |
1925 | Vector2i(p_texture->get_width(), p_texture->get_height())); |
1926 | } |
1927 | |
1928 | notify_property_list_changed(); |
1929 | _queue_shader_change(); |
1930 | } |
1931 | |
1932 | Ref<Texture2D> BaseMaterial3D::get_texture(TextureParam p_param) const { |
1933 | ERR_FAIL_INDEX_V(p_param, TEXTURE_MAX, Ref<Texture2D>()); |
1934 | return textures[p_param]; |
1935 | } |
1936 | |
1937 | Ref<Texture2D> BaseMaterial3D::get_texture_by_name(StringName p_name) const { |
1938 | for (int i = 0; i < (int)BaseMaterial3D::TEXTURE_MAX; i++) { |
1939 | TextureParam param = TextureParam(i); |
1940 | if (p_name == shader_names->texture_names[param]) { |
1941 | return textures[param]; |
1942 | } |
1943 | } |
1944 | return Ref<Texture2D>(); |
1945 | } |
1946 | |
1947 | void BaseMaterial3D::set_texture_filter(TextureFilter p_filter) { |
1948 | texture_filter = p_filter; |
1949 | _queue_shader_change(); |
1950 | } |
1951 | |
1952 | BaseMaterial3D::TextureFilter BaseMaterial3D::get_texture_filter() const { |
1953 | return texture_filter; |
1954 | } |
1955 | |
1956 | void BaseMaterial3D::_validate_feature(const String &text, Feature feature, PropertyInfo &property) const { |
1957 | if (property.name.begins_with(text) && property.name != text + "_enabled" && !features[feature]) { |
1958 | property.usage = PROPERTY_USAGE_NO_EDITOR; |
1959 | } |
1960 | } |
1961 | |
1962 | void BaseMaterial3D::_validate_property(PropertyInfo &p_property) const { |
1963 | _validate_feature("normal" , FEATURE_NORMAL_MAPPING, p_property); |
1964 | _validate_feature("emission" , FEATURE_EMISSION, p_property); |
1965 | _validate_feature("rim" , FEATURE_RIM, p_property); |
1966 | _validate_feature("clearcoat" , FEATURE_CLEARCOAT, p_property); |
1967 | _validate_feature("anisotropy" , FEATURE_ANISOTROPY, p_property); |
1968 | _validate_feature("ao" , FEATURE_AMBIENT_OCCLUSION, p_property); |
1969 | _validate_feature("heightmap" , FEATURE_HEIGHT_MAPPING, p_property); |
1970 | _validate_feature("subsurf_scatter" , FEATURE_SUBSURFACE_SCATTERING, p_property); |
1971 | _validate_feature("backlight" , FEATURE_BACKLIGHT, p_property); |
1972 | _validate_feature("refraction" , FEATURE_REFRACTION, p_property); |
1973 | _validate_feature("detail" , FEATURE_DETAIL, p_property); |
1974 | |
1975 | if (p_property.name == "emission_intensity" && !GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units" )) { |
1976 | p_property.usage = PROPERTY_USAGE_NONE; |
1977 | } |
1978 | |
1979 | if (p_property.name.begins_with("particles_anim_" ) && billboard_mode != BILLBOARD_PARTICLES) { |
1980 | p_property.usage = PROPERTY_USAGE_NONE; |
1981 | } |
1982 | |
1983 | if (p_property.name == "billboard_keep_scale" && billboard_mode == BILLBOARD_DISABLED) { |
1984 | p_property.usage = PROPERTY_USAGE_NO_EDITOR; |
1985 | } |
1986 | |
1987 | if (p_property.name == "grow_amount" && !grow_enabled) { |
1988 | p_property.usage = PROPERTY_USAGE_NO_EDITOR; |
1989 | } |
1990 | |
1991 | if (p_property.name == "point_size" && !flags[FLAG_USE_POINT_SIZE]) { |
1992 | p_property.usage = PROPERTY_USAGE_NO_EDITOR; |
1993 | } |
1994 | |
1995 | if (p_property.name == "proximity_fade_distance" && !proximity_fade_enabled) { |
1996 | p_property.usage = PROPERTY_USAGE_NO_EDITOR; |
1997 | } |
1998 | |
1999 | if (p_property.name == "msdf_pixel_range" && !flags[FLAG_ALBEDO_TEXTURE_MSDF]) { |
2000 | p_property.usage = PROPERTY_USAGE_NO_EDITOR; |
2001 | } |
2002 | |
2003 | if (p_property.name == "msdf_outline_size" && !flags[FLAG_ALBEDO_TEXTURE_MSDF]) { |
2004 | p_property.usage = PROPERTY_USAGE_NO_EDITOR; |
2005 | } |
2006 | |
2007 | if ((p_property.name == "distance_fade_max_distance" || p_property.name == "distance_fade_min_distance" ) && distance_fade == DISTANCE_FADE_DISABLED) { |
2008 | p_property.usage = PROPERTY_USAGE_NO_EDITOR; |
2009 | } |
2010 | |
2011 | if ((p_property.name == "uv1_triplanar_sharpness" || p_property.name == "uv1_world_triplanar" ) && !flags[FLAG_UV1_USE_TRIPLANAR]) { |
2012 | p_property.usage = PROPERTY_USAGE_NO_EDITOR; |
2013 | } |
2014 | |
2015 | if ((p_property.name == "uv2_triplanar_sharpness" || p_property.name == "uv2_world_triplanar" ) && !flags[FLAG_UV2_USE_TRIPLANAR]) { |
2016 | p_property.usage = PROPERTY_USAGE_NO_EDITOR; |
2017 | } |
2018 | |
2019 | // you can only enable anti-aliasing (in materials) on alpha scissor and alpha hash |
2020 | const bool can_select_aa = (transparency == TRANSPARENCY_ALPHA_SCISSOR || transparency == TRANSPARENCY_ALPHA_HASH); |
2021 | // alpha anti aliasiasing is only enabled when you can select aa |
2022 | const bool alpha_aa_enabled = (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF) && can_select_aa; |
2023 | |
2024 | // alpha scissor slider isn't needed when alpha antialiasing is enabled |
2025 | if (p_property.name == "alpha_scissor_threshold" && transparency != TRANSPARENCY_ALPHA_SCISSOR) { |
2026 | p_property.usage = PROPERTY_USAGE_NONE; |
2027 | } |
2028 | |
2029 | // alpha hash scale slider is only needed if transparency is alpha hash |
2030 | if (p_property.name == "alpha_hash_scale" && transparency != TRANSPARENCY_ALPHA_HASH) { |
2031 | p_property.usage = PROPERTY_USAGE_NONE; |
2032 | } |
2033 | |
2034 | if (p_property.name == "alpha_antialiasing_mode" && !can_select_aa) { |
2035 | p_property.usage = PROPERTY_USAGE_NONE; |
2036 | } |
2037 | |
2038 | // we can't choose an antialiasing mode if alpha isn't possible |
2039 | if (p_property.name == "alpha_antialiasing_edge" && !alpha_aa_enabled) { |
2040 | p_property.usage = PROPERTY_USAGE_NONE; |
2041 | } |
2042 | |
2043 | if (p_property.name == "blend_mode" && alpha_aa_enabled) { |
2044 | p_property.usage = PROPERTY_USAGE_NONE; |
2045 | } |
2046 | |
2047 | if ((p_property.name == "heightmap_min_layers" || p_property.name == "heightmap_max_layers" ) && !deep_parallax) { |
2048 | p_property.usage = PROPERTY_USAGE_NONE; |
2049 | } |
2050 | |
2051 | if (flags[FLAG_SUBSURFACE_MODE_SKIN] && (p_property.name == "subsurf_scatter_transmittance_color" || p_property.name == "subsurf_scatter_transmittance_texture" )) { |
2052 | p_property.usage = PROPERTY_USAGE_NONE; |
2053 | } |
2054 | |
2055 | if (orm) { |
2056 | if (p_property.name == "shading_mode" ) { |
2057 | // Vertex not supported in ORM mode, since no individual roughness. |
2058 | p_property.hint_string = "Unshaded,Per-Pixel" ; |
2059 | } |
2060 | if (p_property.name.begins_with("roughness" ) || p_property.name.begins_with("metallic" ) || p_property.name.begins_with("ao_texture" )) { |
2061 | p_property.usage = PROPERTY_USAGE_NONE; |
2062 | } |
2063 | |
2064 | } else { |
2065 | if (p_property.name == "orm_texture" ) { |
2066 | p_property.usage = PROPERTY_USAGE_NONE; |
2067 | } |
2068 | } |
2069 | |
2070 | if (shading_mode != SHADING_MODE_PER_PIXEL) { |
2071 | if (shading_mode != SHADING_MODE_PER_VERTEX) { |
2072 | //these may still work per vertex |
2073 | if (p_property.name.begins_with("ao" )) { |
2074 | p_property.usage = PROPERTY_USAGE_NONE; |
2075 | } |
2076 | if (p_property.name.begins_with("emission" )) { |
2077 | p_property.usage = PROPERTY_USAGE_NONE; |
2078 | } |
2079 | |
2080 | if (p_property.name.begins_with("metallic" )) { |
2081 | p_property.usage = PROPERTY_USAGE_NONE; |
2082 | } |
2083 | if (p_property.name.begins_with("rim" )) { |
2084 | p_property.usage = PROPERTY_USAGE_NONE; |
2085 | } |
2086 | |
2087 | if (p_property.name.begins_with("roughness" )) { |
2088 | p_property.usage = PROPERTY_USAGE_NONE; |
2089 | } |
2090 | |
2091 | if (p_property.name.begins_with("subsurf_scatter" )) { |
2092 | p_property.usage = PROPERTY_USAGE_NONE; |
2093 | } |
2094 | } |
2095 | |
2096 | //these definitely only need per pixel |
2097 | if (p_property.name.begins_with("anisotropy" )) { |
2098 | p_property.usage = PROPERTY_USAGE_NONE; |
2099 | } |
2100 | |
2101 | if (p_property.name.begins_with("clearcoat" )) { |
2102 | p_property.usage = PROPERTY_USAGE_NONE; |
2103 | } |
2104 | |
2105 | if (p_property.name.begins_with("normal" )) { |
2106 | p_property.usage = PROPERTY_USAGE_NONE; |
2107 | } |
2108 | |
2109 | if (p_property.name.begins_with("backlight" )) { |
2110 | p_property.usage = PROPERTY_USAGE_NONE; |
2111 | } |
2112 | |
2113 | if (p_property.name.begins_with("transmittance" )) { |
2114 | p_property.usage = PROPERTY_USAGE_NONE; |
2115 | } |
2116 | } |
2117 | } |
2118 | |
2119 | void BaseMaterial3D::set_point_size(float p_point_size) { |
2120 | point_size = p_point_size; |
2121 | RS::get_singleton()->material_set_param(_get_material(), shader_names->point_size, p_point_size); |
2122 | } |
2123 | |
2124 | float BaseMaterial3D::get_point_size() const { |
2125 | return point_size; |
2126 | } |
2127 | |
2128 | void BaseMaterial3D::set_uv1_scale(const Vector3 &p_scale) { |
2129 | uv1_scale = p_scale; |
2130 | RS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_scale, p_scale); |
2131 | } |
2132 | |
2133 | Vector3 BaseMaterial3D::get_uv1_scale() const { |
2134 | return uv1_scale; |
2135 | } |
2136 | |
2137 | void BaseMaterial3D::set_uv1_offset(const Vector3 &p_offset) { |
2138 | uv1_offset = p_offset; |
2139 | RS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_offset, p_offset); |
2140 | } |
2141 | |
2142 | Vector3 BaseMaterial3D::get_uv1_offset() const { |
2143 | return uv1_offset; |
2144 | } |
2145 | |
2146 | void BaseMaterial3D::set_uv1_triplanar_blend_sharpness(float p_sharpness) { |
2147 | // Negative values or values higher than 150 can result in NaNs, leading to broken rendering. |
2148 | uv1_triplanar_sharpness = CLAMP(p_sharpness, 0.0, 150.0); |
2149 | RS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_blend_sharpness, uv1_triplanar_sharpness); |
2150 | } |
2151 | |
2152 | float BaseMaterial3D::get_uv1_triplanar_blend_sharpness() const { |
2153 | return uv1_triplanar_sharpness; |
2154 | } |
2155 | |
2156 | void BaseMaterial3D::set_uv2_scale(const Vector3 &p_scale) { |
2157 | uv2_scale = p_scale; |
2158 | RS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_scale, p_scale); |
2159 | } |
2160 | |
2161 | Vector3 BaseMaterial3D::get_uv2_scale() const { |
2162 | return uv2_scale; |
2163 | } |
2164 | |
2165 | void BaseMaterial3D::set_uv2_offset(const Vector3 &p_offset) { |
2166 | uv2_offset = p_offset; |
2167 | RS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_offset, p_offset); |
2168 | } |
2169 | |
2170 | Vector3 BaseMaterial3D::get_uv2_offset() const { |
2171 | return uv2_offset; |
2172 | } |
2173 | |
2174 | void BaseMaterial3D::set_uv2_triplanar_blend_sharpness(float p_sharpness) { |
2175 | // Negative values or values higher than 150 can result in NaNs, leading to broken rendering. |
2176 | uv2_triplanar_sharpness = CLAMP(p_sharpness, 0.0, 150.0); |
2177 | RS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_blend_sharpness, uv2_triplanar_sharpness); |
2178 | } |
2179 | |
2180 | float BaseMaterial3D::get_uv2_triplanar_blend_sharpness() const { |
2181 | return uv2_triplanar_sharpness; |
2182 | } |
2183 | |
2184 | void BaseMaterial3D::set_billboard_mode(BillboardMode p_mode) { |
2185 | billboard_mode = p_mode; |
2186 | _queue_shader_change(); |
2187 | notify_property_list_changed(); |
2188 | } |
2189 | |
2190 | BaseMaterial3D::BillboardMode BaseMaterial3D::get_billboard_mode() const { |
2191 | return billboard_mode; |
2192 | } |
2193 | |
2194 | void BaseMaterial3D::set_particles_anim_h_frames(int p_frames) { |
2195 | particles_anim_h_frames = p_frames; |
2196 | RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_h_frames, p_frames); |
2197 | } |
2198 | |
2199 | int BaseMaterial3D::get_particles_anim_h_frames() const { |
2200 | return particles_anim_h_frames; |
2201 | } |
2202 | |
2203 | void BaseMaterial3D::set_particles_anim_v_frames(int p_frames) { |
2204 | particles_anim_v_frames = p_frames; |
2205 | RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_v_frames, p_frames); |
2206 | } |
2207 | |
2208 | int BaseMaterial3D::get_particles_anim_v_frames() const { |
2209 | return particles_anim_v_frames; |
2210 | } |
2211 | |
2212 | void BaseMaterial3D::set_particles_anim_loop(bool p_loop) { |
2213 | particles_anim_loop = p_loop; |
2214 | RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_loop, particles_anim_loop); |
2215 | } |
2216 | |
2217 | bool BaseMaterial3D::get_particles_anim_loop() const { |
2218 | return particles_anim_loop; |
2219 | } |
2220 | |
2221 | void BaseMaterial3D::set_heightmap_deep_parallax(bool p_enable) { |
2222 | deep_parallax = p_enable; |
2223 | _queue_shader_change(); |
2224 | notify_property_list_changed(); |
2225 | } |
2226 | |
2227 | bool BaseMaterial3D::is_heightmap_deep_parallax_enabled() const { |
2228 | return deep_parallax; |
2229 | } |
2230 | |
2231 | void BaseMaterial3D::set_heightmap_deep_parallax_min_layers(int p_layer) { |
2232 | deep_parallax_min_layers = p_layer; |
2233 | RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_min_layers, p_layer); |
2234 | } |
2235 | |
2236 | int BaseMaterial3D::get_heightmap_deep_parallax_min_layers() const { |
2237 | return deep_parallax_min_layers; |
2238 | } |
2239 | |
2240 | void BaseMaterial3D::set_heightmap_deep_parallax_max_layers(int p_layer) { |
2241 | deep_parallax_max_layers = p_layer; |
2242 | RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_max_layers, p_layer); |
2243 | } |
2244 | |
2245 | int BaseMaterial3D::get_heightmap_deep_parallax_max_layers() const { |
2246 | return deep_parallax_max_layers; |
2247 | } |
2248 | |
2249 | void BaseMaterial3D::set_heightmap_deep_parallax_flip_tangent(bool p_flip) { |
2250 | heightmap_parallax_flip_tangent = p_flip; |
2251 | RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_flip, Vector2(heightmap_parallax_flip_tangent ? -1 : 1, heightmap_parallax_flip_binormal ? -1 : 1)); |
2252 | } |
2253 | |
2254 | bool BaseMaterial3D::get_heightmap_deep_parallax_flip_tangent() const { |
2255 | return heightmap_parallax_flip_tangent; |
2256 | } |
2257 | |
2258 | void BaseMaterial3D::set_heightmap_deep_parallax_flip_binormal(bool p_flip) { |
2259 | heightmap_parallax_flip_binormal = p_flip; |
2260 | RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_flip, Vector2(heightmap_parallax_flip_tangent ? -1 : 1, heightmap_parallax_flip_binormal ? -1 : 1)); |
2261 | } |
2262 | |
2263 | bool BaseMaterial3D::get_heightmap_deep_parallax_flip_binormal() const { |
2264 | return heightmap_parallax_flip_binormal; |
2265 | } |
2266 | |
2267 | void BaseMaterial3D::set_grow_enabled(bool p_enable) { |
2268 | grow_enabled = p_enable; |
2269 | _queue_shader_change(); |
2270 | notify_property_list_changed(); |
2271 | } |
2272 | |
2273 | bool BaseMaterial3D::is_grow_enabled() const { |
2274 | return grow_enabled; |
2275 | } |
2276 | |
2277 | void BaseMaterial3D::set_alpha_scissor_threshold(float p_threshold) { |
2278 | alpha_scissor_threshold = p_threshold; |
2279 | RS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_scissor_threshold, p_threshold); |
2280 | } |
2281 | |
2282 | float BaseMaterial3D::get_alpha_scissor_threshold() const { |
2283 | return alpha_scissor_threshold; |
2284 | } |
2285 | |
2286 | void BaseMaterial3D::set_alpha_hash_scale(float p_scale) { |
2287 | alpha_hash_scale = p_scale; |
2288 | RS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_hash_scale, p_scale); |
2289 | } |
2290 | |
2291 | float BaseMaterial3D::get_alpha_hash_scale() const { |
2292 | return alpha_hash_scale; |
2293 | } |
2294 | |
2295 | void BaseMaterial3D::set_alpha_antialiasing_edge(float p_edge) { |
2296 | alpha_antialiasing_edge = p_edge; |
2297 | RS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_antialiasing_edge, p_edge); |
2298 | } |
2299 | |
2300 | float BaseMaterial3D::get_alpha_antialiasing_edge() const { |
2301 | return alpha_antialiasing_edge; |
2302 | } |
2303 | |
2304 | void BaseMaterial3D::set_grow(float p_grow) { |
2305 | grow = p_grow; |
2306 | RS::get_singleton()->material_set_param(_get_material(), shader_names->grow, p_grow); |
2307 | } |
2308 | |
2309 | float BaseMaterial3D::get_grow() const { |
2310 | return grow; |
2311 | } |
2312 | |
2313 | static Plane _get_texture_mask(BaseMaterial3D::TextureChannel p_channel) { |
2314 | static const Plane masks[5] = { |
2315 | Plane(1, 0, 0, 0), |
2316 | Plane(0, 1, 0, 0), |
2317 | Plane(0, 0, 1, 0), |
2318 | Plane(0, 0, 0, 1), |
2319 | Plane(0.3333333, 0.3333333, 0.3333333, 0), |
2320 | }; |
2321 | |
2322 | return masks[p_channel]; |
2323 | } |
2324 | |
2325 | void BaseMaterial3D::set_metallic_texture_channel(TextureChannel p_channel) { |
2326 | ERR_FAIL_INDEX(p_channel, 5); |
2327 | metallic_texture_channel = p_channel; |
2328 | RS::get_singleton()->material_set_param(_get_material(), shader_names->metallic_texture_channel, _get_texture_mask(p_channel)); |
2329 | } |
2330 | |
2331 | BaseMaterial3D::TextureChannel BaseMaterial3D::get_metallic_texture_channel() const { |
2332 | return metallic_texture_channel; |
2333 | } |
2334 | |
2335 | void BaseMaterial3D::set_roughness_texture_channel(TextureChannel p_channel) { |
2336 | ERR_FAIL_INDEX(p_channel, 5); |
2337 | roughness_texture_channel = p_channel; |
2338 | _queue_shader_change(); |
2339 | } |
2340 | |
2341 | BaseMaterial3D::TextureChannel BaseMaterial3D::get_roughness_texture_channel() const { |
2342 | return roughness_texture_channel; |
2343 | } |
2344 | |
2345 | void BaseMaterial3D::set_ao_texture_channel(TextureChannel p_channel) { |
2346 | ERR_FAIL_INDEX(p_channel, 5); |
2347 | ao_texture_channel = p_channel; |
2348 | RS::get_singleton()->material_set_param(_get_material(), shader_names->ao_texture_channel, _get_texture_mask(p_channel)); |
2349 | } |
2350 | |
2351 | BaseMaterial3D::TextureChannel BaseMaterial3D::get_ao_texture_channel() const { |
2352 | return ao_texture_channel; |
2353 | } |
2354 | |
2355 | void BaseMaterial3D::set_refraction_texture_channel(TextureChannel p_channel) { |
2356 | ERR_FAIL_INDEX(p_channel, 5); |
2357 | refraction_texture_channel = p_channel; |
2358 | RS::get_singleton()->material_set_param(_get_material(), shader_names->refraction_texture_channel, _get_texture_mask(p_channel)); |
2359 | } |
2360 | |
2361 | BaseMaterial3D::TextureChannel BaseMaterial3D::get_refraction_texture_channel() const { |
2362 | return refraction_texture_channel; |
2363 | } |
2364 | |
2365 | Ref<Material> BaseMaterial3D::get_material_for_2d(bool p_shaded, Transparency p_transparency, bool p_double_sided, bool p_billboard, bool p_billboard_y, bool p_msdf, bool p_no_depth, bool p_fixed_size, TextureFilter p_filter, AlphaAntiAliasing p_alpha_antialiasing_mode, RID *r_shader_rid) { |
2366 | uint64_t key = 0; |
2367 | key |= ((int8_t)p_shaded & 0x01) << 0; |
2368 | key |= ((int8_t)p_transparency & 0x07) << 1; // Bits 1-3. |
2369 | key |= ((int8_t)p_double_sided & 0x01) << 4; |
2370 | key |= ((int8_t)p_billboard & 0x01) << 5; |
2371 | key |= ((int8_t)p_billboard_y & 0x01) << 6; |
2372 | key |= ((int8_t)p_msdf & 0x01) << 7; |
2373 | key |= ((int8_t)p_no_depth & 0x01) << 8; |
2374 | key |= ((int8_t)p_fixed_size & 0x01) << 9; |
2375 | key |= ((int8_t)p_filter & 0x07) << 10; // Bits 10-12. |
2376 | key |= ((int8_t)p_alpha_antialiasing_mode & 0x07) << 13; // Bits 13-15. |
2377 | |
2378 | if (materials_for_2d.has(key)) { |
2379 | if (r_shader_rid) { |
2380 | *r_shader_rid = materials_for_2d[key]->get_shader_rid(); |
2381 | } |
2382 | return materials_for_2d[key]; |
2383 | } |
2384 | |
2385 | Ref<StandardMaterial3D> material; |
2386 | material.instantiate(); |
2387 | |
2388 | material->set_shading_mode(p_shaded ? SHADING_MODE_PER_PIXEL : SHADING_MODE_UNSHADED); |
2389 | material->set_transparency(p_transparency); |
2390 | material->set_cull_mode(p_double_sided ? CULL_DISABLED : CULL_BACK); |
2391 | material->set_flag(FLAG_SRGB_VERTEX_COLOR, true); |
2392 | material->set_flag(FLAG_ALBEDO_FROM_VERTEX_COLOR, true); |
2393 | material->set_flag(FLAG_ALBEDO_TEXTURE_MSDF, p_msdf); |
2394 | material->set_flag(FLAG_DISABLE_DEPTH_TEST, p_no_depth); |
2395 | material->set_flag(FLAG_FIXED_SIZE, p_fixed_size); |
2396 | material->set_alpha_antialiasing(p_alpha_antialiasing_mode); |
2397 | material->set_texture_filter(p_filter); |
2398 | if (p_billboard || p_billboard_y) { |
2399 | material->set_flag(FLAG_BILLBOARD_KEEP_SCALE, true); |
2400 | material->set_billboard_mode(p_billboard_y ? BILLBOARD_FIXED_Y : BILLBOARD_ENABLED); |
2401 | } |
2402 | |
2403 | materials_for_2d[key] = material; |
2404 | |
2405 | if (r_shader_rid) { |
2406 | *r_shader_rid = materials_for_2d[key]->get_shader_rid(); |
2407 | } |
2408 | |
2409 | return materials_for_2d[key]; |
2410 | } |
2411 | |
2412 | void BaseMaterial3D::set_on_top_of_alpha() { |
2413 | set_transparency(TRANSPARENCY_DISABLED); |
2414 | set_render_priority(RENDER_PRIORITY_MAX); |
2415 | set_flag(FLAG_DISABLE_DEPTH_TEST, true); |
2416 | } |
2417 | |
2418 | void BaseMaterial3D::set_proximity_fade_enabled(bool p_enable) { |
2419 | proximity_fade_enabled = p_enable; |
2420 | _queue_shader_change(); |
2421 | notify_property_list_changed(); |
2422 | } |
2423 | |
2424 | bool BaseMaterial3D::is_proximity_fade_enabled() const { |
2425 | return proximity_fade_enabled; |
2426 | } |
2427 | |
2428 | void BaseMaterial3D::set_proximity_fade_distance(float p_distance) { |
2429 | proximity_fade_distance = p_distance; |
2430 | RS::get_singleton()->material_set_param(_get_material(), shader_names->proximity_fade_distance, p_distance); |
2431 | } |
2432 | |
2433 | float BaseMaterial3D::get_proximity_fade_distance() const { |
2434 | return proximity_fade_distance; |
2435 | } |
2436 | |
2437 | void BaseMaterial3D::set_msdf_pixel_range(float p_range) { |
2438 | msdf_pixel_range = p_range; |
2439 | RS::get_singleton()->material_set_param(_get_material(), shader_names->msdf_pixel_range, p_range); |
2440 | } |
2441 | |
2442 | float BaseMaterial3D::get_msdf_pixel_range() const { |
2443 | return msdf_pixel_range; |
2444 | } |
2445 | |
2446 | void BaseMaterial3D::set_msdf_outline_size(float p_size) { |
2447 | msdf_outline_size = p_size; |
2448 | RS::get_singleton()->material_set_param(_get_material(), shader_names->msdf_outline_size, p_size); |
2449 | } |
2450 | |
2451 | float BaseMaterial3D::get_msdf_outline_size() const { |
2452 | return msdf_outline_size; |
2453 | } |
2454 | |
2455 | void BaseMaterial3D::set_distance_fade(DistanceFadeMode p_mode) { |
2456 | distance_fade = p_mode; |
2457 | _queue_shader_change(); |
2458 | notify_property_list_changed(); |
2459 | } |
2460 | |
2461 | BaseMaterial3D::DistanceFadeMode BaseMaterial3D::get_distance_fade() const { |
2462 | return distance_fade; |
2463 | } |
2464 | |
2465 | void BaseMaterial3D::set_distance_fade_max_distance(float p_distance) { |
2466 | distance_fade_max_distance = p_distance; |
2467 | RS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_max, distance_fade_max_distance); |
2468 | } |
2469 | |
2470 | float BaseMaterial3D::get_distance_fade_max_distance() const { |
2471 | return distance_fade_max_distance; |
2472 | } |
2473 | |
2474 | void BaseMaterial3D::set_distance_fade_min_distance(float p_distance) { |
2475 | distance_fade_min_distance = p_distance; |
2476 | RS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_min, distance_fade_min_distance); |
2477 | } |
2478 | |
2479 | float BaseMaterial3D::get_distance_fade_min_distance() const { |
2480 | return distance_fade_min_distance; |
2481 | } |
2482 | |
2483 | void BaseMaterial3D::set_emission_operator(EmissionOperator p_op) { |
2484 | if (emission_op == p_op) { |
2485 | return; |
2486 | } |
2487 | emission_op = p_op; |
2488 | _queue_shader_change(); |
2489 | } |
2490 | |
2491 | BaseMaterial3D::EmissionOperator BaseMaterial3D::get_emission_operator() const { |
2492 | return emission_op; |
2493 | } |
2494 | |
2495 | RID BaseMaterial3D::get_shader_rid() const { |
2496 | MutexLock lock(material_mutex); |
2497 | if (element.in_list()) { // _is_shader_dirty() would create anoder mutex lock |
2498 | ((BaseMaterial3D *)this)->_update_shader(); |
2499 | } |
2500 | ERR_FAIL_COND_V(!shader_map.has(current_key), RID()); |
2501 | return shader_map[current_key].shader; |
2502 | } |
2503 | |
2504 | Shader::Mode BaseMaterial3D::get_shader_mode() const { |
2505 | return Shader::MODE_SPATIAL; |
2506 | } |
2507 | |
2508 | void BaseMaterial3D::_bind_methods() { |
2509 | static_assert(sizeof(MaterialKey) == 16, "MaterialKey should be 16 bytes" ); |
2510 | |
2511 | ClassDB::bind_method(D_METHOD("set_albedo" , "albedo" ), &BaseMaterial3D::set_albedo); |
2512 | ClassDB::bind_method(D_METHOD("get_albedo" ), &BaseMaterial3D::get_albedo); |
2513 | |
2514 | ClassDB::bind_method(D_METHOD("set_transparency" , "transparency" ), &BaseMaterial3D::set_transparency); |
2515 | ClassDB::bind_method(D_METHOD("get_transparency" ), &BaseMaterial3D::get_transparency); |
2516 | |
2517 | ClassDB::bind_method(D_METHOD("set_alpha_antialiasing" , "alpha_aa" ), &BaseMaterial3D::set_alpha_antialiasing); |
2518 | ClassDB::bind_method(D_METHOD("get_alpha_antialiasing" ), &BaseMaterial3D::get_alpha_antialiasing); |
2519 | |
2520 | ClassDB::bind_method(D_METHOD("set_alpha_antialiasing_edge" , "edge" ), &BaseMaterial3D::set_alpha_antialiasing_edge); |
2521 | ClassDB::bind_method(D_METHOD("get_alpha_antialiasing_edge" ), &BaseMaterial3D::get_alpha_antialiasing_edge); |
2522 | |
2523 | ClassDB::bind_method(D_METHOD("set_shading_mode" , "shading_mode" ), &BaseMaterial3D::set_shading_mode); |
2524 | ClassDB::bind_method(D_METHOD("get_shading_mode" ), &BaseMaterial3D::get_shading_mode); |
2525 | |
2526 | ClassDB::bind_method(D_METHOD("set_specular" , "specular" ), &BaseMaterial3D::set_specular); |
2527 | ClassDB::bind_method(D_METHOD("get_specular" ), &BaseMaterial3D::get_specular); |
2528 | |
2529 | ClassDB::bind_method(D_METHOD("set_metallic" , "metallic" ), &BaseMaterial3D::set_metallic); |
2530 | ClassDB::bind_method(D_METHOD("get_metallic" ), &BaseMaterial3D::get_metallic); |
2531 | |
2532 | ClassDB::bind_method(D_METHOD("set_roughness" , "roughness" ), &BaseMaterial3D::set_roughness); |
2533 | ClassDB::bind_method(D_METHOD("get_roughness" ), &BaseMaterial3D::get_roughness); |
2534 | |
2535 | ClassDB::bind_method(D_METHOD("set_emission" , "emission" ), &BaseMaterial3D::set_emission); |
2536 | ClassDB::bind_method(D_METHOD("get_emission" ), &BaseMaterial3D::get_emission); |
2537 | |
2538 | ClassDB::bind_method(D_METHOD("set_emission_energy_multiplier" , "emission_energy_multiplier" ), &BaseMaterial3D::set_emission_energy_multiplier); |
2539 | ClassDB::bind_method(D_METHOD("get_emission_energy_multiplier" ), &BaseMaterial3D::get_emission_energy_multiplier); |
2540 | |
2541 | ClassDB::bind_method(D_METHOD("set_emission_intensity" , "emission_energy_multiplier" ), &BaseMaterial3D::set_emission_intensity); |
2542 | ClassDB::bind_method(D_METHOD("get_emission_intensity" ), &BaseMaterial3D::get_emission_intensity); |
2543 | |
2544 | ClassDB::bind_method(D_METHOD("set_normal_scale" , "normal_scale" ), &BaseMaterial3D::set_normal_scale); |
2545 | ClassDB::bind_method(D_METHOD("get_normal_scale" ), &BaseMaterial3D::get_normal_scale); |
2546 | |
2547 | ClassDB::bind_method(D_METHOD("set_rim" , "rim" ), &BaseMaterial3D::set_rim); |
2548 | ClassDB::bind_method(D_METHOD("get_rim" ), &BaseMaterial3D::get_rim); |
2549 | |
2550 | ClassDB::bind_method(D_METHOD("set_rim_tint" , "rim_tint" ), &BaseMaterial3D::set_rim_tint); |
2551 | ClassDB::bind_method(D_METHOD("get_rim_tint" ), &BaseMaterial3D::get_rim_tint); |
2552 | |
2553 | ClassDB::bind_method(D_METHOD("set_clearcoat" , "clearcoat" ), &BaseMaterial3D::set_clearcoat); |
2554 | ClassDB::bind_method(D_METHOD("get_clearcoat" ), &BaseMaterial3D::get_clearcoat); |
2555 | |
2556 | ClassDB::bind_method(D_METHOD("set_clearcoat_roughness" , "clearcoat_roughness" ), &BaseMaterial3D::set_clearcoat_roughness); |
2557 | ClassDB::bind_method(D_METHOD("get_clearcoat_roughness" ), &BaseMaterial3D::get_clearcoat_roughness); |
2558 | |
2559 | ClassDB::bind_method(D_METHOD("set_anisotropy" , "anisotropy" ), &BaseMaterial3D::set_anisotropy); |
2560 | ClassDB::bind_method(D_METHOD("get_anisotropy" ), &BaseMaterial3D::get_anisotropy); |
2561 | |
2562 | ClassDB::bind_method(D_METHOD("set_heightmap_scale" , "heightmap_scale" ), &BaseMaterial3D::set_heightmap_scale); |
2563 | ClassDB::bind_method(D_METHOD("get_heightmap_scale" ), &BaseMaterial3D::get_heightmap_scale); |
2564 | |
2565 | ClassDB::bind_method(D_METHOD("set_subsurface_scattering_strength" , "strength" ), &BaseMaterial3D::set_subsurface_scattering_strength); |
2566 | ClassDB::bind_method(D_METHOD("get_subsurface_scattering_strength" ), &BaseMaterial3D::get_subsurface_scattering_strength); |
2567 | |
2568 | ClassDB::bind_method(D_METHOD("set_transmittance_color" , "color" ), &BaseMaterial3D::set_transmittance_color); |
2569 | ClassDB::bind_method(D_METHOD("get_transmittance_color" ), &BaseMaterial3D::get_transmittance_color); |
2570 | |
2571 | ClassDB::bind_method(D_METHOD("set_transmittance_depth" , "depth" ), &BaseMaterial3D::set_transmittance_depth); |
2572 | ClassDB::bind_method(D_METHOD("get_transmittance_depth" ), &BaseMaterial3D::get_transmittance_depth); |
2573 | |
2574 | ClassDB::bind_method(D_METHOD("set_transmittance_boost" , "boost" ), &BaseMaterial3D::set_transmittance_boost); |
2575 | ClassDB::bind_method(D_METHOD("get_transmittance_boost" ), &BaseMaterial3D::get_transmittance_boost); |
2576 | |
2577 | ClassDB::bind_method(D_METHOD("set_backlight" , "backlight" ), &BaseMaterial3D::set_backlight); |
2578 | ClassDB::bind_method(D_METHOD("get_backlight" ), &BaseMaterial3D::get_backlight); |
2579 | |
2580 | ClassDB::bind_method(D_METHOD("set_refraction" , "refraction" ), &BaseMaterial3D::set_refraction); |
2581 | ClassDB::bind_method(D_METHOD("get_refraction" ), &BaseMaterial3D::get_refraction); |
2582 | |
2583 | ClassDB::bind_method(D_METHOD("set_point_size" , "point_size" ), &BaseMaterial3D::set_point_size); |
2584 | ClassDB::bind_method(D_METHOD("get_point_size" ), &BaseMaterial3D::get_point_size); |
2585 | |
2586 | ClassDB::bind_method(D_METHOD("set_detail_uv" , "detail_uv" ), &BaseMaterial3D::set_detail_uv); |
2587 | ClassDB::bind_method(D_METHOD("get_detail_uv" ), &BaseMaterial3D::get_detail_uv); |
2588 | |
2589 | ClassDB::bind_method(D_METHOD("set_blend_mode" , "blend_mode" ), &BaseMaterial3D::set_blend_mode); |
2590 | ClassDB::bind_method(D_METHOD("get_blend_mode" ), &BaseMaterial3D::get_blend_mode); |
2591 | |
2592 | ClassDB::bind_method(D_METHOD("set_depth_draw_mode" , "depth_draw_mode" ), &BaseMaterial3D::set_depth_draw_mode); |
2593 | ClassDB::bind_method(D_METHOD("get_depth_draw_mode" ), &BaseMaterial3D::get_depth_draw_mode); |
2594 | |
2595 | ClassDB::bind_method(D_METHOD("set_cull_mode" , "cull_mode" ), &BaseMaterial3D::set_cull_mode); |
2596 | ClassDB::bind_method(D_METHOD("get_cull_mode" ), &BaseMaterial3D::get_cull_mode); |
2597 | |
2598 | ClassDB::bind_method(D_METHOD("set_diffuse_mode" , "diffuse_mode" ), &BaseMaterial3D::set_diffuse_mode); |
2599 | ClassDB::bind_method(D_METHOD("get_diffuse_mode" ), &BaseMaterial3D::get_diffuse_mode); |
2600 | |
2601 | ClassDB::bind_method(D_METHOD("set_specular_mode" , "specular_mode" ), &BaseMaterial3D::set_specular_mode); |
2602 | ClassDB::bind_method(D_METHOD("get_specular_mode" ), &BaseMaterial3D::get_specular_mode); |
2603 | |
2604 | ClassDB::bind_method(D_METHOD("set_flag" , "flag" , "enable" ), &BaseMaterial3D::set_flag); |
2605 | ClassDB::bind_method(D_METHOD("get_flag" , "flag" ), &BaseMaterial3D::get_flag); |
2606 | |
2607 | ClassDB::bind_method(D_METHOD("set_texture_filter" , "mode" ), &BaseMaterial3D::set_texture_filter); |
2608 | ClassDB::bind_method(D_METHOD("get_texture_filter" ), &BaseMaterial3D::get_texture_filter); |
2609 | |
2610 | ClassDB::bind_method(D_METHOD("set_feature" , "feature" , "enable" ), &BaseMaterial3D::set_feature); |
2611 | ClassDB::bind_method(D_METHOD("get_feature" , "feature" ), &BaseMaterial3D::get_feature); |
2612 | |
2613 | ClassDB::bind_method(D_METHOD("set_texture" , "param" , "texture" ), &BaseMaterial3D::set_texture); |
2614 | ClassDB::bind_method(D_METHOD("get_texture" , "param" ), &BaseMaterial3D::get_texture); |
2615 | |
2616 | ClassDB::bind_method(D_METHOD("set_detail_blend_mode" , "detail_blend_mode" ), &BaseMaterial3D::set_detail_blend_mode); |
2617 | ClassDB::bind_method(D_METHOD("get_detail_blend_mode" ), &BaseMaterial3D::get_detail_blend_mode); |
2618 | |
2619 | ClassDB::bind_method(D_METHOD("set_uv1_scale" , "scale" ), &BaseMaterial3D::set_uv1_scale); |
2620 | ClassDB::bind_method(D_METHOD("get_uv1_scale" ), &BaseMaterial3D::get_uv1_scale); |
2621 | |
2622 | ClassDB::bind_method(D_METHOD("set_uv1_offset" , "offset" ), &BaseMaterial3D::set_uv1_offset); |
2623 | ClassDB::bind_method(D_METHOD("get_uv1_offset" ), &BaseMaterial3D::get_uv1_offset); |
2624 | |
2625 | ClassDB::bind_method(D_METHOD("set_uv1_triplanar_blend_sharpness" , "sharpness" ), &BaseMaterial3D::set_uv1_triplanar_blend_sharpness); |
2626 | ClassDB::bind_method(D_METHOD("get_uv1_triplanar_blend_sharpness" ), &BaseMaterial3D::get_uv1_triplanar_blend_sharpness); |
2627 | |
2628 | ClassDB::bind_method(D_METHOD("set_uv2_scale" , "scale" ), &BaseMaterial3D::set_uv2_scale); |
2629 | ClassDB::bind_method(D_METHOD("get_uv2_scale" ), &BaseMaterial3D::get_uv2_scale); |
2630 | |
2631 | ClassDB::bind_method(D_METHOD("set_uv2_offset" , "offset" ), &BaseMaterial3D::set_uv2_offset); |
2632 | ClassDB::bind_method(D_METHOD("get_uv2_offset" ), &BaseMaterial3D::get_uv2_offset); |
2633 | |
2634 | ClassDB::bind_method(D_METHOD("set_uv2_triplanar_blend_sharpness" , "sharpness" ), &BaseMaterial3D::set_uv2_triplanar_blend_sharpness); |
2635 | ClassDB::bind_method(D_METHOD("get_uv2_triplanar_blend_sharpness" ), &BaseMaterial3D::get_uv2_triplanar_blend_sharpness); |
2636 | |
2637 | ClassDB::bind_method(D_METHOD("set_billboard_mode" , "mode" ), &BaseMaterial3D::set_billboard_mode); |
2638 | ClassDB::bind_method(D_METHOD("get_billboard_mode" ), &BaseMaterial3D::get_billboard_mode); |
2639 | |
2640 | ClassDB::bind_method(D_METHOD("set_particles_anim_h_frames" , "frames" ), &BaseMaterial3D::set_particles_anim_h_frames); |
2641 | ClassDB::bind_method(D_METHOD("get_particles_anim_h_frames" ), &BaseMaterial3D::get_particles_anim_h_frames); |
2642 | |
2643 | ClassDB::bind_method(D_METHOD("set_particles_anim_v_frames" , "frames" ), &BaseMaterial3D::set_particles_anim_v_frames); |
2644 | ClassDB::bind_method(D_METHOD("get_particles_anim_v_frames" ), &BaseMaterial3D::get_particles_anim_v_frames); |
2645 | |
2646 | ClassDB::bind_method(D_METHOD("set_particles_anim_loop" , "loop" ), &BaseMaterial3D::set_particles_anim_loop); |
2647 | ClassDB::bind_method(D_METHOD("get_particles_anim_loop" ), &BaseMaterial3D::get_particles_anim_loop); |
2648 | |
2649 | ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax" , "enable" ), &BaseMaterial3D::set_heightmap_deep_parallax); |
2650 | ClassDB::bind_method(D_METHOD("is_heightmap_deep_parallax_enabled" ), &BaseMaterial3D::is_heightmap_deep_parallax_enabled); |
2651 | |
2652 | ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax_min_layers" , "layer" ), &BaseMaterial3D::set_heightmap_deep_parallax_min_layers); |
2653 | ClassDB::bind_method(D_METHOD("get_heightmap_deep_parallax_min_layers" ), &BaseMaterial3D::get_heightmap_deep_parallax_min_layers); |
2654 | |
2655 | ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax_max_layers" , "layer" ), &BaseMaterial3D::set_heightmap_deep_parallax_max_layers); |
2656 | ClassDB::bind_method(D_METHOD("get_heightmap_deep_parallax_max_layers" ), &BaseMaterial3D::get_heightmap_deep_parallax_max_layers); |
2657 | |
2658 | ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax_flip_tangent" , "flip" ), &BaseMaterial3D::set_heightmap_deep_parallax_flip_tangent); |
2659 | ClassDB::bind_method(D_METHOD("get_heightmap_deep_parallax_flip_tangent" ), &BaseMaterial3D::get_heightmap_deep_parallax_flip_tangent); |
2660 | |
2661 | ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax_flip_binormal" , "flip" ), &BaseMaterial3D::set_heightmap_deep_parallax_flip_binormal); |
2662 | ClassDB::bind_method(D_METHOD("get_heightmap_deep_parallax_flip_binormal" ), &BaseMaterial3D::get_heightmap_deep_parallax_flip_binormal); |
2663 | |
2664 | ClassDB::bind_method(D_METHOD("set_grow" , "amount" ), &BaseMaterial3D::set_grow); |
2665 | ClassDB::bind_method(D_METHOD("get_grow" ), &BaseMaterial3D::get_grow); |
2666 | |
2667 | ClassDB::bind_method(D_METHOD("set_emission_operator" , "operator" ), &BaseMaterial3D::set_emission_operator); |
2668 | ClassDB::bind_method(D_METHOD("get_emission_operator" ), &BaseMaterial3D::get_emission_operator); |
2669 | |
2670 | ClassDB::bind_method(D_METHOD("set_ao_light_affect" , "amount" ), &BaseMaterial3D::set_ao_light_affect); |
2671 | ClassDB::bind_method(D_METHOD("get_ao_light_affect" ), &BaseMaterial3D::get_ao_light_affect); |
2672 | |
2673 | ClassDB::bind_method(D_METHOD("set_alpha_scissor_threshold" , "threshold" ), &BaseMaterial3D::set_alpha_scissor_threshold); |
2674 | ClassDB::bind_method(D_METHOD("get_alpha_scissor_threshold" ), &BaseMaterial3D::get_alpha_scissor_threshold); |
2675 | |
2676 | ClassDB::bind_method(D_METHOD("set_alpha_hash_scale" , "threshold" ), &BaseMaterial3D::set_alpha_hash_scale); |
2677 | ClassDB::bind_method(D_METHOD("get_alpha_hash_scale" ), &BaseMaterial3D::get_alpha_hash_scale); |
2678 | |
2679 | ClassDB::bind_method(D_METHOD("set_grow_enabled" , "enable" ), &BaseMaterial3D::set_grow_enabled); |
2680 | ClassDB::bind_method(D_METHOD("is_grow_enabled" ), &BaseMaterial3D::is_grow_enabled); |
2681 | |
2682 | ClassDB::bind_method(D_METHOD("set_metallic_texture_channel" , "channel" ), &BaseMaterial3D::set_metallic_texture_channel); |
2683 | ClassDB::bind_method(D_METHOD("get_metallic_texture_channel" ), &BaseMaterial3D::get_metallic_texture_channel); |
2684 | |
2685 | ClassDB::bind_method(D_METHOD("set_roughness_texture_channel" , "channel" ), &BaseMaterial3D::set_roughness_texture_channel); |
2686 | ClassDB::bind_method(D_METHOD("get_roughness_texture_channel" ), &BaseMaterial3D::get_roughness_texture_channel); |
2687 | |
2688 | ClassDB::bind_method(D_METHOD("set_ao_texture_channel" , "channel" ), &BaseMaterial3D::set_ao_texture_channel); |
2689 | ClassDB::bind_method(D_METHOD("get_ao_texture_channel" ), &BaseMaterial3D::get_ao_texture_channel); |
2690 | |
2691 | ClassDB::bind_method(D_METHOD("set_refraction_texture_channel" , "channel" ), &BaseMaterial3D::set_refraction_texture_channel); |
2692 | ClassDB::bind_method(D_METHOD("get_refraction_texture_channel" ), &BaseMaterial3D::get_refraction_texture_channel); |
2693 | |
2694 | ClassDB::bind_method(D_METHOD("set_proximity_fade_enabled" , "enabled" ), &BaseMaterial3D::set_proximity_fade_enabled); |
2695 | ClassDB::bind_method(D_METHOD("is_proximity_fade_enabled" ), &BaseMaterial3D::is_proximity_fade_enabled); |
2696 | |
2697 | ClassDB::bind_method(D_METHOD("set_proximity_fade_distance" , "distance" ), &BaseMaterial3D::set_proximity_fade_distance); |
2698 | ClassDB::bind_method(D_METHOD("get_proximity_fade_distance" ), &BaseMaterial3D::get_proximity_fade_distance); |
2699 | |
2700 | ClassDB::bind_method(D_METHOD("set_msdf_pixel_range" , "range" ), &BaseMaterial3D::set_msdf_pixel_range); |
2701 | ClassDB::bind_method(D_METHOD("get_msdf_pixel_range" ), &BaseMaterial3D::get_msdf_pixel_range); |
2702 | |
2703 | ClassDB::bind_method(D_METHOD("set_msdf_outline_size" , "size" ), &BaseMaterial3D::set_msdf_outline_size); |
2704 | ClassDB::bind_method(D_METHOD("get_msdf_outline_size" ), &BaseMaterial3D::get_msdf_outline_size); |
2705 | |
2706 | ClassDB::bind_method(D_METHOD("set_distance_fade" , "mode" ), &BaseMaterial3D::set_distance_fade); |
2707 | ClassDB::bind_method(D_METHOD("get_distance_fade" ), &BaseMaterial3D::get_distance_fade); |
2708 | |
2709 | ClassDB::bind_method(D_METHOD("set_distance_fade_max_distance" , "distance" ), &BaseMaterial3D::set_distance_fade_max_distance); |
2710 | ClassDB::bind_method(D_METHOD("get_distance_fade_max_distance" ), &BaseMaterial3D::get_distance_fade_max_distance); |
2711 | |
2712 | ClassDB::bind_method(D_METHOD("set_distance_fade_min_distance" , "distance" ), &BaseMaterial3D::set_distance_fade_min_distance); |
2713 | ClassDB::bind_method(D_METHOD("get_distance_fade_min_distance" ), &BaseMaterial3D::get_distance_fade_min_distance); |
2714 | |
2715 | ADD_GROUP("Transparency" , "" ); |
2716 | ADD_PROPERTY(PropertyInfo(Variant::INT, "transparency" , PROPERTY_HINT_ENUM, "Disabled,Alpha,Alpha Scissor,Alpha Hash,Depth Pre-Pass" ), "set_transparency" , "get_transparency" ); |
2717 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold" , PROPERTY_HINT_RANGE, "0,1,0.001" ), "set_alpha_scissor_threshold" , "get_alpha_scissor_threshold" ); |
2718 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_hash_scale" , PROPERTY_HINT_RANGE, "0,2,0.01" ), "set_alpha_hash_scale" , "get_alpha_hash_scale" ); |
2719 | ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_antialiasing_mode" , PROPERTY_HINT_ENUM, "Disabled,Alpha Edge Blend,Alpha Edge Clip" ), "set_alpha_antialiasing" , "get_alpha_antialiasing" ); |
2720 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_antialiasing_edge" , PROPERTY_HINT_RANGE, "0,1,0.01" ), "set_alpha_antialiasing_edge" , "get_alpha_antialiasing_edge" ); |
2721 | ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode" , PROPERTY_HINT_ENUM, "Mix,Add,Subtract,Multiply" ), "set_blend_mode" , "get_blend_mode" ); |
2722 | ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mode" , PROPERTY_HINT_ENUM, "Back,Front,Disabled" ), "set_cull_mode" , "get_cull_mode" ); |
2723 | ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_draw_mode" , PROPERTY_HINT_ENUM, "Opaque Only,Always,Never" ), "set_depth_draw_mode" , "get_depth_draw_mode" ); |
2724 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "no_depth_test" ), "set_flag" , "get_flag" , FLAG_DISABLE_DEPTH_TEST); |
2725 | |
2726 | ADD_GROUP("Shading" , "" ); |
2727 | ADD_PROPERTY(PropertyInfo(Variant::INT, "shading_mode" , PROPERTY_HINT_ENUM, "Unshaded,Per-Pixel,Per-Vertex" ), "set_shading_mode" , "get_shading_mode" ); |
2728 | ADD_PROPERTY(PropertyInfo(Variant::INT, "diffuse_mode" , PROPERTY_HINT_ENUM, "Burley,Lambert,Lambert Wrap,Toon" ), "set_diffuse_mode" , "get_diffuse_mode" ); |
2729 | ADD_PROPERTY(PropertyInfo(Variant::INT, "specular_mode" , PROPERTY_HINT_ENUM, "SchlickGGX,Toon,Disabled" ), "set_specular_mode" , "get_specular_mode" ); |
2730 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "disable_ambient_light" ), "set_flag" , "get_flag" , FLAG_DISABLE_AMBIENT_LIGHT); |
2731 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "disable_fog" ), "set_flag" , "get_flag" , FLAG_DISABLE_FOG); |
2732 | |
2733 | ADD_GROUP("Vertex Color" , "vertex_color" ); |
2734 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_use_as_albedo" ), "set_flag" , "get_flag" , FLAG_ALBEDO_FROM_VERTEX_COLOR); |
2735 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_is_srgb" ), "set_flag" , "get_flag" , FLAG_SRGB_VERTEX_COLOR); |
2736 | |
2737 | ADD_GROUP("Albedo" , "albedo_" ); |
2738 | ADD_PROPERTY(PropertyInfo(Variant::COLOR, "albedo_color" ), "set_albedo" , "get_albedo" ); |
2739 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "albedo_texture" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_ALBEDO); |
2740 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "albedo_texture_force_srgb" ), "set_flag" , "get_flag" , FLAG_ALBEDO_TEXTURE_FORCE_SRGB); |
2741 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "albedo_texture_msdf" ), "set_flag" , "get_flag" , FLAG_ALBEDO_TEXTURE_MSDF); |
2742 | |
2743 | ADD_GROUP("ORM" , "orm_" ); |
2744 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orm_texture" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_ORM); |
2745 | |
2746 | ADD_GROUP("Metallic" , "metallic_" ); |
2747 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "metallic" , PROPERTY_HINT_RANGE, "0,1,0.01" ), "set_metallic" , "get_metallic" ); |
2748 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "metallic_specular" , PROPERTY_HINT_RANGE, "0,1,0.01" ), "set_specular" , "get_specular" ); |
2749 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "metallic_texture" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_METALLIC); |
2750 | ADD_PROPERTY(PropertyInfo(Variant::INT, "metallic_texture_channel" , PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray" ), "set_metallic_texture_channel" , "get_metallic_texture_channel" ); |
2751 | |
2752 | ADD_GROUP("Roughness" , "roughness_" ); |
2753 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "roughness" , PROPERTY_HINT_RANGE, "0,1,0.01" ), "set_roughness" , "get_roughness" ); |
2754 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "roughness_texture" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_ROUGHNESS); |
2755 | ADD_PROPERTY(PropertyInfo(Variant::INT, "roughness_texture_channel" , PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray" ), "set_roughness_texture_channel" , "get_roughness_texture_channel" ); |
2756 | |
2757 | ADD_GROUP("Emission" , "emission_" ); |
2758 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "emission_enabled" ), "set_feature" , "get_feature" , FEATURE_EMISSION); |
2759 | ADD_PROPERTY(PropertyInfo(Variant::COLOR, "emission" , PROPERTY_HINT_COLOR_NO_ALPHA), "set_emission" , "get_emission" ); |
2760 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_energy_multiplier" , PROPERTY_HINT_RANGE, "0,16,0.01,or_greater" ), "set_emission_energy_multiplier" , "get_emission_energy_multiplier" ); |
2761 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_intensity" , PROPERTY_HINT_RANGE, "0,100000.0,0.01,or_greater,suffix:nt" ), "set_emission_intensity" , "get_emission_intensity" ); |
2762 | |
2763 | ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_operator" , PROPERTY_HINT_ENUM, "Add,Multiply" ), "set_emission_operator" , "get_emission_operator" ); |
2764 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "emission_on_uv2" ), "set_flag" , "get_flag" , FLAG_EMISSION_ON_UV2); |
2765 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "emission_texture" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_EMISSION); |
2766 | |
2767 | ADD_GROUP("Normal Map" , "normal_" ); |
2768 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "normal_enabled" ), "set_feature" , "get_feature" , FEATURE_NORMAL_MAPPING); |
2769 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "normal_scale" , PROPERTY_HINT_RANGE, "-16,16,0.01" ), "set_normal_scale" , "get_normal_scale" ); |
2770 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "normal_texture" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_NORMAL); |
2771 | |
2772 | ADD_GROUP("Rim" , "rim_" ); |
2773 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "rim_enabled" ), "set_feature" , "get_feature" , FEATURE_RIM); |
2774 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rim" , PROPERTY_HINT_RANGE, "0,1,0.01" ), "set_rim" , "get_rim" ); |
2775 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rim_tint" , PROPERTY_HINT_RANGE, "0,1,0.01" ), "set_rim_tint" , "get_rim_tint" ); |
2776 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "rim_texture" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_RIM); |
2777 | |
2778 | ADD_GROUP("Clearcoat" , "clearcoat_" ); |
2779 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "clearcoat_enabled" ), "set_feature" , "get_feature" , FEATURE_CLEARCOAT); |
2780 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "clearcoat" , PROPERTY_HINT_RANGE, "0,1,0.01" ), "set_clearcoat" , "get_clearcoat" ); |
2781 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "clearcoat_roughness" , PROPERTY_HINT_RANGE, "0,1,0.01" ), "set_clearcoat_roughness" , "get_clearcoat_roughness" ); |
2782 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "clearcoat_texture" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_CLEARCOAT); |
2783 | |
2784 | ADD_GROUP("Anisotropy" , "anisotropy_" ); |
2785 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "anisotropy_enabled" ), "set_feature" , "get_feature" , FEATURE_ANISOTROPY); |
2786 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "anisotropy" , PROPERTY_HINT_RANGE, "-1,1,0.01" ), "set_anisotropy" , "get_anisotropy" ); |
2787 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anisotropy_flowmap" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_FLOWMAP); |
2788 | |
2789 | ADD_GROUP("Ambient Occlusion" , "ao_" ); |
2790 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "ao_enabled" ), "set_feature" , "get_feature" , FEATURE_AMBIENT_OCCLUSION); |
2791 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ao_light_affect" , PROPERTY_HINT_RANGE, "0,1,0.01" ), "set_ao_light_affect" , "get_ao_light_affect" ); |
2792 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "ao_texture" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_AMBIENT_OCCLUSION); |
2793 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "ao_on_uv2" ), "set_flag" , "get_flag" , FLAG_AO_ON_UV2); |
2794 | ADD_PROPERTY(PropertyInfo(Variant::INT, "ao_texture_channel" , PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray" ), "set_ao_texture_channel" , "get_ao_texture_channel" ); |
2795 | |
2796 | ADD_GROUP("Height" , "heightmap_" ); |
2797 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "heightmap_enabled" ), "set_feature" , "get_feature" , FEATURE_HEIGHT_MAPPING); |
2798 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "heightmap_scale" , PROPERTY_HINT_RANGE, "-16,16,0.001" ), "set_heightmap_scale" , "get_heightmap_scale" ); |
2799 | ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_deep_parallax" ), "set_heightmap_deep_parallax" , "is_heightmap_deep_parallax_enabled" ); |
2800 | ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_min_layers" , PROPERTY_HINT_RANGE, "1,64,1" ), "set_heightmap_deep_parallax_min_layers" , "get_heightmap_deep_parallax_min_layers" ); |
2801 | ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_max_layers" , PROPERTY_HINT_RANGE, "1,64,1" ), "set_heightmap_deep_parallax_max_layers" , "get_heightmap_deep_parallax_max_layers" ); |
2802 | ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_flip_tangent" ), "set_heightmap_deep_parallax_flip_tangent" , "get_heightmap_deep_parallax_flip_tangent" ); |
2803 | ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_flip_binormal" ), "set_heightmap_deep_parallax_flip_binormal" , "get_heightmap_deep_parallax_flip_binormal" ); |
2804 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "heightmap_texture" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_HEIGHTMAP); |
2805 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "heightmap_flip_texture" ), "set_flag" , "get_flag" , FLAG_INVERT_HEIGHTMAP); |
2806 | |
2807 | ADD_GROUP("Subsurface Scattering" , "subsurf_scatter_" ); |
2808 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_enabled" ), "set_feature" , "get_feature" , FEATURE_SUBSURFACE_SCATTERING); |
2809 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_strength" , PROPERTY_HINT_RANGE, "0,1,0.01" ), "set_subsurface_scattering_strength" , "get_subsurface_scattering_strength" ); |
2810 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_skin_mode" ), "set_flag" , "get_flag" , FLAG_SUBSURFACE_MODE_SKIN); |
2811 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_texture" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_SUBSURFACE_SCATTERING); |
2812 | |
2813 | ADD_SUBGROUP("Transmittance" , "subsurf_scatter_transmittance_" ); |
2814 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_transmittance_enabled" ), "set_feature" , "get_feature" , FEATURE_SUBSURFACE_TRANSMITTANCE); |
2815 | ADD_PROPERTY(PropertyInfo(Variant::COLOR, "subsurf_scatter_transmittance_color" ), "set_transmittance_color" , "get_transmittance_color" ); |
2816 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_transmittance_texture" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_SUBSURFACE_TRANSMITTANCE); |
2817 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_depth" , PROPERTY_HINT_RANGE, "0.001,8,0.001,or_greater" ), "set_transmittance_depth" , "get_transmittance_depth" ); |
2818 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_boost" , PROPERTY_HINT_RANGE, "0.00,1.0,0.01" ), "set_transmittance_boost" , "get_transmittance_boost" ); |
2819 | |
2820 | ADD_GROUP("Back Lighting" , "backlight_" ); |
2821 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "backlight_enabled" ), "set_feature" , "get_feature" , FEATURE_BACKLIGHT); |
2822 | ADD_PROPERTY(PropertyInfo(Variant::COLOR, "backlight" , PROPERTY_HINT_COLOR_NO_ALPHA), "set_backlight" , "get_backlight" ); |
2823 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "backlight_texture" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_BACKLIGHT); |
2824 | |
2825 | ADD_GROUP("Refraction" , "refraction_" ); |
2826 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "refraction_enabled" ), "set_feature" , "get_feature" , FEATURE_REFRACTION); |
2827 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "refraction_scale" , PROPERTY_HINT_RANGE, "-1,1,0.01" ), "set_refraction" , "get_refraction" ); |
2828 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "refraction_texture" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_REFRACTION); |
2829 | ADD_PROPERTY(PropertyInfo(Variant::INT, "refraction_texture_channel" , PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray" ), "set_refraction_texture_channel" , "get_refraction_texture_channel" ); |
2830 | |
2831 | ADD_GROUP("Detail" , "detail_" ); |
2832 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "detail_enabled" ), "set_feature" , "get_feature" , FEATURE_DETAIL); |
2833 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_mask" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_DETAIL_MASK); |
2834 | ADD_PROPERTY(PropertyInfo(Variant::INT, "detail_blend_mode" , PROPERTY_HINT_ENUM, "Mix,Add,Subtract,Multiply" ), "set_detail_blend_mode" , "get_detail_blend_mode" ); |
2835 | ADD_PROPERTY(PropertyInfo(Variant::INT, "detail_uv_layer" , PROPERTY_HINT_ENUM, "UV1,UV2" ), "set_detail_uv" , "get_detail_uv" ); |
2836 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_albedo" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_DETAIL_ALBEDO); |
2837 | ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_normal" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" ), "set_texture" , "get_texture" , TEXTURE_DETAIL_NORMAL); |
2838 | |
2839 | ADD_GROUP("UV1" , "uv1_" ); |
2840 | ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv1_scale" , PROPERTY_HINT_LINK), "set_uv1_scale" , "get_uv1_scale" ); |
2841 | ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv1_offset" ), "set_uv1_offset" , "get_uv1_offset" ); |
2842 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv1_triplanar" ), "set_flag" , "get_flag" , FLAG_UV1_USE_TRIPLANAR); |
2843 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "uv1_triplanar_sharpness" , PROPERTY_HINT_EXP_EASING), "set_uv1_triplanar_blend_sharpness" , "get_uv1_triplanar_blend_sharpness" ); |
2844 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv1_world_triplanar" ), "set_flag" , "get_flag" , FLAG_UV1_USE_WORLD_TRIPLANAR); |
2845 | |
2846 | ADD_GROUP("UV2" , "uv2_" ); |
2847 | ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv2_scale" , PROPERTY_HINT_LINK), "set_uv2_scale" , "get_uv2_scale" ); |
2848 | ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv2_offset" ), "set_uv2_offset" , "get_uv2_offset" ); |
2849 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv2_triplanar" ), "set_flag" , "get_flag" , FLAG_UV2_USE_TRIPLANAR); |
2850 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "uv2_triplanar_sharpness" , PROPERTY_HINT_EXP_EASING), "set_uv2_triplanar_blend_sharpness" , "get_uv2_triplanar_blend_sharpness" ); |
2851 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv2_world_triplanar" ), "set_flag" , "get_flag" , FLAG_UV2_USE_WORLD_TRIPLANAR); |
2852 | |
2853 | ADD_GROUP("Sampling" , "texture_" ); |
2854 | ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter" , PROPERTY_HINT_ENUM, "Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic" ), "set_texture_filter" , "get_texture_filter" ); |
2855 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "texture_repeat" ), "set_flag" , "get_flag" , FLAG_USE_TEXTURE_REPEAT); |
2856 | |
2857 | ADD_GROUP("Shadows" , "" ); |
2858 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "disable_receive_shadows" ), "set_flag" , "get_flag" , FLAG_DONT_RECEIVE_SHADOWS); |
2859 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "shadow_to_opacity" ), "set_flag" , "get_flag" , FLAG_USE_SHADOW_TO_OPACITY); |
2860 | |
2861 | ADD_GROUP("Billboard" , "billboard_" ); |
2862 | ADD_PROPERTY(PropertyInfo(Variant::INT, "billboard_mode" , PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard,Particle Billboard" ), "set_billboard_mode" , "get_billboard_mode" ); |
2863 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "billboard_keep_scale" ), "set_flag" , "get_flag" , FLAG_BILLBOARD_KEEP_SCALE); |
2864 | |
2865 | ADD_GROUP("Particles Anim" , "particles_anim_" ); |
2866 | ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_h_frames" , PROPERTY_HINT_RANGE, "1,128,1" ), "set_particles_anim_h_frames" , "get_particles_anim_h_frames" ); |
2867 | ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_v_frames" , PROPERTY_HINT_RANGE, "1,128,1" ), "set_particles_anim_v_frames" , "get_particles_anim_v_frames" ); |
2868 | ADD_PROPERTY(PropertyInfo(Variant::BOOL, "particles_anim_loop" ), "set_particles_anim_loop" , "get_particles_anim_loop" ); |
2869 | |
2870 | ADD_GROUP("Grow" , "grow_" ); |
2871 | ADD_PROPERTY(PropertyInfo(Variant::BOOL, "grow" ), "set_grow_enabled" , "is_grow_enabled" ); |
2872 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "grow_amount" , PROPERTY_HINT_RANGE, "-16,16,0.001,suffix:m" ), "set_grow" , "get_grow" ); |
2873 | ADD_GROUP("Transform" , "" ); |
2874 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "fixed_size" ), "set_flag" , "get_flag" , FLAG_FIXED_SIZE); |
2875 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_point_size" ), "set_flag" , "get_flag" , FLAG_USE_POINT_SIZE); |
2876 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "point_size" , PROPERTY_HINT_RANGE, "0.1,128,0.1,suffix:px" ), "set_point_size" , "get_point_size" ); |
2877 | ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_particle_trails" ), "set_flag" , "get_flag" , FLAG_PARTICLE_TRAILS_MODE); |
2878 | ADD_GROUP("Proximity Fade" , "proximity_fade_" ); |
2879 | ADD_PROPERTY(PropertyInfo(Variant::BOOL, "proximity_fade_enabled" ), "set_proximity_fade_enabled" , "is_proximity_fade_enabled" ); |
2880 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "proximity_fade_distance" , PROPERTY_HINT_RANGE, "0,4096,0.01,suffix:m" ), "set_proximity_fade_distance" , "get_proximity_fade_distance" ); |
2881 | ADD_GROUP("MSDF" , "msdf_" ); |
2882 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "msdf_pixel_range" , PROPERTY_HINT_RANGE, "1,100,1" ), "set_msdf_pixel_range" , "get_msdf_pixel_range" ); |
2883 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "msdf_outline_size" , PROPERTY_HINT_RANGE, "0,250,1" ), "set_msdf_outline_size" , "get_msdf_outline_size" ); |
2884 | ADD_GROUP("Distance Fade" , "distance_fade_" ); |
2885 | ADD_PROPERTY(PropertyInfo(Variant::INT, "distance_fade_mode" , PROPERTY_HINT_ENUM, "Disabled,PixelAlpha,PixelDither,ObjectDither" ), "set_distance_fade" , "get_distance_fade" ); |
2886 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_min_distance" , PROPERTY_HINT_RANGE, "0,4096,0.01,suffix:m" ), "set_distance_fade_min_distance" , "get_distance_fade_min_distance" ); |
2887 | ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_max_distance" , PROPERTY_HINT_RANGE, "0,4096,0.01,suffix:m" ), "set_distance_fade_max_distance" , "get_distance_fade_max_distance" ); |
2888 | |
2889 | BIND_ENUM_CONSTANT(TEXTURE_ALBEDO); |
2890 | BIND_ENUM_CONSTANT(TEXTURE_METALLIC); |
2891 | BIND_ENUM_CONSTANT(TEXTURE_ROUGHNESS); |
2892 | BIND_ENUM_CONSTANT(TEXTURE_EMISSION); |
2893 | BIND_ENUM_CONSTANT(TEXTURE_NORMAL); |
2894 | BIND_ENUM_CONSTANT(TEXTURE_RIM); |
2895 | BIND_ENUM_CONSTANT(TEXTURE_CLEARCOAT); |
2896 | BIND_ENUM_CONSTANT(TEXTURE_FLOWMAP); |
2897 | BIND_ENUM_CONSTANT(TEXTURE_AMBIENT_OCCLUSION); |
2898 | BIND_ENUM_CONSTANT(TEXTURE_HEIGHTMAP); |
2899 | BIND_ENUM_CONSTANT(TEXTURE_SUBSURFACE_SCATTERING); |
2900 | BIND_ENUM_CONSTANT(TEXTURE_SUBSURFACE_TRANSMITTANCE); |
2901 | BIND_ENUM_CONSTANT(TEXTURE_BACKLIGHT); |
2902 | BIND_ENUM_CONSTANT(TEXTURE_REFRACTION); |
2903 | BIND_ENUM_CONSTANT(TEXTURE_DETAIL_MASK); |
2904 | BIND_ENUM_CONSTANT(TEXTURE_DETAIL_ALBEDO); |
2905 | BIND_ENUM_CONSTANT(TEXTURE_DETAIL_NORMAL); |
2906 | BIND_ENUM_CONSTANT(TEXTURE_ORM); |
2907 | BIND_ENUM_CONSTANT(TEXTURE_MAX); |
2908 | |
2909 | BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST); |
2910 | BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR); |
2911 | BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST_WITH_MIPMAPS); |
2912 | BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR_WITH_MIPMAPS); |
2913 | BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC); |
2914 | BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC); |
2915 | BIND_ENUM_CONSTANT(TEXTURE_FILTER_MAX); |
2916 | |
2917 | BIND_ENUM_CONSTANT(DETAIL_UV_1); |
2918 | BIND_ENUM_CONSTANT(DETAIL_UV_2); |
2919 | |
2920 | BIND_ENUM_CONSTANT(TRANSPARENCY_DISABLED); |
2921 | BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA); |
2922 | BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA_SCISSOR); |
2923 | BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA_HASH); |
2924 | BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA_DEPTH_PRE_PASS); |
2925 | BIND_ENUM_CONSTANT(TRANSPARENCY_MAX); |
2926 | |
2927 | BIND_ENUM_CONSTANT(SHADING_MODE_UNSHADED); |
2928 | BIND_ENUM_CONSTANT(SHADING_MODE_PER_PIXEL); |
2929 | BIND_ENUM_CONSTANT(SHADING_MODE_PER_VERTEX); |
2930 | BIND_ENUM_CONSTANT(SHADING_MODE_MAX); |
2931 | |
2932 | BIND_ENUM_CONSTANT(FEATURE_EMISSION); |
2933 | BIND_ENUM_CONSTANT(FEATURE_NORMAL_MAPPING); |
2934 | BIND_ENUM_CONSTANT(FEATURE_RIM); |
2935 | BIND_ENUM_CONSTANT(FEATURE_CLEARCOAT); |
2936 | BIND_ENUM_CONSTANT(FEATURE_ANISOTROPY); |
2937 | BIND_ENUM_CONSTANT(FEATURE_AMBIENT_OCCLUSION); |
2938 | BIND_ENUM_CONSTANT(FEATURE_HEIGHT_MAPPING); |
2939 | BIND_ENUM_CONSTANT(FEATURE_SUBSURFACE_SCATTERING); |
2940 | BIND_ENUM_CONSTANT(FEATURE_SUBSURFACE_TRANSMITTANCE); |
2941 | BIND_ENUM_CONSTANT(FEATURE_BACKLIGHT); |
2942 | BIND_ENUM_CONSTANT(FEATURE_REFRACTION); |
2943 | BIND_ENUM_CONSTANT(FEATURE_DETAIL); |
2944 | BIND_ENUM_CONSTANT(FEATURE_MAX); |
2945 | |
2946 | BIND_ENUM_CONSTANT(BLEND_MODE_MIX); |
2947 | BIND_ENUM_CONSTANT(BLEND_MODE_ADD); |
2948 | BIND_ENUM_CONSTANT(BLEND_MODE_SUB); |
2949 | BIND_ENUM_CONSTANT(BLEND_MODE_MUL); |
2950 | |
2951 | BIND_ENUM_CONSTANT(ALPHA_ANTIALIASING_OFF); |
2952 | BIND_ENUM_CONSTANT(ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE); |
2953 | BIND_ENUM_CONSTANT(ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE); |
2954 | |
2955 | BIND_ENUM_CONSTANT(DEPTH_DRAW_OPAQUE_ONLY); |
2956 | BIND_ENUM_CONSTANT(DEPTH_DRAW_ALWAYS); |
2957 | BIND_ENUM_CONSTANT(DEPTH_DRAW_DISABLED); |
2958 | |
2959 | BIND_ENUM_CONSTANT(CULL_BACK); |
2960 | BIND_ENUM_CONSTANT(CULL_FRONT); |
2961 | BIND_ENUM_CONSTANT(CULL_DISABLED); |
2962 | |
2963 | BIND_ENUM_CONSTANT(FLAG_DISABLE_DEPTH_TEST); |
2964 | BIND_ENUM_CONSTANT(FLAG_ALBEDO_FROM_VERTEX_COLOR); |
2965 | BIND_ENUM_CONSTANT(FLAG_SRGB_VERTEX_COLOR); |
2966 | BIND_ENUM_CONSTANT(FLAG_USE_POINT_SIZE); |
2967 | BIND_ENUM_CONSTANT(FLAG_FIXED_SIZE); |
2968 | BIND_ENUM_CONSTANT(FLAG_BILLBOARD_KEEP_SCALE); |
2969 | BIND_ENUM_CONSTANT(FLAG_UV1_USE_TRIPLANAR); |
2970 | BIND_ENUM_CONSTANT(FLAG_UV2_USE_TRIPLANAR); |
2971 | BIND_ENUM_CONSTANT(FLAG_UV1_USE_WORLD_TRIPLANAR); |
2972 | BIND_ENUM_CONSTANT(FLAG_UV2_USE_WORLD_TRIPLANAR); |
2973 | BIND_ENUM_CONSTANT(FLAG_AO_ON_UV2); |
2974 | BIND_ENUM_CONSTANT(FLAG_EMISSION_ON_UV2); |
2975 | BIND_ENUM_CONSTANT(FLAG_ALBEDO_TEXTURE_FORCE_SRGB); |
2976 | BIND_ENUM_CONSTANT(FLAG_DONT_RECEIVE_SHADOWS); |
2977 | BIND_ENUM_CONSTANT(FLAG_DISABLE_AMBIENT_LIGHT); |
2978 | BIND_ENUM_CONSTANT(FLAG_USE_SHADOW_TO_OPACITY); |
2979 | BIND_ENUM_CONSTANT(FLAG_USE_TEXTURE_REPEAT); |
2980 | BIND_ENUM_CONSTANT(FLAG_INVERT_HEIGHTMAP); |
2981 | BIND_ENUM_CONSTANT(FLAG_SUBSURFACE_MODE_SKIN); |
2982 | BIND_ENUM_CONSTANT(FLAG_PARTICLE_TRAILS_MODE); |
2983 | BIND_ENUM_CONSTANT(FLAG_ALBEDO_TEXTURE_MSDF); |
2984 | BIND_ENUM_CONSTANT(FLAG_DISABLE_FOG); |
2985 | BIND_ENUM_CONSTANT(FLAG_MAX); |
2986 | |
2987 | BIND_ENUM_CONSTANT(DIFFUSE_BURLEY); |
2988 | BIND_ENUM_CONSTANT(DIFFUSE_LAMBERT); |
2989 | BIND_ENUM_CONSTANT(DIFFUSE_LAMBERT_WRAP); |
2990 | BIND_ENUM_CONSTANT(DIFFUSE_TOON); |
2991 | |
2992 | BIND_ENUM_CONSTANT(SPECULAR_SCHLICK_GGX); |
2993 | BIND_ENUM_CONSTANT(SPECULAR_TOON); |
2994 | BIND_ENUM_CONSTANT(SPECULAR_DISABLED); |
2995 | |
2996 | BIND_ENUM_CONSTANT(BILLBOARD_DISABLED); |
2997 | BIND_ENUM_CONSTANT(BILLBOARD_ENABLED); |
2998 | BIND_ENUM_CONSTANT(BILLBOARD_FIXED_Y); |
2999 | BIND_ENUM_CONSTANT(BILLBOARD_PARTICLES); |
3000 | |
3001 | BIND_ENUM_CONSTANT(TEXTURE_CHANNEL_RED); |
3002 | BIND_ENUM_CONSTANT(TEXTURE_CHANNEL_GREEN); |
3003 | BIND_ENUM_CONSTANT(TEXTURE_CHANNEL_BLUE); |
3004 | BIND_ENUM_CONSTANT(TEXTURE_CHANNEL_ALPHA); |
3005 | BIND_ENUM_CONSTANT(TEXTURE_CHANNEL_GRAYSCALE); |
3006 | |
3007 | BIND_ENUM_CONSTANT(EMISSION_OP_ADD); |
3008 | BIND_ENUM_CONSTANT(EMISSION_OP_MULTIPLY); |
3009 | |
3010 | BIND_ENUM_CONSTANT(DISTANCE_FADE_DISABLED); |
3011 | BIND_ENUM_CONSTANT(DISTANCE_FADE_PIXEL_ALPHA); |
3012 | BIND_ENUM_CONSTANT(DISTANCE_FADE_PIXEL_DITHER); |
3013 | BIND_ENUM_CONSTANT(DISTANCE_FADE_OBJECT_DITHER); |
3014 | } |
3015 | |
3016 | BaseMaterial3D::BaseMaterial3D(bool p_orm) : |
3017 | element(this) { |
3018 | orm = p_orm; |
3019 | // Initialize to the same values as the shader |
3020 | set_albedo(Color(1.0, 1.0, 1.0, 1.0)); |
3021 | set_specular(0.5); |
3022 | set_roughness(1.0); |
3023 | set_metallic(0.0); |
3024 | set_emission(Color(0, 0, 0)); |
3025 | set_emission_energy_multiplier(1.0); |
3026 | set_normal_scale(1); |
3027 | set_rim(1.0); |
3028 | set_rim_tint(0.5); |
3029 | set_clearcoat(1); |
3030 | set_clearcoat_roughness(0.5); |
3031 | set_anisotropy(0); |
3032 | set_heightmap_scale(5.0); |
3033 | set_subsurface_scattering_strength(0); |
3034 | set_backlight(Color(0, 0, 0)); |
3035 | set_transmittance_color(Color(1, 1, 1, 1)); |
3036 | set_transmittance_depth(0.1); |
3037 | set_transmittance_boost(0.0); |
3038 | set_refraction(0.05); |
3039 | set_point_size(1); |
3040 | set_uv1_offset(Vector3(0, 0, 0)); |
3041 | set_uv1_scale(Vector3(1, 1, 1)); |
3042 | set_uv1_triplanar_blend_sharpness(1); |
3043 | set_uv2_offset(Vector3(0, 0, 0)); |
3044 | set_uv2_scale(Vector3(1, 1, 1)); |
3045 | set_uv2_triplanar_blend_sharpness(1); |
3046 | set_billboard_mode(BILLBOARD_DISABLED); |
3047 | set_particles_anim_h_frames(1); |
3048 | set_particles_anim_v_frames(1); |
3049 | set_particles_anim_loop(false); |
3050 | |
3051 | set_transparency(TRANSPARENCY_DISABLED); |
3052 | set_alpha_antialiasing(ALPHA_ANTIALIASING_OFF); |
3053 | // Alpha scissor threshold of 0.5 matches the glTF specification and Label3D default. |
3054 | // <https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#_material_alphacutoff> |
3055 | set_alpha_scissor_threshold(0.5); |
3056 | set_alpha_hash_scale(1.0); |
3057 | set_alpha_antialiasing_edge(0.3); |
3058 | |
3059 | set_proximity_fade_distance(1); |
3060 | set_distance_fade_min_distance(0); |
3061 | set_distance_fade_max_distance(10); |
3062 | |
3063 | set_ao_light_affect(0.0); |
3064 | |
3065 | set_metallic_texture_channel(TEXTURE_CHANNEL_RED); |
3066 | set_roughness_texture_channel(TEXTURE_CHANNEL_RED); |
3067 | set_ao_texture_channel(TEXTURE_CHANNEL_RED); |
3068 | set_refraction_texture_channel(TEXTURE_CHANNEL_RED); |
3069 | |
3070 | set_grow(0.0); |
3071 | |
3072 | set_msdf_pixel_range(4.0); |
3073 | set_msdf_outline_size(0.0); |
3074 | |
3075 | set_heightmap_deep_parallax_min_layers(8); |
3076 | set_heightmap_deep_parallax_max_layers(32); |
3077 | set_heightmap_deep_parallax_flip_tangent(false); //also sets binormal |
3078 | |
3079 | flags[FLAG_ALBEDO_TEXTURE_MSDF] = false; |
3080 | flags[FLAG_USE_TEXTURE_REPEAT] = true; |
3081 | |
3082 | _mark_initialized(callable_mp(this, &BaseMaterial3D::_queue_shader_change)); |
3083 | } |
3084 | |
3085 | BaseMaterial3D::~BaseMaterial3D() { |
3086 | ERR_FAIL_NULL(RenderingServer::get_singleton()); |
3087 | MutexLock lock(material_mutex); |
3088 | |
3089 | if (shader_map.has(current_key)) { |
3090 | shader_map[current_key].users--; |
3091 | if (shader_map[current_key].users == 0) { |
3092 | //deallocate shader, as it's no longer in use |
3093 | RS::get_singleton()->free(shader_map[current_key].shader); |
3094 | shader_map.erase(current_key); |
3095 | } |
3096 | |
3097 | RS::get_singleton()->material_set_shader(_get_material(), RID()); |
3098 | } |
3099 | } |
3100 | |
3101 | ////////////////////// |
3102 | |
3103 | #ifndef DISABLE_DEPRECATED |
3104 | // Kept for compatibility from 3.x to 4.0. |
3105 | bool StandardMaterial3D::_set(const StringName &p_name, const Variant &p_value) { |
3106 | if (p_name == "flags_transparent" ) { |
3107 | bool transparent = p_value; |
3108 | if (transparent) { |
3109 | set_transparency(TRANSPARENCY_ALPHA); |
3110 | } |
3111 | return true; |
3112 | } else if (p_name == "flags_unshaded" ) { |
3113 | bool unshaded = p_value; |
3114 | if (unshaded) { |
3115 | set_shading_mode(SHADING_MODE_UNSHADED); |
3116 | } |
3117 | return true; |
3118 | } else if (p_name == "flags_vertex_lighting" ) { |
3119 | bool vertex_lit = p_value; |
3120 | if (vertex_lit && get_shading_mode() != SHADING_MODE_UNSHADED) { |
3121 | set_shading_mode(SHADING_MODE_PER_VERTEX); |
3122 | } |
3123 | return true; |
3124 | } else if (p_name == "params_use_alpha_scissor" ) { |
3125 | bool use_scissor = p_value; |
3126 | if (use_scissor) { |
3127 | set_transparency(TRANSPARENCY_ALPHA_SCISSOR); |
3128 | } |
3129 | return true; |
3130 | } else if (p_name == "params_use_alpha_hash" ) { |
3131 | bool use_hash = p_value; |
3132 | if (use_hash) { |
3133 | set_transparency(TRANSPARENCY_ALPHA_HASH); |
3134 | } |
3135 | return true; |
3136 | } else if (p_name == "params_depth_draw_mode" ) { |
3137 | int mode = p_value; |
3138 | if (mode == 3) { |
3139 | set_transparency(TRANSPARENCY_ALPHA_DEPTH_PRE_PASS); |
3140 | } |
3141 | return true; |
3142 | } else if (p_name == "depth_enabled" ) { |
3143 | bool enabled = p_value; |
3144 | if (enabled) { |
3145 | set_feature(FEATURE_HEIGHT_MAPPING, true); |
3146 | set_flag(FLAG_INVERT_HEIGHTMAP, true); |
3147 | } |
3148 | return true; |
3149 | } else { |
3150 | static const Pair<const char *, const char *> remaps[] = { |
3151 | { "flags_use_shadow_to_opacity" , "shadow_to_opacity" }, |
3152 | { "flags_use_shadow_to_opacity" , "shadow_to_opacity" }, |
3153 | { "flags_no_depth_test" , "no_depth_test" }, |
3154 | { "flags_use_point_size" , "use_point_size" }, |
3155 | { "flags_fixed_size" , "fixed_Size" }, |
3156 | { "flags_albedo_tex_force_srgb" , "albedo_texture_force_srgb" }, |
3157 | { "flags_do_not_receive_shadows" , "disable_receive_shadows" }, |
3158 | { "flags_disable_ambient_light" , "disable_ambient_light" }, |
3159 | { "params_diffuse_mode" , "diffuse_mode" }, |
3160 | { "params_specular_mode" , "specular_mode" }, |
3161 | { "params_blend_mode" , "blend_mode" }, |
3162 | { "params_cull_mode" , "cull_mode" }, |
3163 | { "params_depth_draw_mode" , "params_depth_draw_mode" }, |
3164 | { "params_point_size" , "point_size" }, |
3165 | { "params_billboard_mode" , "billboard_mode" }, |
3166 | { "params_billboard_keep_scale" , "billboard_keep_scale" }, |
3167 | { "params_grow" , "grow" }, |
3168 | { "params_grow_amount" , "grow_amount" }, |
3169 | { "params_alpha_scissor_threshold" , "alpha_scissor_threshold" }, |
3170 | { "params_alpha_hash_scale" , "alpha_hash_scale" }, |
3171 | { "params_alpha_antialiasing_edge" , "alpha_antialiasing_edge" }, |
3172 | |
3173 | { "depth_scale" , "heightmap_scale" }, |
3174 | { "depth_deep_parallax" , "heightmap_deep_parallax" }, |
3175 | { "depth_min_layers" , "heightmap_min_layers" }, |
3176 | { "depth_max_layers" , "heightmap_max_layers" }, |
3177 | { "depth_flip_tangent" , "heightmap_flip_tangent" }, |
3178 | { "depth_flip_binormal" , "heightmap_flip_binormal" }, |
3179 | { "depth_texture" , "heightmap_texture" }, |
3180 | |
3181 | { "emission_energy" , "emission_energy_multiplier" }, |
3182 | |
3183 | { nullptr, nullptr }, |
3184 | }; |
3185 | |
3186 | int idx = 0; |
3187 | while (remaps[idx].first) { |
3188 | if (p_name == remaps[idx].first) { |
3189 | set(remaps[idx].second, p_value); |
3190 | return true; |
3191 | } |
3192 | idx++; |
3193 | } |
3194 | |
3195 | WARN_PRINT("Godot 3.x SpatialMaterial remapped parameter not found: " + String(p_name)); |
3196 | return true; |
3197 | } |
3198 | } |
3199 | |
3200 | #endif // DISABLE_DEPRECATED |
3201 | |
3202 | /////////////////////// |
3203 | |