Move metallic and roughness automated assignment to an inspector UndoRedo

callback.
This commit is contained in:
SaracenOne 2021-12-21 22:19:00 +00:00
parent f57bdf13af
commit 901f376671
4 changed files with 41 additions and 15 deletions

View file

@ -53,7 +53,6 @@
<argument index="1" name="texture" type="Texture2D" /> <argument index="1" name="texture" type="Texture2D" />
<description> <description>
Sets the texture for the slot specified by [code]param[/code]. See [enum TextureParam] for available slots. Sets the texture for the slot specified by [code]param[/code]. See [enum TextureParam] for available slots.
[b]Note:[/b] When setting a roughness or metallic texture on a material that has no texture assigned to those slots, [member roughness] or [member metallic] will automatically be set to [code]1.0[/code] to ensure correct appearance.
</description> </description>
</method> </method>
</methods> </methods>
@ -233,7 +232,6 @@
</member> </member>
<member name="metallic" type="float" setter="set_metallic" getter="get_metallic" default="0.0"> <member name="metallic" type="float" setter="set_metallic" getter="get_metallic" default="0.0">
A high value makes the material appear more like a metal. Non-metals use their albedo as the diffuse color and add diffuse to the specular reflection. With non-metals, the reflection appears on top of the albedo color. Metals use their albedo as a multiplier to the specular reflection and set the diffuse color to black resulting in a tinted reflection. Materials work better when fully metal or fully non-metal, values between [code]0[/code] and [code]1[/code] should only be used for blending between metal and non-metal sections. To alter the amount of reflection use [member roughness]. A high value makes the material appear more like a metal. Non-metals use their albedo as the diffuse color and add diffuse to the specular reflection. With non-metals, the reflection appears on top of the albedo color. Metals use their albedo as a multiplier to the specular reflection and set the diffuse color to black resulting in a tinted reflection. Materials work better when fully metal or fully non-metal, values between [code]0[/code] and [code]1[/code] should only be used for blending between metal and non-metal sections. To alter the amount of reflection use [member roughness].
[b]Note:[/b] [member metallic] is automatically set to [code]1.0[/code] when assigning a metallic texture using [method set_texture].
</member> </member>
<member name="metallic_specular" type="float" setter="set_specular" getter="get_specular" default="0.5"> <member name="metallic_specular" type="float" setter="set_specular" getter="get_specular" default="0.5">
Sets the size of the specular lobe. The specular lobe is the bright spot that is reflected from light sources. Sets the size of the specular lobe. The specular lobe is the bright spot that is reflected from light sources.
@ -306,7 +304,6 @@
</member> </member>
<member name="roughness" type="float" setter="set_roughness" getter="get_roughness" default="1.0"> <member name="roughness" type="float" setter="set_roughness" getter="get_roughness" default="1.0">
Surface reflection. A value of [code]0[/code] represents a perfect mirror while a value of [code]1[/code] completely blurs the reflection. See also [member metallic]. Surface reflection. A value of [code]0[/code] represents a perfect mirror while a value of [code]1[/code] completely blurs the reflection. See also [member metallic].
[b]Note:[/b] [member roughness] is automatically set to [code]1.0[/code] when assigning a roughness texture using [method set_texture].
</member> </member>
<member name="roughness_texture" type="Texture2D" setter="set_texture" getter="get_texture"> <member name="roughness_texture" type="Texture2D" setter="set_texture" getter="get_texture">
Texture used to control the roughness per-pixel. Multiplied by [member roughness]. Texture used to control the roughness per-pixel. Multiplied by [member roughness].

View file

@ -254,6 +254,43 @@ void EditorInspectorPluginMaterial::parse_begin(Object *p_object) {
add_custom_control(editor); add_custom_control(editor);
} }
void EditorInspectorPluginMaterial::_undo_redo_inspector_callback(Object *p_undo_redo, Object *p_edited, String p_property, Variant p_new_value) {
UndoRedo *undo_redo = Object::cast_to<UndoRedo>(p_undo_redo);
if (!undo_redo) {
return;
}
// For BaseMaterial3D, if a roughness or metallic textures is being assigned to an empty slot,
// set the respective metallic or roughness factor to 1.0 as a convinence feature
BaseMaterial3D *base_material = Object::cast_to<StandardMaterial3D>(p_edited);
if (base_material) {
Texture2D *texture = Object::cast_to<Texture2D>(p_new_value);
if (texture) {
if (p_property == "roughness_texture") {
if (base_material->get_texture(StandardMaterial3D::TEXTURE_ROUGHNESS).is_null() && texture) {
undo_redo->add_do_property(p_edited, "roughness", 1.0);
bool valid = false;
Variant value = p_edited->get("roughness", &valid);
if (valid) {
undo_redo->add_undo_property(p_edited, "roughness", value);
}
}
} else if (p_property == "metallic_texture") {
if (base_material->get_texture(StandardMaterial3D::TEXTURE_METALLIC).is_null() && texture) {
undo_redo->add_do_property(p_edited, "metallic", 1.0);
bool valid = false;
Variant value = p_edited->get("metallic", &valid);
if (valid) {
undo_redo->add_undo_property(p_edited, "metallic", value);
}
}
}
}
}
}
EditorInspectorPluginMaterial::EditorInspectorPluginMaterial() { EditorInspectorPluginMaterial::EditorInspectorPluginMaterial() {
env.instantiate(); env.instantiate();
Ref<Sky> sky = memnew(Sky()); Ref<Sky> sky = memnew(Sky());
@ -261,6 +298,8 @@ EditorInspectorPluginMaterial::EditorInspectorPluginMaterial() {
env->set_background(Environment::BG_COLOR); env->set_background(Environment::BG_COLOR);
env->set_ambient_source(Environment::AMBIENT_SOURCE_SKY); env->set_ambient_source(Environment::AMBIENT_SOURCE_SKY);
env->set_reflection_source(Environment::REFLECTION_SOURCE_SKY); env->set_reflection_source(Environment::REFLECTION_SOURCE_SKY);
EditorNode::get_singleton()->get_editor_data().add_undo_redo_inspector_hook_callback(callable_mp(this, &EditorInspectorPluginMaterial::_undo_redo_inspector_callback));
} }
MaterialEditorPlugin::MaterialEditorPlugin(EditorNode *p_node) { MaterialEditorPlugin::MaterialEditorPlugin(EditorNode *p_node) {

View file

@ -92,6 +92,8 @@ public:
virtual bool can_handle(Object *p_object) override; virtual bool can_handle(Object *p_object) override;
virtual void parse_begin(Object *p_object) override; virtual void parse_begin(Object *p_object) override;
void _undo_redo_inspector_callback(Object *p_undo_redo, Object *p_edited, String p_property, Variant p_new_value);
EditorInspectorPluginMaterial(); EditorInspectorPluginMaterial();
}; };

View file

@ -1659,18 +1659,6 @@ bool BaseMaterial3D::get_feature(Feature p_feature) const {
void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture) { void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture) {
ERR_FAIL_INDEX(p_param, TEXTURE_MAX); ERR_FAIL_INDEX(p_param, TEXTURE_MAX);
if (get_texture(TEXTURE_ROUGHNESS).is_null() && p_texture.is_valid() && p_param == TEXTURE_ROUGHNESS) {
// If no roughness texture is currently set, automatically set the recommended value
// for roughness when using a roughness map.
set_roughness(1.0);
}
if (get_texture(TEXTURE_METALLIC).is_null() && p_texture.is_valid() && p_param == TEXTURE_METALLIC) {
// If no metallic texture is currently set, automatically set the recommended value
// for metallic when using a metallic map.
set_metallic(1.0);
}
textures[p_param] = p_texture; textures[p_param] = p_texture;
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid); RS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid);